summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-18 00:24:27 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-18 00:24:27 +0000
commitb9558d5f86c471a125abf1fb3a3882fb053b1f8c (patch)
tree707b53ec64e740a7da87d5f36485e3cd9b1c794e
parentb3ac367c7a3e6047abe74817db27e34e759f279f (diff)
Merge with Linux 2.3.41.
-rw-r--r--CREDITS16
-rw-r--r--Documentation/Configure.help96
-rw-r--r--Documentation/DMA-mapping.txt143
-rw-r--r--Documentation/filesystems/udf.txt4
-rw-r--r--Documentation/networking/ip-sysctl.txt121
-rw-r--r--Documentation/networking/smctr.txt4
-rw-r--r--Documentation/networking/wan-router.txt65
-rw-r--r--Documentation/networking/wanpipe.txt330
-rw-r--r--Documentation/rtc.txt4
-rw-r--r--Documentation/usb/CREDITS1
-rw-r--r--Documentation/usb/ibmcam.txt166
-rw-r--r--Documentation/usb/ohci.txt (renamed from Documentation/usb/ohci-hcd.txt)2
-rw-r--r--Documentation/usb/ov511.txt10
-rw-r--r--Documentation/usb/scanner-hp-sane.txt21
-rw-r--r--Documentation/usb/scanner.txt133
-rw-r--r--Documentation/usb/usb-serial.txt14
-rw-r--r--Documentation/vm/balance81
-rw-r--r--MAINTAINERS41
-rw-r--r--Makefile8
-rw-r--r--arch/alpha/kernel/osf_sys.c16
-rw-r--r--arch/arm/kernel/signal.c2
-rw-r--r--arch/arm/kernel/sys_arm.c8
-rw-r--r--arch/i386/Makefile11
-rw-r--r--arch/i386/config.in6
-rw-r--r--arch/i386/defconfig20
-rw-r--r--arch/i386/kernel/Makefile13
-rw-r--r--arch/i386/kernel/acpi.c256
-rw-r--r--arch/i386/kernel/apm.c17
-rw-r--r--arch/i386/kernel/entry.S3
-rw-r--r--arch/i386/kernel/i386_ksyms.c4
-rw-r--r--arch/i386/kernel/pci-dma.c51
-rw-r--r--arch/i386/kernel/pm.c104
-rw-r--r--arch/i386/kernel/signal.c2
-rw-r--r--arch/i386/kernel/sys_i386.c8
-rw-r--r--arch/i386/mm/init.c2
-rw-r--r--arch/m68k/amiga/amisound.c2
-rw-r--r--arch/m68k/amiga/chipram.c23
-rw-r--r--arch/m68k/amiga/config.c49
-rw-r--r--arch/m68k/apollo/Makefile2
-rw-r--r--arch/m68k/apollo/config.c181
-rw-r--r--arch/m68k/apollo/dma.c49
-rw-r--r--arch/m68k/apollo/dn_ints.c34
-rw-r--r--arch/m68k/atari/Makefile6
-rw-r--r--arch/m68k/atari/config.c22
-rw-r--r--arch/m68k/atari/hades-pci.c437
-rw-r--r--arch/m68k/atari/stram.c2
-rw-r--r--arch/m68k/bvme6000/config.c17
-rw-r--r--arch/m68k/bvme6000/rtc.c41
-rw-r--r--arch/m68k/config.in14
-rw-r--r--arch/m68k/defconfig1
-rw-r--r--arch/m68k/kernel/Makefile4
-rw-r--r--arch/m68k/kernel/bios32.c529
-rw-r--r--arch/m68k/kernel/entry.S40
-rw-r--r--arch/m68k/kernel/head.S248
-rw-r--r--arch/m68k/kernel/kgdb.c1362
-rw-r--r--arch/m68k/kernel/m68k_ksyms.c7
-rw-r--r--arch/m68k/kernel/ptrace.c224
-rw-r--r--arch/m68k/kernel/semaphore.c126
-rw-r--r--arch/m68k/kernel/setup.c70
-rw-r--r--arch/m68k/kernel/signal.c5
-rw-r--r--arch/m68k/kernel/sys_m68k.c4
-rw-r--r--arch/m68k/kernel/traps.c61
-rw-r--r--arch/m68k/lib/Makefile2
-rw-r--r--arch/m68k/lib/lshrdi3.c62
-rw-r--r--arch/m68k/lib/semaphore.S48
-rw-r--r--arch/m68k/mm/fault.c2
-rw-r--r--arch/m68k/mm/init.c56
-rw-r--r--arch/m68k/mm/kmap.c2
-rw-r--r--arch/m68k/mm/memory.c65
-rw-r--r--arch/m68k/mm/motorola.c57
-rw-r--r--arch/m68k/mm/sun3mmu.c2
-rw-r--r--arch/m68k/mvme147/config.c13
-rw-r--r--arch/m68k/mvme16x/Makefile2
-rw-r--r--arch/m68k/mvme16x/config.c102
-rw-r--r--arch/m68k/mvme16x/mvme16x_ksyms.c6
-rw-r--r--arch/m68k/mvme16x/rtc.c43
-rw-r--r--arch/m68k/sun3/Makefile3
-rw-r--r--arch/m68k/sun3/config.c30
-rw-r--r--arch/m68k/sun3/intersil.c100
-rw-r--r--arch/m68k/sun3/mmu_emu.c50
-rw-r--r--arch/m68k/sun3/sun3_ksyms.c10
-rw-r--r--arch/mips/defconfig12
-rw-r--r--arch/mips/defconfig-ip2212
-rw-r--r--arch/mips/kernel/semaphore.c111
-rw-r--r--arch/mips/kernel/syscalls.h3
-rw-r--r--arch/mips/kernel/sysmips.c3
-rw-r--r--arch/mips/mm/fault.c11
-rw-r--r--arch/mips/sni/Makefile4
-rw-r--r--arch/mips/sni/dma.c56
-rw-r--r--arch/mips64/defconfig19
-rw-r--r--arch/mips64/defconfig-ip2219
-rw-r--r--arch/mips64/defconfig-ip2719
-rw-r--r--arch/mips64/kernel/scall_64.S3
-rw-r--r--arch/mips64/kernel/scall_o32.S3
-rw-r--r--arch/mips64/kernel/semaphore.c111
-rw-r--r--arch/mips64/mm/fault.c11
-rw-r--r--arch/mips64/sgi-ip27/Makefile6
-rw-r--r--arch/mips64/sgi-ip27/ip27-pci-dma.c55
-rw-r--r--arch/ppc/kernel/entry.S21
-rw-r--r--arch/ppc/kernel/i8259.c18
-rw-r--r--arch/ppc/kernel/misc.S4
-rw-r--r--arch/ppc/xmon/start.c15
-rw-r--r--arch/sh/kernel/sys_sh.c4
-rw-r--r--arch/sparc/config.in3
-rw-r--r--arch/sparc/kernel/ebus.c100
-rw-r--r--arch/sparc/kernel/ioport.c29
-rw-r--r--arch/sparc/kernel/pcic.c163
-rw-r--r--arch/sparc/kernel/process.c5
-rw-r--r--arch/sparc/kernel/signal.c88
-rw-r--r--arch/sparc/kernel/smp.c3
-rw-r--r--arch/sparc/kernel/sparc_ksyms.c7
-rw-r--r--arch/sparc/kernel/sun4d_smp.c50
-rw-r--r--arch/sparc/kernel/sun4m_smp.c65
-rw-r--r--arch/sparc/kernel/sys_sparc.c16
-rw-r--r--arch/sparc/kernel/sys_sunos.c27
-rw-r--r--arch/sparc/kernel/systbls.S8
-rw-r--r--arch/sparc/kernel/time.c4
-rw-r--r--arch/sparc/kernel/traps.c130
-rw-r--r--arch/sparc/kernel/unaligned.c17
-rw-r--r--arch/sparc/mm/asyncd.c12
-rw-r--r--arch/sparc/mm/fault.c106
-rw-r--r--arch/sparc/mm/init.c23
-rw-r--r--arch/sparc/mm/srmmu.c10
-rw-r--r--arch/sparc64/config.in2
-rw-r--r--arch/sparc64/kernel/binfmt_aout32.c28
-rw-r--r--arch/sparc64/kernel/ioctl32.c29
-rw-r--r--arch/sparc64/kernel/iommu_common.c11
-rw-r--r--arch/sparc64/kernel/irq.c4
-rw-r--r--arch/sparc64/kernel/pci_iommu.c156
-rw-r--r--arch/sparc64/kernel/pci_psycho.c4
-rw-r--r--arch/sparc64/kernel/pci_sabre.c4
-rw-r--r--arch/sparc64/kernel/process.c5
-rw-r--r--arch/sparc64/kernel/sbus.c44
-rw-r--r--arch/sparc64/kernel/signal32.c173
-rw-r--r--arch/sparc64/kernel/smp.c10
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c14
-rw-r--r--arch/sparc64/kernel/sys_sparc.c15
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c42
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c27
-rw-r--r--arch/sparc64/kernel/systbls.S8
-rw-r--r--arch/sparc64/kernel/traps.c172
-rw-r--r--arch/sparc64/lib/Makefile6
-rw-r--r--arch/sparc64/lib/VIScsumcopy.S4
-rw-r--r--arch/sparc64/lib/VIScsumcopyusr.S914
-rw-r--r--arch/sparc64/lib/checksum.S238
-rw-r--r--arch/sparc64/mm/asyncd.c13
-rw-r--r--arch/sparc64/mm/fault.c53
-rw-r--r--arch/sparc64/mm/init.c13
-rw-r--r--arch/sparc64/solaris/misc.c8
-rw-r--r--drivers/block/Config.in21
-rw-r--r--drivers/block/DAC960.c51
-rw-r--r--drivers/block/alim15x3.c4
-rw-r--r--drivers/block/amiflop.c3
-rw-r--r--drivers/block/buddha.c36
-rw-r--r--drivers/block/cmd64x.c1
-rw-r--r--drivers/block/hpt34x.c3
-rw-r--r--drivers/block/hpt366.c28
-rw-r--r--drivers/block/icside.c8
-rw-r--r--drivers/block/ide-disk.c2
-rw-r--r--drivers/block/ide-dma.c199
-rw-r--r--drivers/block/ide-pci.c89
-rw-r--r--drivers/block/ide-pmac.c6
-rw-r--r--drivers/block/ide-probe.c1
-rw-r--r--drivers/block/ide-tape.c33
-rw-r--r--drivers/block/ide.c17
-rw-r--r--drivers/block/ll_rw_blk.c312
-rw-r--r--drivers/block/ns87415.c1
-rw-r--r--drivers/block/paride/Config.in11
-rw-r--r--drivers/block/piix.c104
-rw-r--r--drivers/block/trm290.c3
-rw-r--r--drivers/block/z2ram.c2
-rw-r--r--drivers/cdrom/Config.in4
-rw-r--r--drivers/cdrom/cdrom.c111
-rw-r--r--drivers/char/Config.in5
-rw-r--r--drivers/char/Makefile14
-rw-r--r--drivers/char/console.c34
-rw-r--r--drivers/char/dtlk.c20
-rw-r--r--drivers/char/ftape/Config.in8
-rw-r--r--drivers/char/h8.c47
-rw-r--r--drivers/char/keyboard.c9
-rw-r--r--drivers/char/mem.c6
-rw-r--r--drivers/char/misc.c15
-rw-r--r--drivers/char/mixcomwd.c250
-rw-r--r--drivers/char/moxa.c1
-rw-r--r--drivers/char/pc_keyb.c9
-rw-r--r--drivers/char/random.c12
-rw-r--r--drivers/char/rtc.c173
-rw-r--r--drivers/char/saa5249.c290
-rw-r--r--drivers/char/serial.c647
-rw-r--r--drivers/char/sx.c14
-rw-r--r--drivers/char/wdt.c26
-rw-r--r--drivers/fc4/fc.c99
-rw-r--r--drivers/fc4/fcp_impl.h16
-rw-r--r--drivers/fc4/soc.c4
-rw-r--r--drivers/fc4/socal.c4
-rw-r--r--drivers/i2o/i2o_core.c23
-rw-r--r--drivers/net/Space.c4
-rw-r--r--drivers/net/a2065.c163
-rw-r--r--drivers/net/a2065.h11
-rw-r--r--drivers/net/ariadne.c359
-rw-r--r--drivers/net/ariadne.h19
-rw-r--r--drivers/net/ariadne2.c34
-rw-r--r--drivers/net/eexpress.c69
-rw-r--r--drivers/net/hydra.c108
-rw-r--r--drivers/net/pcmcia/Config.in4
-rw-r--r--drivers/net/pcnet32.c138
-rw-r--r--drivers/net/setup.c21
-rw-r--r--drivers/net/sunbmac.c8
-rw-r--r--drivers/net/sunhme.c75
-rw-r--r--drivers/net/sunlance.c6
-rw-r--r--drivers/net/sunqe.c12
-rw-r--r--drivers/net/tokenring/Config.in15
-rw-r--r--drivers/net/tokenring/Makefile18
-rw-r--r--drivers/net/tokenring/abyss.c512
-rw-r--r--drivers/net/tokenring/abyss.h58
-rw-r--r--drivers/net/tokenring/madgemc.c806
-rw-r--r--drivers/net/tokenring/madgemc.h70
-rw-r--r--drivers/net/tokenring/smctr.c254
-rw-r--r--drivers/net/tokenring/smctr.h7
-rw-r--r--drivers/net/tokenring/tms380tr.c901
-rw-r--r--drivers/net/tokenring/tms380tr.h239
-rw-r--r--drivers/net/tokenring/tmspci.c336
-rw-r--r--drivers/net/wan/Config.in5
-rw-r--r--drivers/net/wan/Makefile6
-rw-r--r--drivers/net/wan/cycx_main.c16
-rw-r--r--drivers/net/wan/cycx_x25.c9
-rw-r--r--drivers/net/wan/sdla.c4
-rw-r--r--drivers/net/wan/sdla_chdlc.c2785
-rw-r--r--drivers/net/wan/sdla_fr.c4734
-rw-r--r--drivers/net/wan/sdla_ppp.c3488
-rw-r--r--drivers/net/wan/sdladrv.c1104
-rw-r--r--drivers/net/wan/sdlamain.c638
-rw-r--r--drivers/parport/init.c2
-rw-r--r--drivers/parport/parport_amiga.c65
-rw-r--r--drivers/parport/parport_mfc3.c140
-rw-r--r--drivers/parport/parport_pc.c46
-rw-r--r--drivers/parport/procfs.c2
-rw-r--r--drivers/pci/compat.c4
-rw-r--r--drivers/pci/gen-devlist.c2
-rw-r--r--drivers/pci/pci.c24
-rw-r--r--drivers/pci/pcisyms.c1
-rw-r--r--drivers/pci/proc.c26
-rw-r--r--drivers/pcmcia/ricoh.h1
-rw-r--r--drivers/pnp/Makefile6
-rw-r--r--drivers/pnp/isapnp.c1
-rw-r--r--drivers/sbus/audio/amd7930.c6
-rw-r--r--drivers/sbus/audio/cs4231.c63
-rw-r--r--drivers/sbus/audio/dbri.c14
-rw-r--r--drivers/sbus/char/Makefile7
-rw-r--r--drivers/sbus/char/jsflash.c9
-rw-r--r--drivers/sbus/char/uctrl.c4
-rw-r--r--drivers/sbus/char/vfc_i2c.c2
-rw-r--r--drivers/scsi/3w-xxxx.c2223
-rw-r--r--drivers/scsi/3w-xxxx.h369
-rw-r--r--drivers/scsi/53c7xx.c1
-rw-r--r--drivers/scsi/Config.in20
-rw-r--r--drivers/scsi/Makefile15
-rw-r--r--drivers/scsi/a2091.c25
-rw-r--r--drivers/scsi/a3000.c2
-rw-r--r--drivers/scsi/aha1542.c70
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx.seq2
-rw-r--r--drivers/scsi/amiga7xx.c160
-rw-r--r--drivers/scsi/blz1230.c48
-rw-r--r--drivers/scsi/blz2060.c25
-rw-r--r--drivers/scsi/cyberstorm.c34
-rw-r--r--drivers/scsi/cyberstormII.c27
-rw-r--r--drivers/scsi/eata_dma.c10
-rw-r--r--drivers/scsi/eata_dma_proc.c49
-rw-r--r--drivers/scsi/esp.c12
-rw-r--r--drivers/scsi/fastlane.c36
-rw-r--r--drivers/scsi/gdth.c59
-rw-r--r--drivers/scsi/gdth.h3
-rw-r--r--drivers/scsi/gdth_proc.c86
-rw-r--r--drivers/scsi/gdth_proc.h4
-rw-r--r--drivers/scsi/gvp11.c65
-rw-r--r--drivers/scsi/hosts.c10
-rw-r--r--drivers/scsi/hosts.h12
-rw-r--r--drivers/scsi/megaraid.c53
-rw-r--r--drivers/scsi/megaraid.h2
-rw-r--r--drivers/scsi/oktagon_esp.c24
-rw-r--r--drivers/scsi/pci2220i.h2
-rw-r--r--drivers/scsi/qlogicfc.c152
-rw-r--r--drivers/scsi/qlogicfc_asm.c14844
-rw-r--r--drivers/scsi/qlogicpti.c22
-rw-r--r--drivers/scsi/scsi.c1270
-rw-r--r--drivers/scsi/scsi.h110
-rw-r--r--drivers/scsi/scsi_debug.c14
-rw-r--r--drivers/scsi/scsi_dma.c449
-rw-r--r--drivers/scsi/scsi_ioctl.c21
-rw-r--r--drivers/scsi/scsi_lib.c25
-rw-r--r--drivers/scsi/scsi_merge.c119
-rw-r--r--drivers/scsi/scsi_obsolete.c1
-rw-r--r--drivers/scsi/scsi_scan.c820
-rw-r--r--drivers/scsi/sd.c19
-rw-r--r--drivers/scsi/sr.c18
-rw-r--r--drivers/scsi/sr_ioctl.c39
-rw-r--r--drivers/scsi/sr_vendor.c14
-rw-r--r--drivers/sgi/char/graphics.c12
-rw-r--r--drivers/sgi/char/shmiq.c12
-rw-r--r--drivers/sound/ad1848.c87
-rw-r--r--drivers/sound/audio.c8
-rw-r--r--drivers/sound/cmpci.c3
-rw-r--r--drivers/sound/dmasound.c34
-rw-r--r--drivers/sound/esssolo1.c1
-rw-r--r--drivers/sound/msnd_pinnacle.c1
-rw-r--r--drivers/sound/soundcard.c4
-rw-r--r--drivers/usb/Config.in23
-rw-r--r--drivers/usb/Makefile25
-rw-r--r--drivers/usb/audio.c4
-rw-r--r--drivers/usb/bitstream.h1508
-rw-r--r--drivers/usb/dabfirmware.h1408
-rw-r--r--drivers/usb/dabusb.c3
-rw-r--r--drivers/usb/dc2xx.c4
-rw-r--r--drivers/usb/devices.c4
-rw-r--r--drivers/usb/firmware.h3213
-rw-r--r--drivers/usb/graphire.c71
-rw-r--r--drivers/usb/hid.c80
-rw-r--r--drivers/usb/hid.h2
-rw-r--r--drivers/usb/hub.c66
-rw-r--r--drivers/usb/ibmcam.c2346
-rw-r--r--drivers/usb/ibmcam.h222
-rw-r--r--drivers/usb/keybdev.c6
-rw-r--r--drivers/usb/mousedev.c55
-rw-r--r--drivers/usb/ov511.c34
-rw-r--r--drivers/usb/scanner.c397
-rw-r--r--drivers/usb/scanner.h55
-rw-r--r--drivers/usb/uhci-debug.c245
-rw-r--r--drivers/usb/uhci-debug.h202
-rw-r--r--drivers/usb/usb-core.c8
-rw-r--r--drivers/usb/usb-debug.c31
-rw-r--r--drivers/usb/usb-ohci.c (renamed from drivers/usb/ohci-hcd.c)23
-rw-r--r--drivers/usb/usb-ohci.h (renamed from drivers/usb/ohci-hcd.h)2
-rw-r--r--drivers/usb/usb-serial.c315
-rw-r--r--drivers/usb/usb-uhci.c (renamed from drivers/usb/uhci.c)377
-rw-r--r--drivers/usb/usb-uhci.h (renamed from drivers/usb/uhci.h)5
-rw-r--r--drivers/usb/usb.c158
-rw-r--r--drivers/usb/usb.h38
-rw-r--r--drivers/usb/usb_scsi.c1539
-rw-r--r--drivers/usb/usb_scsi_debug.c102
-rw-r--r--drivers/usb/usb_storage.c1837
-rw-r--r--drivers/usb/usb_storage.h (renamed from drivers/usb/usb_scsi.h)86
-rw-r--r--drivers/usb/usb_storage_debug.c104
-rw-r--r--drivers/usb/usbdevice_fs.h1
-rw-r--r--drivers/usb/usbkbd.c3
-rw-r--r--drivers/usb/usbmouse.c3
-rw-r--r--drivers/usb/uss720.c21
-rw-r--r--drivers/usb/wmforce.c4
-rw-r--r--drivers/video/Config.in9
-rw-r--r--drivers/video/amifb.c2
-rw-r--r--drivers/video/bwtwofb.c4
-rw-r--r--drivers/video/clgenfb.c63
-rw-r--r--drivers/video/cvisionppc.h2
-rw-r--r--drivers/video/cyberfb.c123
-rw-r--r--drivers/video/fbcon.c2
-rw-r--r--drivers/video/fbgen.c2
-rw-r--r--drivers/video/fbmem.c6
-rw-r--r--drivers/video/fm2fb.c176
-rw-r--r--drivers/video/igafb.c32
-rw-r--r--drivers/video/offb.c3
-rw-r--r--drivers/video/platinumfb.h2
-rw-r--r--drivers/video/pm2fb.c2
-rw-r--r--drivers/video/pm2fb.h2
-rw-r--r--drivers/video/retz3fb.c126
-rw-r--r--drivers/video/rivafb.c2
-rw-r--r--drivers/video/skeletonfb.c5
-rw-r--r--drivers/video/virgefb.c111
-rw-r--r--drivers/zorro/Makefile4
-rw-r--r--drivers/zorro/names.c83
-rw-r--r--drivers/zorro/proc.c37
-rw-r--r--drivers/zorro/zorro.c177
-rw-r--r--drivers/zorro/zorrosyms.c7
-rw-r--r--fs/Config.in83
-rw-r--r--fs/Makefile11
-rw-r--r--fs/autofs/init.c15
-rw-r--r--fs/autofs4/.cvsignore2
-rw-r--r--fs/autofs4/Makefile35
-rw-r--r--fs/autofs4/autofs_i.h175
-rw-r--r--fs/autofs4/expire.c234
-rw-r--r--fs/autofs4/init.c35
-rw-r--r--fs/autofs4/inode.c423
-rw-r--r--fs/autofs4/inohash.c68
-rw-r--r--fs/autofs4/root.c624
-rw-r--r--fs/autofs4/symlink.c34
-rw-r--r--fs/autofs4/waitq.c251
-rw-r--r--fs/block_dev.c2
-rw-r--r--fs/dcache.c26
-rw-r--r--fs/devices.c4
-rw-r--r--fs/dquot.c41
-rw-r--r--fs/ext2/namei.c20
-rw-r--r--fs/fat/misc.c1
-rw-r--r--fs/filesystems.c4
-rw-r--r--fs/hpfs/hpfs_fn.h4
-rw-r--r--fs/inode.c23
-rw-r--r--fs/isofs/util.c5
-rw-r--r--fs/namei.c6
-rw-r--r--fs/ncpfs/dir.c24
-rw-r--r--fs/ncpfs/file.c27
-rw-r--r--fs/ncpfs/inode.c2
-rw-r--r--fs/ncpfs/ioctl.c1
-rw-r--r--fs/ncpfs/mmap.c12
-rw-r--r--fs/nfs/write.c4
-rw-r--r--fs/nfsd/nfsfh.c2
-rw-r--r--fs/open.c9
-rw-r--r--fs/partitions/Config.in27
-rw-r--r--fs/partitions/check.c1
-rw-r--r--fs/partitions/sgi.c8
-rw-r--r--fs/partitions/sun.c6
-rw-r--r--fs/partitions/ultrix.c27
-rw-r--r--fs/partitions/ultrix.h10
-rw-r--r--fs/select.c130
-rw-r--r--fs/super.c127
-rw-r--r--fs/udf/dir.c14
-rw-r--r--fs/udf/directory.c4
-rw-r--r--fs/udf/file.c317
-rw-r--r--fs/udf/fsync.c29
-rw-r--r--fs/udf/ialloc.c11
-rw-r--r--fs/udf/inode.c467
-rw-r--r--fs/udf/lowlevel.c26
-rw-r--r--fs/udf/misc.c19
-rw-r--r--fs/udf/namei.c62
-rw-r--r--fs/udf/partition.c275
-rw-r--r--fs/udf/super.c91
-rw-r--r--fs/udf/symlink.c62
-rw-r--r--fs/udf/truncate.c51
-rw-r--r--fs/udf/udf_i.h7
-rw-r--r--fs/udf/udf_sb.h4
-rw-r--r--fs/udf/udfdecl.h22
-rw-r--r--fs/udf/udftime.c2
-rw-r--r--fs/udf/unicode.c98
-rw-r--r--include/asm-alpha/ioctls.h3
-rw-r--r--include/asm-alpha/parport.h8
-rw-r--r--include/asm-alpha/siginfo.h2
-rw-r--r--include/asm-arm/parport.h8
-rw-r--r--include/asm-arm/siginfo.h18
-rw-r--r--include/asm-arm/termios.h1
-rw-r--r--include/asm-i386/parport.h8
-rw-r--r--include/asm-i386/pci.h131
-rw-r--r--include/asm-i386/semaphore.h11
-rw-r--r--include/asm-i386/siginfo.h18
-rw-r--r--include/asm-i386/termios.h1
-rw-r--r--include/asm-i386/types.h4
-rw-r--r--include/asm-i386/unistd.h1
-rw-r--r--include/asm-m68k/amigahw.h2
-rw-r--r--include/asm-m68k/apollodma.h248
-rw-r--r--include/asm-m68k/apollohw.h54
-rw-r--r--include/asm-m68k/bootinfo.h32
-rw-r--r--include/asm-m68k/bvme6000hw.h1
-rw-r--r--include/asm-m68k/cache.h12
-rw-r--r--include/asm-m68k/div64.h35
-rw-r--r--include/asm-m68k/dma.h13
-rw-r--r--include/asm-m68k/entry.h10
-rw-r--r--include/asm-m68k/fcntl.h2
-rw-r--r--include/asm-m68k/hardirq.h4
-rw-r--r--include/asm-m68k/mmu_context.h1
-rw-r--r--include/asm-m68k/movs.h28
-rw-r--r--include/asm-m68k/mvme147hw.h3
-rw-r--r--include/asm-m68k/mvme16xhw.h1
-rw-r--r--include/asm-m68k/page.h78
-rw-r--r--include/asm-m68k/page_offset.h9
-rw-r--r--include/asm-m68k/pci.h38
-rw-r--r--include/asm-m68k/pgalloc.h399
-rw-r--r--include/asm-m68k/pgtable.h524
-rw-r--r--include/asm-m68k/poll.h1
-rw-r--r--include/asm-m68k/semaphore.h175
-rw-r--r--include/asm-m68k/setup.h3
-rw-r--r--include/asm-m68k/siginfo.h16
-rw-r--r--include/asm-m68k/stat.h38
-rw-r--r--include/asm-m68k/system.h65
-rw-r--r--include/asm-m68k/termios.h3
-rw-r--r--include/asm-m68k/uaccess.h59
-rw-r--r--include/asm-m68k/virtconvert.h17
-rw-r--r--include/asm-mips/checksum.h4
-rw-r--r--include/asm-mips/parport.h10
-rw-r--r--include/asm-mips/pci.h160
-rw-r--r--include/asm-mips/semaphore.h176
-rw-r--r--include/asm-mips/siginfo.h4
-rw-r--r--include/asm-mips/termios.h3
-rw-r--r--include/asm-mips/types.h4
-rw-r--r--include/asm-mips/unistd.h5
-rw-r--r--include/asm-mips64/checksum.h4
-rw-r--r--include/asm-mips64/parport.h10
-rw-r--r--include/asm-mips64/pci.h160
-rw-r--r--include/asm-mips64/semaphore.h179
-rw-r--r--include/asm-mips64/siginfo.h4
-rw-r--r--include/asm-mips64/termios.h3
-rw-r--r--include/asm-mips64/types.h4
-rw-r--r--include/asm-mips64/unistd.h20
-rw-r--r--include/asm-ppc/siginfo.h2
-rw-r--r--include/asm-ppc/termios.h3
-rw-r--r--include/asm-sparc/asm_offsets.h136
-rw-r--r--include/asm-sparc/hdreg.h13
-rw-r--r--include/asm-sparc/ide.h289
-rw-r--r--include/asm-sparc/io.h11
-rw-r--r--include/asm-sparc/irq.h3
-rw-r--r--include/asm-sparc/pci.h3
-rw-r--r--include/asm-sparc/processor.h10
-rw-r--r--include/asm-sparc/sbus.h6
-rw-r--r--include/asm-sparc/semaphore.h11
-rw-r--r--include/asm-sparc/sembuf.h2
-rw-r--r--include/asm-sparc/siginfo.h11
-rw-r--r--include/asm-sparc/smp.h6
-rw-r--r--include/asm-sparc/stat.h36
-rw-r--r--include/asm-sparc/termbits.h3
-rw-r--r--include/asm-sparc/unistd.h2
-rw-r--r--include/asm-sparc64/asm_offsets.h162
-rw-r--r--include/asm-sparc64/checksum.h24
-rw-r--r--include/asm-sparc64/dma.h6
-rw-r--r--include/asm-sparc64/floppy.h17
-rw-r--r--include/asm-sparc64/io.h2
-rw-r--r--include/asm-sparc64/parport.h2
-rw-r--r--include/asm-sparc64/pci.h57
-rw-r--r--include/asm-sparc64/processor.h15
-rw-r--r--include/asm-sparc64/sbus.h12
-rw-r--r--include/asm-sparc64/semaphore.h11
-rw-r--r--include/asm-sparc64/siginfo.h9
-rw-r--r--include/asm-sparc64/smp.h6
-rw-r--r--include/asm-sparc64/termbits.h3
-rw-r--r--include/asm-sparc64/types.h4
-rw-r--r--include/asm-sparc64/unistd.h2
-rw-r--r--include/linux/acpi.h130
-rw-r--r--include/linux/auto_fs.h21
-rw-r--r--include/linux/blkdev.h3
-rw-r--r--include/linux/cdrom.h4
-rw-r--r--include/linux/cyclomx.h6
-rw-r--r--include/linux/etherdevice.h3
-rw-r--r--include/linux/fs.h15
-rw-r--r--include/linux/hdreg.h1
-rw-r--r--include/linux/hfs_sysdep.h2
-rw-r--r--include/linux/highuid.h9
-rw-r--r--include/linux/ide.h6
-rw-r--r--include/linux/init.h2
-rw-r--r--include/linux/input.h15
-rw-r--r--include/linux/isapnp.h2
-rw-r--r--include/linux/kdev_t.h2
-rw-r--r--include/linux/mm.h20
-rw-r--r--include/linux/parport_pc.h5
-rw-r--r--include/linux/pci.h23
-rw-r--r--include/linux/pci_ids.h13
-rw-r--r--include/linux/pm.h157
-rw-r--r--include/linux/random.h2
-rw-r--r--include/linux/sdla_chdlc.h808
-rw-r--r--include/linux/sdla_fr.h260
-rw-r--r--include/linux/sdla_ppp.h231
-rw-r--r--include/linux/sdladrv.h20
-rw-r--r--include/linux/sdlapci.h68
-rw-r--r--include/linux/sdlasfm.h16
-rw-r--r--include/linux/serial.h14
-rw-r--r--include/linux/serialP.h38
-rw-r--r--include/linux/skbuff.h13
-rw-r--r--include/linux/slab.h3
-rw-r--r--include/linux/smp.h1
-rw-r--r--include/linux/sockios.h4
-rw-r--r--include/linux/sysctl.h7
-rw-r--r--include/linux/tcp.h1
-rw-r--r--include/linux/udf_fs.h37
-rw-r--r--include/linux/udf_fs_i.h3
-rw-r--r--include/linux/udf_fs_sb.h28
-rw-r--r--include/linux/udf_udf.h3
-rw-r--r--include/linux/utsname.h2
-rw-r--r--include/linux/videodev.h1
-rw-r--r--include/linux/wanpipe.h196
-rw-r--r--include/linux/wanrouter.h174
-rw-r--r--include/linux/zorro.h34
-rw-r--r--include/net/dst.h6
-rw-r--r--include/net/ip.h2
-rw-r--r--include/net/route.h3
-rw-r--r--include/net/snmp.h19
-rw-r--r--include/net/sock.h167
-rw-r--r--include/net/tcp.h727
-rw-r--r--ipc/shm.c13
-rw-r--r--kernel/dma.c26
-rw-r--r--kernel/exit.c6
-rw-r--r--kernel/ksyms.c7
-rw-r--r--kernel/sched.c2
-rw-r--r--kernel/signal.c5
-rw-r--r--kernel/sys.c23
-rw-r--r--kernel/sysctl.c15
-rw-r--r--lib/vsprintf.c7
-rw-r--r--mm/filemap.c23
-rw-r--r--mm/page_alloc.c67
-rw-r--r--mm/vmscan.c49
-rw-r--r--net/ax25/af_ax25.c2
-rw-r--r--net/core/datagram.c19
-rw-r--r--net/core/iovec.c12
-rw-r--r--net/core/skbuff.c16
-rw-r--r--net/core/sock.c116
-rw-r--r--net/ethernet/eth.c7
-rw-r--r--net/ipv4/af_inet.c261
-rw-r--r--net/ipv4/arp.c10
-rw-r--r--net/ipv4/ip_input.c13
-rw-r--r--net/ipv4/ip_output.c12
-rw-r--r--net/ipv4/ip_sockglue.c4
-rw-r--r--net/ipv4/ipconfig.c9
-rw-r--r--net/ipv4/proc.c16
-rw-r--r--net/ipv4/raw.c8
-rw-r--r--net/ipv4/route.c49
-rw-r--r--net/ipv4/syncookies.c34
-rw-r--r--net/ipv4/sysctl_net_ipv4.c34
-rw-r--r--net/ipv4/tcp.c1048
-rw-r--r--net/ipv4/tcp_input.c1370
-rw-r--r--net/ipv4/tcp_ipv4.c951
-rw-r--r--net/ipv4/tcp_output.c495
-rw-r--r--net/ipv4/tcp_timer.c648
-rw-r--r--net/ipv4/udp.c182
-rw-r--r--net/ipv6/addrconf.c24
-rw-r--r--net/ipv6/af_inet6.c19
-rw-r--r--net/ipv6/icmp.c18
-rw-r--r--net/ipv6/ip6_fib.c6
-rw-r--r--net/ipv6/ipv6_sockglue.c6
-rw-r--r--net/ipv6/mcast.c11
-rw-r--r--net/ipv6/raw.c8
-rw-r--r--net/ipv6/route.c14
-rw-r--r--net/ipv6/tcp_ipv6.c962
-rw-r--r--net/ipv6/udp.c100
-rw-r--r--net/irda/af_irda.c2
-rw-r--r--net/khttpd/accept.c2
-rw-r--r--net/khttpd/datasending.c2
-rw-r--r--net/khttpd/sockets.c5
-rw-r--r--net/khttpd/userspace.c21
-rw-r--r--net/khttpd/waitheaders.c2
-rw-r--r--net/netlink/af_netlink.c35
-rw-r--r--net/netrom/af_netrom.c2
-rw-r--r--net/netsyms.c21
-rw-r--r--net/packet/af_packet.c20
-rw-r--r--net/rose/af_rose.c2
-rw-r--r--net/socket.c46
-rw-r--r--net/sunrpc/xprt.c2
-rw-r--r--net/unix/af_unix.c114
-rw-r--r--net/wanrouter/wanmain.c213
-rw-r--r--net/wanrouter/wanproc.c142
630 files changed, 52413 insertions, 32867 deletions
diff --git a/CREDITS b/CREDITS
index 91ae4ccca..693d651f1 100644
--- a/CREDITS
+++ b/CREDITS
@@ -854,12 +854,12 @@ S: Oakland, CA
S: USA
N: Jochen Hein
-E: jochen.hein@delphi.central.de
+E: jochen@jochen.org
P: 1024/4A27F015 25 72 FB E3 85 9F DE 3B CB 0A DA DA 40 77 05 6C
D: National Language Support
D: Linux Internationalization Project
D: German Localization for Linux and GNU software
-S: Frankenstraße
+S: Frankenstraße 33
S: 34131 Kassel
S: Germany
@@ -937,7 +937,7 @@ S: CV5 8BZ
S: United Kingdom
N: Ron Holt
-E: ron@holt.org
+E: ron@sovereign.org
W: http://www.holt.org/
W: http://www.ronholt.com/
D: Kernel development
@@ -998,6 +998,14 @@ S: Cambridge
S: CB3 0DS
S: United Kingdom
+N: Andreas Jaeger
+E: aj@suse.de
+D: Various smaller kernel fixes
+D: glibc developer
+S: Gottfried-Kinkel-Str. 18
+S: D 67659 Kaiserslautern
+S: Germany
+
N: Mike Jagdis
E: jaggy@purplet.demon.co.uk
E: Mike.Jagdis@purplet.demon.co.uk
@@ -1667,7 +1675,7 @@ E: vojtech@suse.cz
D: Joystick driver
D: arcnet-hardware readme
D: Minor ARCnet hacking
-D: USB hacking
+D: USB (HID, ACM, Printer ...)
S: Ucitelska 1576
S: Prague 8
S: 182 00 Czech Republic
diff --git a/Documentation/Configure.help b/Documentation/Configure.help
index 4ea28a70c..701089489 100644
--- a/Documentation/Configure.help
+++ b/Documentation/Configure.help
@@ -4444,15 +4444,6 @@ CONFIG_SCSI_IPS
does not work correctly without modification please contact the
author by email at ipslinux@us.ibm.com.
-IBM ServeRAID Support
-CONFIG_SCSI_IPS
- This is support for the IBM ServeRAID hardware RAID controllers.
- Consult the SCSI-HOWTO, available via anonymous FTP from
- ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, and the file
- README.ips in drivers/scsi for more information. If this driver
- does not work correctly without modification please contact the
- author by email at ipslinux@us.ibm.com.
-
BusLogic SCSI support
CONFIG_SCSI_BUSLOGIC
This is support for BusLogic MultiMaster and FlashPoint SCSI Host
@@ -8031,8 +8022,8 @@ CONFIG_USB_UHCI
The module will be called usb-uhci.o. If you want to compile it as a
module, say M here and read Documentation/modules.txt.
-OHCI-HCD (Compaq, iMacs, OPTi, SiS, ALi, ...) support?
-CONFIG_USB_OHCI_HCD
+OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support?
+CONFIG_USB_OHCI
The Open Host Controller Interface is a standard by
Compaq/Microsoft/National for accessing the USB PC hardware (also
called USB host controller). If your USB host controller conforms
@@ -8041,11 +8032,11 @@ CONFIG_USB_OHCI_HCD
chipsets - like SiS (actual 610, 610 and so on) or ALi (ALi IV, ALi V,
Aladdin Pro..) - conform to this standard.
- You may want to read the file Documentation/usb/ohci-hcd.txt.
+ You may want to read the file Documentation/usb/ohci.txt.
This code 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 usb-ohci-hcd.o. If you want to compile it
+ The module will be called usb-ohci.o. If you want to compile it
as a module, say M here and read Documentation/modules.txt.
USB Human Interface Device (HID) support
@@ -8095,6 +8086,21 @@ CONFIG_INPUT_MOUSEDEV_MIX
into one misc device. If you say N, you'll have a separate
device for each your USB mouse.
+Support for digitizers
+CONFIG_INPUT_MOUSEDEV_DIGITIZER
+ Use this if you have a digitizer that doesn't emulate a mouse
+ itself, and want to use it as a mouse.
+
+Horizontal screen resolution
+CONFIG_INPUT_MOUSEDEV_SCREEN_X
+ For the mouse emulation to be correct, the mousedev driver needs
+ to know the screen resolution you are using (in X).
+
+Vertical screen resolution
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y
+ For the mouse emulation to be correct, the mousedev driver needs
+ to know the screen resolution you are using (in X).
+
Joystick support
CONFIG_INPUT_JOYDEV
Say Y here if you want your USB HID joystick or gamepad to be
@@ -8192,17 +8198,47 @@ CONFIG_USB_CPIA
Say Y here if you want to connect this type of camera to your
computer's USB port.
+ This driver uses the Video For Linux API. You must enable
+ (Y or M in config) Video For Linux (under Character Devices)
+ to use this driver. Information on this API and pointers to
+ "v4l" programs may be found on the WWW at
+ http://roadrunner.swansea.uk.linux.org/v4l.shtml .
+
This code 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 cpia.o. If you want to compile it as a
module, say M here and read Documentation/modules.txt.
+USB IBM (Xirlink) C-It Camera support
+CONFIG_USB_IBMCAM
+ Say Y here if you want to connect this type of camera to your
+ computer's USB port.
+
+ This driver uses the Video For Linux API. You must enable
+ (Y or M in config) Video For Linux (under Character Devices)
+ to use this driver. Information on this API and pointers to
+ "v4l" programs may be found on the WWW at
+ http://roadrunner.swansea.uk.linux.org/v4l.shtml .
+
+ This code 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 ibmcam.o. If you want to compile it as a
+ module, say M here and read Documentation/modules.txt. This camera
+ has several configuration options which can be specified when you
+ load the module. Read Documentation/usb/ibmcam.txt to learn more.
+
USB OV511 Camera support
CONFIG_USB_OV511
Say Y here if you want to connect this type of camera to your
computer's USB port. See Documentation/usb/ov511.txt for more
information and for a list of supported cameras.
+ This driver uses the Video For Linux API. You must enable
+ (Y or M in config) Video For Linux (under Character Devices)
+ to use this driver. Information on this API and pointers to
+ "v4l" programs may be found on the WWW at
+ http://roadrunner.swansea.uk.linux.org/v4l.shtml .
+
This code 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 ov511.o. If you want to compile it as a
@@ -8220,20 +8256,20 @@ CONFIG_USB_DC2XX
The module will be called dc2xx.o. If you want to compile it as a
module, say M here and read Documentation/modules.txt.
-USB SCSI (mass storage) support
-CONFIG_USB_SCSI
+USB Mass Storage support
+CONFIG_USB_STORAGE
Say Y here if you want to connect USB mass storage devices to your
computer's USB port.
This code 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 usb-scsi.o. If you want to compile it as a
- module, say M here and read Documentation/modules.txt.
+ The module will be called usb-storage.o. If you want to compile it
+ as a module, say M here and read Documentation/modules.txt.
-USB SCSI verbose debug
-CONFIG_USB_SCSI_DEBUG
- Say Y here in order to have the USB SCSI code generate verbose
- debugging messages.
+USB Mass Storage verbose debug
+CONFIG_USB_STORAGE_DEBUG
+ Say Y here in order to have the USB Mass Storage code generate
+ verbose debugging messages.
USS720 parport driver
CONFIG_USB_USS720
@@ -10607,9 +10643,10 @@ CONFIG_RTC
major number 10 and minor number 135 using mknod ("man mknod"), you
will get access to the real time clock built into your computer.
Every PC has such a clock built in. It can be used to generate
- signals from as low as 1Hz up to 8192Hz, and can also be used as a
- 24 hour alarm. It reports status information via the file /proc/rtc
- and its behaviour is set by various ioctls on /dev/rtc.
+ signals from as low as 1Hz up to 8192Hz, and can also be used
+ as a 24 hour alarm. It reports status information via the file
+ /proc/driver/rtc and its behaviour is set by various ioctls on
+ /dev/rtc.
If you run Linux on a multiprocessor machine and said Y to
"Symmetric Multi Processing" above, you should say Y here to read
@@ -11915,6 +11952,11 @@ CONFIG_SUN_MOSTEK_RTC
Say Y here unless you are building a special purpose kernel.
+JavaStation OS Flash SIMM (EXPERIMENTAL)
+CONFIG_SUN_JSFLASH
+ This option enables a driver for JavaStation OS Flash driver.
+ Say N unless you want to boot from your Flash SIMM.
+
#Siemens SAB82532 serial support
#CONFIG_SAB82532
###
@@ -12294,13 +12336,11 @@ CONFIG_ATARI_SCSI_TOSHIBA_DELAY
use a Toshiba CD-ROM drive; otherwise, the option is not needed and
would impact performance a bit, so say N.
-Hades SCSI DMA emulator (EXPERIMENTAL)
+Hades SCSI DMA emulator
CONFIG_TT_DMA_EMUL
This option enables code which emulates the TT SCSI DMA chip on the
Hades. This increases the SCSI transfer rates at least ten times
- compared to PIO transfers. Note that this code is experimental and
- has only been tested on a Hades with a 68060 processor. Before you
- use this, make backups of your entire hard disk.
+ compared to PIO transfers.
Ariadne support
CONFIG_ARIADNE
diff --git a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt
new file mode 100644
index 000000000..c48758677
--- /dev/null
+++ b/Documentation/DMA-mapping.txt
@@ -0,0 +1,143 @@
+ Dynamic DMA mapping
+ ===================
+
+ David S. Miller <davem@redhat.com>
+ Richard Henderson <rth@cygnus.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+Most of the 64bit platforms have special hardware that translates bus
+addresses (DMA addresses) to physical addresses similarly to how page
+tables and/or TLB translate virtual addresses to physical addresses.
+This is needed so that e.g. PCI devices can access with a Single Address
+Cycle (32bit DMA address) any page in the 64bit physical address space.
+Previously in Linux those 64bit platforms had to set artificial limits on
+the maximum RAM size in the system, so that the virt_to_bus() static scheme
+works (the DMA address translation tables were simply filled on bootup
+to map each bus address to the physical page __pa(bus_to_virt())).
+
+So that Linux can use the dynamic DMA mapping, it needs some help from the
+drivers, namely it has to take into account that DMA addresses should be
+mapped only for the time they are actually used and unmapped after the DMA
+transfer.
+
+The following API will work of course even on platforms where no such
+hardware exists, see e.g. include/asm-i386/pci.h for how it is implemented on
+top of the virt_to_bus interface.
+
+First of all, you should make sure
+
+#include <linux/pci.h>
+
+is in your driver. This file defines a dma_addr_t type which should be
+used everywhere you hold a DMA (bus) address returned from the DMA mapping
+functions.
+
+There are two types of DMA mappings:
+- static DMA mappings which are usually mapped at driver initialization,
+ unmapped at the end and for which the hardware should not assume
+ sequential accesses (from both the DMA engine in the card and CPU).
+- streaming DMA mappings which are usually mapped for one DMA transfer,
+ unmapped right after it (unless you use pci_dma_sync below) and for which
+ hardware can optimize for sequential accesses.
+
+To allocate and map a static DMA region, you should do:
+
+ dma_addr_t dma_handle;
+
+ cpu_addr = pci_alloc_consistent(dev, size, &dma_handle);
+
+where dev is a struct pci_dev *. You should pass NULL for PCI like buses
+where devices don't have struct pci_dev (like ISA, EISA).
+This argument is needed because the DMA translations may be bus
+specific (and often is private to the bus which the device is attached to).
+Size is the length of the region you want to allocate.
+This routine will allocate RAM for that region, so it acts similarly to
+__get_free_pages (but takes size instead of page order).
+It returns two values: the virtual address which you can use to access it
+from the CPU and dma_handle which you pass to the card.
+The return address is guaranteed to be page aligned.
+
+To unmap and free such DMA region, you call:
+
+ pci_free_consistent(dev, size, cpu_addr, dma_handle);
+
+where dev, size are the same as in the above call and cpu_addr and
+dma_handle are the values pci_alloc_consistent returned.
+
+The streaming DMA mapping routines can be called from interrupt context.
+There are two versions of each map/unmap, one which map/unmap a single
+memory region, one which map/unmap a scatterlist.
+
+To map a single region, you do:
+
+ dma_addr_t dma_handle;
+
+ dma_handle = pci_map_single(dev, addr, size);
+
+and to unmap it:
+
+ pci_unmap_single(dev, dma_handle, size);
+
+You should call pci_unmap_single when the DMA activity is finished, e.g.
+from interrupt which told you the DMA transfer is done.
+
+Similarly with scatterlists, you map a region gathered from several regions by:
+
+ int i, count = pci_map_sg(dev, sglist, nents);
+ struct scatterlist *sg;
+
+ for (i = 0, sg = sglist; i < count; i++, sg++) {
+ hw_address[i] = sg_dma_address(sg);
+ hw_len[i] = sg_dma_len(sg);
+ }
+
+where nents is the number of entries in the sglist.
+The implementation is free to merge several consecutive sglist entries
+into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any
+consecutive sglist entries can be merged into one provided the first one
+ends and the second one starts on a page boundary - in fact this is a huge
+advantage for cards which either cannot do scatter-gather or have very
+limited number of scatter-gather entries) and returns the actual number
+of sg entries it mapped them too.
+Then you should loop count times (note: this can be less than nents times)
+and use sg_dma_address() and sg_dma_length() macros where you previously
+accessed sg->address and sg->length as shown above.
+
+To unmap a scatterlist, just call:
+
+ pci_unmap_sg(dev, sglist, nents);
+
+Again, make sure DMA activity finished.
+Every pci_map_{single,sg} call should have its pci_unmap_{single,sg}
+counterpart, because the bus address space is a shared resource (although
+in some ports the mapping is per each BUS so less devices contend for the
+same bus address space) and you could render the machine unusable by eating
+all bus addresses.
+
+If you need to use the same streaming DMA region multiple times and touch
+the data in between the DMA transfers, just map it
+with pci_map_{single,sg}, after each DMA transfer call either:
+
+ pci_dma_sync_single(dev, dma_handle, size);
+
+or:
+
+ pci_dma_sync_sg(dev, sglist, nents);
+
+and after the last DMA transfer call one of the DMA unmap routines
+pci_unmap_{single,sg}. If you don't touch the data from the first pci_map_*
+call till pci_unmap_*, then you don't have to call pci_sync_* routines.
+
+Drivers converted fully to this interface should not use virt_to_bus any
+longer, nor should they use bus_to_virt. Some drivers have to be changed a
+little bit, because there is no longer an equivalent to bus_to_virt in the
+dynamic DMA mapping scheme - you have to always store the DMA addresses
+returned by the pci_alloc_consistent and pci_map_single calls (pci_map_sg
+stores them in the scatterlist itself if the platform supports dynamic DMA
+mapping in hardware) in your driver structures and/or in the card registers.
+
+For PCI cards which recognize fewer address lines than 32 in Single
+Address Cycle, you should set corresponding pci_dev's dma_mask field to a
+different mask. The dma mapping routines then should either honour your request
+and allocate the DMA only with the bus address with bits set in your
+dma_mask or should complain that the device is not supported on that platform.
diff --git a/Documentation/filesystems/udf.txt b/Documentation/filesystems/udf.txt
index 5db0ed332..1bc75744c 100644
--- a/Documentation/filesystems/udf.txt
+++ b/Documentation/filesystems/udf.txt
@@ -1,7 +1,7 @@
*
* ./Documentation/filesystems/udf.txt
*
-UDF Filesystem version 0.8.9
+UDF Filesystem version 0.9.0
If you encounter problems with reading UDF discs using this driver,
please report them to linux_udf@hootie.lvld.hp.com, which is the
@@ -19,8 +19,6 @@ The following mount options are supported:
unhide Show otherwise hidden files.
undelete Show deleted files in lists.
strict Set strict conformance (unused)
- utf8 (unused)
- iocharset (unused)
The remaining are for debugging and disaster recovery:
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index e432afc64..482fbecb0 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -64,8 +64,14 @@ inet_peer_gc_maxtime - INTEGER
TCP variables:
tcp_syn_retries - INTEGER
- Number of times initial SYNs for an TCP connection attempt will
- be retransmitted. Should not be higher than 255.
+ Number of times initial SYNs for an active TCP connection attempt
+ will be retransmitted. Should not be higher than 255. Default value
+ is 5, which corresponds to ~180seconds.
+
+tcp_synack_retries - INTEGER
+ Number of times SYNACKs for a passive TCP connection attempt will
+ be retransmitted. Should not be higher than 255. Default value
+ is 5, which corresponds to ~180seconds.
tcp_keepalive_time - INTEGER
How often TCP sends out keepalive messages when keepalive is enabled.
@@ -73,15 +79,76 @@ tcp_keepalive_time - INTEGER
tcp_keepalive_probes - INTEGER
How many keepalive probes TCP sends out, until it decides that the
- connection is broken.
+ connection is broken. Default value: 9.
+
+tcp_keepalive_interval - INTEGER
+ How frequently the probes are send out. Multiplied by
+ tcp_keepalive_probes it is time to kill not responding connection,
+ after probes started. Default value: 75sec i.e. connection
+ will be aborted after ~11 minutes of retries.
tcp_retries1 - INTEGER
+ How many times to retry before deciding that somethig is wrong
+ and it is necessary to report this suspection to network layer.
+ Minimal RFC value is 3, it is default, which corresponds
+ to ~3sec-8min depending on RTO.
+
tcp_retries2 - INTEGER
-tcp_max_delay_acks - INTEGER
+ How may times to retry before killing alive TCP connection.
+ RFC1122 says that the limit should be longer than 100 sec.
+ It is too small number. Default value 15 corresponds to ~13-30min
+ depending on RTO.
+
+tcp_orphan_retries - INTEGER
+ How may times to retry before killing TCP connection, closed
+ by our side. Default value 7 corresponds to ~50sec-16min
+ depending on RTO. If you machine is loaded WEB server,
+ you should think about lowering this value, such sockets
+ may consume significant resources. Cf. tcp_max_orphans.
+
tcp_fin_timeout - INTEGER
-tcp_max_ka_probes - INTEGER
-tcp_hoe_retransmits - INTEGER
- Undocumented for now.
+ Time to hold socket in state FIN-WAIT-2, if it was closed
+ by our side. Peer can be broken and never close its side,
+ or even died unexpectedly. Default value is 60sec.
+ Usual value used in 2.2 was 180 seconds, you may restore
+ it, but remember that if your machine is even underloaded WEB server,
+ you risk to overflow memory with kilotons of dead sockets,
+ FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1,
+ because they eat maximum 1.5K of memory, but they tend
+ to live longer. Cf. tcp_max_orphans.
+
+tcp_max_tw_buckets - INTEGER
+ Maximal number of timewait sockets held by system simultaneously.
+ If this number is exceeded time-wait socket is immediately destroyed
+ and warning is printed. This limit exists only to prevent
+ simple DoS attacks, you _must_ not lower the limit artificially,
+ but rather increase it (probably, after increasing installed memory),
+ if network conditions require more than default value.
+
+tcp_tw_recycle - BOOLEAN
+ Enable fast recycling TIME-WAIT sockets. Default value is 1.
+ It should not be changed without advice/request of technical
+ experts.
+
+tcp_max_orphans - INTEGER
+ Maximal number of TCP sockets not attached to any user file handle,
+ held by system. If this number is exceeded orphaned connections are
+ reset immediately and warning is printed. This limit exists
+ only to prevent simple DoS attacks, you _must_ not rely on this
+ or lower the limit artificially, but rather increase it
+ (probably, after increasing installed memory),
+ if network conditions require more than default value,
+ and tune network services to linger and kill such states
+ more aggressivley. Let me to remind again: each orphan eats
+ up to ~64K of unswappable memory.
+
+tcp_abort_on_overflow - BOOLEAN
+ If listening service is too slow to accept new connections,
+ reset them. Default state is FALSE. It means that if overflow
+ occured due to a burst, connection will recover. Enable this
+ option _only_ if you are really sure that listening daemon
+ cannot be tuned to accept connections faster. Enabling this
+ option can harm clients of your server.
tcp_syncookies - BOOLEAN
Only valid when the kernel was compiled with CONFIG_SYNCOOKIES
@@ -89,15 +156,36 @@ tcp_syncookies - BOOLEAN
overflows. This is to prevent against the common 'syn flood attack'
Default: FALSE
+ Note, that syncookies is fallback facility.
+ It MUST NOT be used to help highly loaded servers to stand
+ against legal connection rate. If you see synflood warnings
+ in your logs, but investigation shows that they occur
+ because of overload with legal connections, you should tune
+ another parameters until this warning disappear.
+ See: tcp_max_syn_backlog, tcp_synack_retries, tcp_abort_on_overflow.
+
+ syncookies seriously violate TCP protocol, do not allow
+ to use TCP extensions, can result in serious degradation
+ of some services (f.e. SMTP relaying), visible not by you,
+ but your clients and relays, contacting you. While you see
+ synflood warnings in logs not being really flooded, your server
+ is seriously misconfigured.
+
tcp_stdurg - BOOLEAN
Use the Host requirements interpretation of the TCP urg pointer field.
Most hosts use the older BSD interpretation, so if you turn this on
Linux might not communicate correctly with them.
Default: FALSE
-tcp_syn_taildrop - BOOLEAN
tcp_max_syn_backlog - INTEGER
- Undocumented (work in progress)
+ Maximal number of remembered connection requests, which are
+ still did not receive an acknowldgement from connecting client.
+ Default value is 1024 for systems with more than 128Mb of memory,
+ and 128 for low memory machines. If server suffers of overload,
+ try to increase this number. Warning! If you make it greater
+ than 1024, it would be better to change TCP_SYNQ_HSIZE in
+ include/net/tcp.h to keep TCP_SYNQ_HSIZE*16<=tcp_max_syn_backlog
+ and to recompile kernel.
tcp_window_scaling - BOOLEAN
Enable window scaling as defined in RFC1323.
@@ -116,8 +204,15 @@ tcp_retrans_collapse - BOOLEAN
ip_local_port_range - 2 INTEGERS
Defines the local port range that is used by TCP and UDP to
choose the local port. The first number is the first, the
- second the last local port number. For high-usage systems
- change this to 32768-61000.
+ second the last local port number. Default value depends on
+ amount of memory available on the system:
+ > 128Mb 32768-61000
+ < 128Mb 1024-4999 or even less.
+ This number defines number of active connections, which this
+ system can issue simultaneously to systems not supporting
+ TCP extensions (timestamps). With tcp_tw_recycle enabled
+ (i.e. by default) range 1024-4999 is enough to issue up to
+ 2000 connections per second to systems supporting timestamps.
icmp_echo_ignore_all - BOOLEAN
icmp_echo_ignore_broadcasts - BOOLEAN
@@ -201,7 +296,7 @@ rp_filter - BOOLEAN
0 - No source validation.
- Default value is 0. Note that some distribution enable it
+ Default value is 0. Note that some distributions enable it
in startip scripts.
Alexey Kuznetsov.
@@ -210,4 +305,4 @@ kuznet@ms2.inr.ac.ru
Updated by:
Andi Kleen
ak@muc.de
-$Id: ip-sysctl.txt,v 1.11 2000/01/08 20:32:41 davem Exp $
+$Id: ip-sysctl.txt,v 1.13 2000/01/18 08:24:09 davem Exp $
diff --git a/Documentation/networking/smctr.txt b/Documentation/networking/smctr.txt
index f93c51470..57dbe7a65 100644
--- a/Documentation/networking/smctr.txt
+++ b/Documentation/networking/smctr.txt
@@ -2,9 +2,7 @@ Text File for the SMC TokenCard TokenRing Linux driver (smctr.c).
By Jay Schulist <jschlst@turbolinux.com>
The Linux SMC Token Ring driver works with the SMC TokenCard Elite (8115T)
-ISA adapters. Preliminary support for the SMC TokenCard Elite/A (8115T/A)
-MCA adapter has been started but is not complete. (Contact me for information
-if you have the proper setup to finish the MCA parts).
+ISA and SMC TokenCard Elite/A (8115T/A) MCA adapters.
Latest information on this driver can be obtained on the Linux-SNA WWW site.
Please point your browser to: http://www.linux-sna.org
diff --git a/Documentation/networking/wan-router.txt b/Documentation/networking/wan-router.txt
index 5fc1afffc..f82ceb548 100644
--- a/Documentation/networking/wan-router.txt
+++ b/Documentation/networking/wan-router.txt
@@ -1,19 +1,26 @@
------------------------------------------------------------------------------
WAN Router for Linux Operating System
------------------------------------------------------------------------------
+Version 2.1.1 - Nov 08, 1999
+Version 2.0.8 - Nov 02, 1999
+Version 2.0.7 - Aug 26, 1999
+Version 2.0.6 - Aug 17, 1999
+Version 2.0.5 - Aug 12, 1999
+Version 2.0.4 - Nov 26, 1998
+Version 2.0.3 - Aug 25, 1998
+Version 2.0.2 - Dec 09, 1997
Version 2.0.1 - Nov 28, 1997
Version 2.0.0 - Nov 06, 1997
Version 1.0.3 - June 3, 1997
Version 1.0.1 - January 30, 1997
-Author: Jaspreet Singh <jaspreet@sangoma.com>
- Gene Kozin <genek@compuserve.com>
-Copyright (c) 1995-1997 Sangoma Technologies Inc.
+Author: Nenad Corbic <ncorbic@sangoma.com>
+Copyright (c) 1995-1999 Sangoma Technologies Inc.
------------------------------------------------------------------------------
WARNING: This Version of WANPIPE supports only the S508 and S508/FT1 cards.
IF YOU OWN A S502E OR A S508 CARD THEN PLEASE CONTACT SANGOMA TECHNOLOGIES FOR
-AN UPGRADE.
+AN UPGRADE. ONLY THE BiSYNC STREAMING CODE IS SUPPORTED ON S502E/S503 cards.
INTRODUCTION
@@ -129,11 +136,55 @@ product.
REVISION HISTORY
+2.1.1 Nov 09, 1999 - New code for S514PCI card
+ - Completely redesigned drivers
+ fully tested and optimized.
+
+2.0.8 Nov 02, 1999 - Fixed up the X25API code.
+ - Clear call bug fixed.i
+ - Eanbled driver for multi-card
+ operation.
+
+2.0.7 Aug 26, 1999 - Merged X25API code into WANPIPE.
+ - Fixed a memeory leak for X25API
+ - Updated the X25API code for 2.2.X kernels.
+ - Improved NEM handling.
+
+2.0.6 Aug 17, 1999 - Kernel patch works for both 2.2.10 and 2.2.11 kernels
+ - Fixed up 2.0.5 installation bugs
+ - No functional difference between 2.0.6 and 2.0.5
+
+2.0.5 Aug 12, 1999 - NEW PPP, interrupt drive code
+ - NEW X25 Xpipmon debugger
+ - Comments added to setup scripts
+ - Numerous bug fixes
+
+2.0.4 Nov 26, 1998 - NEW Cisco Dual Port support.
+ - NEW support for BiSync Streaming API.
+ - NEW support for HDLC (LAPB) API.
+ - WANPIPE provides an API for application
+ development using the BSD socket interface.
+
+2.0.3 Aug 25, 1998 - NEW support for Cisco HDLC, with cpipemon
+ utility for monitoring
+ - CIR support for Frame-relay
+ - Support for PAP and CHAP for ppp has been
+ implemented
+ - Dynamic IP assignment for PPP
+ - Multiple channel IPX support for Frame-relay
+ and X25
+ - Inverse Arp support for Frame-relay
+ - FT1 Configuration utility for linux
+ - Man Pages for router.conf, router, sdladump,
+ cfgft1, fpipemon, ppipemon and cpipemon
+
+2.0.2 Dev 09, 1997 - Implemented PAP and CHAP for ppp.
+
2.0.1 Nov 28, 1997 - Protection of "enable_irq()" while
"disable_irq()" has been enabled from any other
routine (for Frame Relay, PPP and X25).
- - Added additional Stats for Fpipemon and Ppipemon - Improved Load Sharing for multiple boards.
-
+ - Added additional Stats for Fpipemon and Ppipemon
+ - Improved Load Sharing for multiple boards.
2.0.0 Nov 07, 1997 - Implemented protection of RACE conditions by
critical flags for FRAME RELAY and PPP.
@@ -173,7 +224,7 @@ REVISION HISTORY
1.0.1 January 30, 1997
- Implemented user-readable status and statistics
- via /proc file system
+ via /proc filesystem
1.0.0 December 31, 1996
diff --git a/Documentation/networking/wanpipe.txt b/Documentation/networking/wanpipe.txt
index 0be0c5dc1..7cb28178e 100644
--- a/Documentation/networking/wanpipe.txt
+++ b/Documentation/networking/wanpipe.txt
@@ -1,36 +1,23 @@
------------------------------------------------------------------------------
-WANPIPE(tm) Multiprotocol WAN Driver for Linux WAN Router
+Linux WAN Router Utilities Package
------------------------------------------------------------------------------
-Release 4.1
-November 17, 1997
-Author: Jaspreet Singh <jaspreet@sangoma.com>
-Copyright (c) 1995-1997 Sangoma Technologies Inc.
+Version 2.1.1
+Nov 08, 1999
+Author: Nenad Corbic <ncorbic@sangoma.com>
+Copyright (c) 1995-1999 Sangoma Technologies Inc.
------------------------------------------------------------------------------
INTRODUCTION
-WANPIPE(tm) is a family of intelligent multiprotocol WAN communication adapters
-for personal computers (ISA bus) designed to provide PC connectivity to
-various communication links, such as leased lines and public data networks, at
-speeds up to T1/E1 using a variety of synchronous communications protocols,
-including frame relay, PPP, X.25, SDLC, etc.
+This is a set of utilities and shell scripts you need in order to be able to
+use Linux kernel-level WAN Router. Please read WAN Router User's manual
+(router.txt) and WANPIPE driver documentation found in /usr/lib/router/doc
+directory for installation and configuration instructions.
-WANPIPE driver together with Linux WAN Router module allows you to build a
-relatively inexpensive, yet high-performance multiprotocol WAN router. For
-more information about the Linux WAN Router please read the file
-Documentation/networking/wan-router.txt. You must also obtain the WAN Tools
-package to be able to use the Linux WAN Router and WANPIPE driver. The package
-is available via the Internet from Sangoma Technologies' anonymous FTP server:
+You can find the latest version of this software in /pub/linux directory on
+Sangoma Technologies' anonymous FTP server (ftp.sangoma.com).
- ftp.sangoma.com/pub/linux/wantools-X.Y.Z.tgz
- or
- ftp.sangoma.com/pub/linux/wanpipe-X.Y.Z.tgz
-
-The names of the packages differ only due to naming convention. The
-functionality of wantools and wanpipe packages are the same. The latest
-version of the WAN Drivers is wanpipe-2.0.0.
-
-For technical questions and/or comments please e-mail to jaspreet@sangoma.com.
+For technical questions and/or comments please e-mail to ncorbic@sangoma.com.
For general inquiries please contact Sangoma Technologies Inc. by
Hotline: 1-800-388-2475 (USA and Canada, toll free)
@@ -57,117 +44,214 @@ Ave, Cambridge, MA 02139, USA.
-NEW IN THIS RELEASE
-
- o This Version of WANPIPE supports only the S508 and S508/FT1 cards. IF YOU
- OWN A S502E OR A S508 CARD THEN PLEASE CONTACT SANGOMA TECHNOLOGIES FOR AN
- UPGRADE.
- o Protection of "enable_irq()" while "disable_irq()" has been enabled from
- any other routine (for Frame Relay, PPP and X25).
- o Added additional Stats for Fpipemon and Ppipemon.
- o Improved Load Sharing for multiple boards
-
-
-FILE LIST
-
-drivers/net:
- README.wanpipe This file
- sdladrv.c SDLA support module source code
- sdla_fr.c SDLA Frame Relay source code
- sdla_ppp.c SDLA PPP source code
- sdla_x25.c SDLA X.25 source code
- sdlamain.c SDLA support source code
-
-include/linux:
- sdla_x25.h SDLA X.25 firmware API definitions
- sdla_fr.h SDLA frame relay firmware API definitions
- sdla_ppp.h SDLA PPP firmware API definitions
- wanpipe.h WANPIPE API definitions
- sdladrv.h SDLA support module API definitions
- sdlasfm.h SDLA firmware module definitions
- router.h
-
-
-REVISION HISTORY
-
-4.1 November 28, 1997
- o Protection of "enable_irq()" while "disable_irq()" has been enabled
- from any other routine (for Frame Relay, PPP and X25).
- o Added additional Stats for Fpipemon and Ppipemon
- o Improved Load Sharing for multiple boards
-
-
-4.0 November 06, 1997
- o Implemented better protection of RACE conditions by critical flags for
- FRAME RELAY, PPP and X25.
- o DLCI List interrupt mode implemented for DLCI specific CIR.
- o IPX support for FRAME RELAY, PPP and X25.
- o IPX Server Support (MARS) for FRAME RELAY, PPP and X25.
- o More driver specific stats included.
- o MULTICAST for FRAME RELAY and PPP.
-
-3.1.0 January 30, 1997
-
- o Implemented IOCTL for executing adapter commands.
- o Fixed a bug in frame relay code causing driver configured as a FR
- switch to be stuck in WAN_DISCONNECTED mode.
-
-3.0.0 December 31, 1996
-
- o Uses Linux WAN Router interface
- o Added support for X.25 routing
- o Miscellaneous bug fixes and performance improvements
-
-2.4.1 December 18, 1996
+ACKNOWLEDGEMENTS
- o Added support for LMI and Q.933 frame relay link management
+This product is based on the WANPIPE(tm) Multiprotocol WAN Router developed
+by Sangoma Technologies Inc. for Linux 2.2.x. Success of the WANPIPE
+together with the next major release of Linux kernel in summer 1996 commanded
+adequate changes to the WANPIPE code to take full advantage of new Linux
+features.
-2.3.0 October 17, 1996
+Instead of continuing developing proprietary interface tied to Sangoma WAN
+cards, we decided to separate all hardware-independent code into a separate
+module and defined two levels of interfaces - one for user-level applications
+and another for kernel-level WAN drivers. WANPIPE is now implemented as a
+WAN driver compliant with the WAN Link Driver interface. Also a general
+purpose WAN configuration utility and a set of shell scripts was developed to
+support WAN router at the user level.
- o All shell scripts use meta-configuration file
- o Miscellaneous bug fixes
+Many useful ideas concerning hardware-independent interface implementation
+were given by Mike McLagan <mike.mclagan@linux.org> and his implementation
+of the Frame Relay router and drivers for Sangoma cards (dlci/sdla).
-2.2.0 July 16, 1996
+With the new implementation of the APIs being incorporated into the WANPIPE,
+a special thank goes to Alan Cox in providing insight into BSD sockets.
- o Compatible with Linux 2.0
- o Added uninstall script
- o User's Manual is available in HTML format
+Special thanks to all the WANPIPE users who performed field-testing, reported
+bugs and made valuable comments and suggestions that help us to improve this
+product.
-2.1.0 June 20, 1996
- o Added support for synchronous PPP
- o Added support for S503 adapter
- o Added API for executing adapter commands
- o Fixed a re-entrancy problem in frame relay driver
- o Changed interface between SDLA driver and protocol support modules
- o Updated frame relay firmware
-2.0.0 May 1, 1996
-
- o Added interactive installation and configuration scripts
- o Added System V-style start-up script
- o Added dynamic memory window address selection in SDLA driver
- o Miscellaneous bug fixes in SDLA driver
- o Updated S508 frame relay firmware
- o Changed SFM file format
+NEW IN THIS RELEASE
-1.0.0 February 12, 1996
+o Renamed startup script to wanrouter
+o Option to turn off/on each router
+ separately
+o New source directory /usr/lib/wanrouter
+o New PPP driver
+o X25 is not supported in this release
+
+
+PRODUCT COMPONENTS AND RELATED FILES
+
+/etc:
+ wanpipe1.conf default router configuration file
+ wanrouter.rc meta-configuration file (used by the Setup script)
+
+/lib/modules/X.Y.Z/misc:
+ wanrouter.o router kernel loadable module
+
+/lib/modules/X.Y.Z/net:
+ sdladrv.o Sangoma SDLA support module
+ wanpipe.o Sangoma WANPIPE(tm) driver module
+
+/proc/net/wanrouter
+ Config reads current router configuration
+ Status reads current router status
+ {name} reads WAN driver statistics
+
+/usr/sbin:
+ wanrouter router start-up script
+ wanconfig router configuration utility
+ sdladump WANPIPE adapter memory dump utility
+ fpipemon Monitor for Frame Relay
+ cpipemon Monitor for Cisco HDLC
+
+/usr/lib/wanrouter:
+ README this file
+ COPYING GNU General Public License
+ Setup installation script
+ Configure configuration script
+ Filelist distribution definition file
+
+/usr/lib/wanrouter/doc:
+ WANPIPE_USER_MANUAL.txt WAN Router User's Manual
+ WANPIPE_CONFIG.txt WAN Configuration Manual
+
+/usr/lib/wanrouter/interfaces:
+ * interface configuration files (TCP/IP configuration)
+
+/usr/lib/wanrouter/patches:
+ wanrouter-22.gz patch for Linux kernel 2.2.10 and 2.2.11
+ (compatible for all 2.2.X kernels)
+ wanrouter-20.gz patch for Linux kernel 2.0.36
+
+ Fix_2.2.11.gz patch to fix the 2.2.11 kernel so other patches
+ can be applied properly.
+
+/usr/lib/wanrouter/samples:
+ interface sample interface configuration file
+ wanpipe1.cpri CHDLC primary port
+ wanpipe2.csec CHDLC secondary port
+ wanpipe1.fr Frame Relay protocol
+ wanpipe1.ppp PPP protocol )
+ wanrouter.rc sample meta-configuration file
+
+/usr/lib/wanrouter/src:
+ * wan-tools source code
+
+/usr/include/linux:
+ wanrouter.h router API definitions
+ wanpipe.h WANPIPE API definitions
+ sdladrv.h SDLA support module API definitions
+ sdlasfm.h SDLA firmware module definitions
- o Final release
- o Added support for Linux 1.3
- o Updated S508 frame relay firmware
+/usr/src/linux/net/router:
+ * router source code
-0.9.0 December 21, 1995
+/var/log:
+ wanrouter router start-up log (created by the Setup script)
- o Added SNAP encapsulation for routed frames
- o Added support for the frame relay switch emulation mode
- o Added support for S508 adapter
- o Added capability to autodetect adapter type
- o Miscellaneous bug fixes in SDLA and frame relay drivers
+/var/lock:
+ wanrouter router lock file (created by the Setup script)
-0.1.0 October 12, 1995
+/usr/lib/wanrouter/wanpipe:
+ fr514.sfm Frame relay firmware for Sangoma S508/S514 card
+ cdual514.sfm Dual Port Cisco HDLC firmware for Sangoma S508/S514 card
+ ppp514.sfm PPP Firmware for Sangoma S508 and S514 cards
- o Initial version
->>>>>>> END OF README <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+REVISION HISTORY
+1.0.0 December 31, 1996 Initial version
+
+1.0.1 January 30, 1997 Status and statistics can be read via /proc
+ filesystem entries.
+
+1.0.2 April 30, 1997 Added UDP management via monitors.
+
+1.0.3 June 3, 1997 UDP management for multiple boards using Frame
+ Relay and PPP
+ Enabled continuous transmission of Configure
+ Request Packet for PPP (for 508 only)
+ Connection Timeout for PPP changed from 900 to 0
+ Flow Control Problem fixed for Frame Relay
+
+1.0.4 July 10, 1997 S508/FT1 monitoring capability in fpipemon and
+ ppipemon utilities.
+ Configurable TTL for UDP packets.
+ Multicast and Broadcast IP source addresses are
+ silently discarded.
+
+1.0.5 July 28, 1997 Configurable T391,T392,N391,N392,N393 for Frame
+ Relay in router.conf.
+ Configurable Memory Address through router.conf
+ for Frame Relay, PPP and X.25. (commenting this
+ out enables auto-detection).
+ Fixed freeing up received buffers using kfree()
+ for Frame Relay and X.25.
+ Protect sdla_peek() by calling save_flags(),
+ cli() and restore_flags().
+ Changed number of Trace elements from 32 to 20
+ Added DLCI specific data monitoring in FPIPEMON.
+2.0.0 Nov 07, 1997 Implemented protection of RACE conditions by
+ critical flags for FRAME RELAY and PPP.
+ DLCI List interrupt mode implemented.
+ IPX support in FRAME RELAY and PPP.
+ IPX Server Support (MARS)
+ More driver specific stats included in FPIPEMON
+ and PIPEMON.
+
+2.0.1 Nov 28, 1997 Bug Fixes for version 2.0.0.
+ Protection of "enable_irq()" while
+ "disable_irq()" has been enabled from any other
+ routine (for Frame Relay, PPP and X25).
+ Added additional Stats for Fpipemon and Ppipemon
+ Improved Load Sharing for multiple boards
+
+2.0.2 Dec 09, 1997 Support for PAP and CHAP for ppp has been
+ implemented.
+
+2.0.3 Aug 15, 1998 New release supporting Cisco HDLC, CIR for Frame
+ relay, Dynamic IP assignment for PPP and Inverse
+ Arp support for Frame-relay. Man Pages are
+ included for better support and a new utility
+ for configuring FT1 cards.
+
+2.0.4 Dec 09, 1998 Dual Port support for Cisco HDLC.
+ Support for HDLC (LAPB) API.
+ Supports BiSync Streaming code for S502E
+ and S503 cards.
+ Support for Streaming HDLC API.
+ Provides a BSD socket interface for
+ creating applications using BiSync
+ streaming.
+
+2.0.5 Aug 04, 1999 CHDLC initializatin bug fix.
+ PPP interrupt driven driver:
+ Fix to the PPP line hangup problem.
+ New PPP firmware
+ Added comments to the startup SYSTEM ERROR messages
+ Xpipemon debugging application for the X25 protocol
+ New USER_MANUAL.txt
+ Fixed the odd boundary 4byte writes to the board.
+ BiSync Streaming code has been taken out.
+ Available as a patch.
+ Streaming HDLC API has been taken out.
+ Available as a patch.
+
+2.0.6 Aug 17, 1999 Increased debugging in statup scripts
+ Fixed insallation bugs from 2.0.5
+ Kernel patch works for both 2.2.10 and 2.2.11 kernels.
+ There is no functional difference between the two packages
+
+2.0.7 Aug 26, 1999 o Merged X25API code into WANPIPE.
+ o Fixed a memeory leak for X25API
+ o Updated the X25API code for 2.2.X kernels.
+ o Improved NEM handling.
+
+2.1.0 Oct 25, 1999 o New code for S514 PCI Card
+ o New CHDLC and Frame Relay drivers
+ o PPP and X25 are not supported in this release
+>>>>>> END OF README <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
diff --git a/Documentation/rtc.txt b/Documentation/rtc.txt
index 7718228ba..a7b22b4c2 100644
--- a/Documentation/rtc.txt
+++ b/Documentation/rtc.txt
@@ -22,8 +22,8 @@ character device) in the form of an unsigned long. The low byte contains
the type of interrupt (update-done, alarm-rang, or periodic) that was
raised, and the remaining bytes contain the number of interrupts since
the last read. Status information is reported through the pseudo-file
-/proc/rtc if the /proc filesystem was enabled. The driver has built in
-locking so that only one process is allowed to have the /dev/rtc
+/proc/driver/rtc if the /proc filesystem was enabled. The driver has
+built in locking so that only one process is allowed to have the /dev/rtc
interface open at a time.
A user process can monitor these interrupts by doing a read(2) or a
diff --git a/Documentation/usb/CREDITS b/Documentation/usb/CREDITS
index 738b55efc..b1230f70a 100644
--- a/Documentation/usb/CREDITS
+++ b/Documentation/usb/CREDITS
@@ -12,6 +12,7 @@ difficult to maintain, add yourself with a patch if desired.
ham <ham@unsuave.com>
Bradley M Keryan <keryan@andrew.cmu.edu>
Greg Kroah-Hartman <greg@kroah.com>
+ Pavel Machek <pavel@suse.cz>
Paul Mackerras <paulus@cs.anu.edu.au>
David E. Nelson <dnelson@jump.net>
Vojtech Pavlik <vojtech@suse.cz>
diff --git a/Documentation/usb/ibmcam.txt b/Documentation/usb/ibmcam.txt
new file mode 100644
index 000000000..4d7ab56eb
--- /dev/null
+++ b/Documentation/usb/ibmcam.txt
@@ -0,0 +1,166 @@
+README for Linux device driver for the IBM "C-It" USB video camera
+
+INTRODUCTION:
+
+This driver does not use all features known to exist in
+the IBM camera. However most of needed features work well.
+
+This driver was developed using logs of observed USB traffic
+which was produced by standard Windows driver (c-it98.sys).
+I did not have any input from Xirlink. Some people asked about
+data sheets, but nothing came out of that. I didn't try.
+
+Video formats: 128x96, 176x144, 352x288
+Frame rate: 3 - 30 frames per second (FPS)
+External interface: USB
+Internal interface: Video For Linux (V4L)
+Supported controls:
+- by V4L: Contrast, Brightness, Color, Hue
+- by driver options: frame rate, lighting conditions, video format,
+ default picture settings, sharpness.
+
+SUPPORTED CAMERAS:
+
+IBM "C-It" camera, also known as "Xirlink PC Camera"
+The device uses proprietary ASIC (and compression method);
+it is manufactured by Xirlink. See http://www.xirlink.com
+
+WHAT YOU NEED:
+
+- An IBM C-it camera
+
+- A Linux box with USB support (2.3/2.4 or 2.2 w/backport)
+
+- A Video4Linux compatible frame grabber program such as xawtv.
+
+HOW TO COMPILE THE DRIVER:
+
+You need to compile the driver only if you are a developer
+or if you want to make changes to the code. Most distributions
+precompile all modules, so you can go directly to the next
+section "HOW TO USE THE DRIVER".
+
+The driver consists of two files in usb/ directory:
+ibmcam.c and ibmcam.h These files are included into the
+Linux kernel build process if you configure the kernel
+for CONFIG_USB_IBMCAM. Run "make xconfig" and in USB section
+you will find the IBM camera driver. Select it, save the
+configuration and recompile.
+
+HOW TO USE THE DRIVER:
+
+I recommend to compile driver as a module. This gives you an
+easier access to its configuration. The camera has many more
+settings than V4L can operate, so some settings are done using
+module options.
+
+Typically module is installed with command 'modprobe', like this:
+
+# modprobe ibmcam framerate=1
+
+Alternatively you can use 'insmod' in similar fashion:
+
+# insmod /lib/modules/2.x.y/usb/ibmcam.o framerate=1
+
+Module can be inserted with camera connected or disconnected.
+
+The driver can have options, though some defaults are provided.
+
+Driver options:
+
+Name Type Range [default] Example
+-------------- -------------- -------------- ------------------
+debug Integer 0-9 [0] debug=1
+flags Integer 0-0xFF [0] flags=0x0d
+framerate Integer 0-6 [2] framerate=1
+init_brightness Integer 0-255 [128] init_brightness=100
+init_contrast Integer 0-255 [192] init_contrast=200
+init_color Integer 0-255 [128] init_color=130
+init_hue Integer 0-255 [128] init_hue=115
+lighting Integer 0-2 [1] lighting=2
+sharpness Integer 0-6 [4] sharpness=3
+videosize Integer 0-2 [2] videosize=1
+
+debug You don't need this option unless you are a developer.
+ If you are a developer then you will see in the code
+ what values do what. 0=off.
+
+flags This is a bit mask, and you can combine any number of
+ bits to produce what you want. Usually you don't want
+ any of extra features this option provides:
+
+ FLAGS_RETRY_VIDIOCSYNC 1 This bit allows to retry failed
+ VIDIOCSYNC ioctls without failing.
+ Will work with xawtv, will not
+ with xrealproducer. Default is
+ not set.
+ FLAGS_MONOCHROME 2 Activates monochrome (b/w) mode.
+ FLAGS_DISPLAY_HINTS 4 Shows colored pixels which have
+ magic meaning to developers.
+ FLAGS_OVERLAY_STATS 8 Shows tiny numbers on screen,
+ useful only for debugging.
+ FLAGS_FORCE_TESTPATTERN 16 Shows blue screen with numbers.
+
+framerate This setting controls frame rate of the camera. This is
+ an approximate setting (in terms of "worst" ... "best")
+ because camera changes frame rate depending on amount
+ of light available. Setting 0 is slowest, 6 is fastest.
+ Beware - fast settings are very demanding and may not
+ work well with all video sizes. Be conservative.
+
+init_brightness These settings specify _initial_ values which will be
+init_contrast used to set up the camera. If your V4L application has
+init_color its own controls to adjust the picture then these
+init_hue controls will be used too. These options allow you to
+ preconfigure the camera when it gets connected, before
+ any V4L application connects to it. Good for webcams.
+
+lighting This option selects one of three hardware-defined
+ photosensitivity settings of the camera. 0=bright light,
+ 1=Medium (default), 2=Low light. This setting affects
+ frame rate: the dimmer the lighting the lower the frame
+ rate (because longer exposition time is needed).
+
+sharpness This option controls smoothing (noise reduction)
+ made by camera. Setting 0 is most smooth, setting 6
+ is most sharp. Be aware that CMOS sensor used in the
+ camera is pretty noisy, so if you choose 6 you will
+ be greeted with "snowy" image. Default is 4.
+
+videosize This setting chooses one if three image sizes that are
+ supported by this driver. Camera supports more, but
+ it's difficult to reverse-engineer all formats.
+ Following video sizes are supported:
+
+ videosize=0 128x96
+ videosize=1 176x144
+ videosize=2 352x288
+
+ The last one (352x288) is the native size of the sensor
+ array, so it's the best resolution camera can yield.
+ Choose the image size you need. The smaller image can
+ support faster frame rate. Default is 352x288.
+
+WHAT NEEDS TO BE DONE:
+
+- The box freezes if working camera (with xawtv) is unplugged (OHCI).
+ Workaround: don't do that :) End the V4L application first.
+- Some USB frames are lost on high frame rates, though they shouldn't
+- ViCE compression (Xirlink proprietary) may improve frame rate
+- On occasion camera does not start properly; xawtv reports errors.
+ Workaround: reload the driver module. Reason: [1].
+- On occasion camera produces negative image (funny colors.)
+ Workaround: reload the driver module. Reason: [1].
+- The button on the camera is not used. I don't know how to get to it.
+
+[1]
+- Camera reports its status back to the driver; however I don't know
+ what returned data means. If camera fails at some initialization
+ stage then something should be done, and I don't do that because
+ I don't even know that some command failed.
+
+CREDITS:
+
+The code is based in no small part on the CPiA driver by Johannes Erdfelt,
+Randy Dunlap, and others. Big thanks to them for their pioneering work on that
+and the USB stack.
diff --git a/Documentation/usb/ohci-hcd.txt b/Documentation/usb/ohci.txt
index 37a637251..39a5ce482 100644
--- a/Documentation/usb/ohci-hcd.txt
+++ b/Documentation/usb/ohci.txt
@@ -21,7 +21,7 @@ The layer (functions) on top of it, is for interfacing to the alternate-usb devi
* v0.1.0 1999/04/27 initial release
to remove the module try:
-rmmod usb-ohci-hcd
+rmmod usb-ohci
Features:
- virtual root hub, all basic hub descriptors and commands (state: complete)
diff --git a/Documentation/usb/ov511.txt b/Documentation/usb/ov511.txt
index 3a73afc0d..fe84f11df 100644
--- a/Documentation/usb/ov511.txt
+++ b/Documentation/usb/ov511.txt
@@ -11,10 +11,6 @@ This is a preliminary version of my OV511 Linux device driver. Currently, it can
grab a frame in color (YUV420) at 640x480 or 320x240 using either vidcat or
xawtv. Other utilities may work but have not yet been tested.
-NOTE: 320x240 does not work reliably for me, and causes complete system crashes.
- I recommend not using it until a later version, and if you do, run "sync"
- first.
-
SUPPORTED CAMERAS:
________________________________________________________
Manufacturer | Model | Custom ID | Status
@@ -24,6 +20,7 @@ D-Link | DSB-C300 | 3 | Working
Creative Labs | WebCam 3 | 21 | Working
Lifeview | RoboCam | 100 | Untested
AverMedia | InterCam Elite | 102 | Working
+MediaForte | MV300 | 112 | Untested
--------------------------------------------------------
Any camera using the OV511 and the OV7610 CCD should work with this driver. The
@@ -39,7 +36,8 @@ WHAT YOU NEED:
http://www.ovt.com/omniusbp.html
- A Video4Linux compatible frame grabber program (I recommend vidcat and xawtv)
- (see: http://www.exploits.org/v4l/ )
+ vidcat is part of the w3cam package: http://www.hdk-berlin.de/~rasca/w3cam/
+ xawtv is available at: http://www.in-berlin.de/User/kraxel/xawtv.html
HOW TO USE IT:
@@ -83,7 +81,7 @@ directory:
Now you should be able to run xawtv. Right click for the options dialog.
WORKING FEATURES:
- o Color streaming/capture at 640x480 (reliably) and 320x240 (unreliably)
+ o Color streaming/capture at 640x480 and 320x240
o YUV420 color
o Setting/getting of saturation, contrast and brightness (no color yet)
diff --git a/Documentation/usb/scanner-hp-sane.txt b/Documentation/usb/scanner-hp-sane.txt
index 220bbb290..a1cbcd1b4 100644
--- a/Documentation/usb/scanner-hp-sane.txt
+++ b/Documentation/usb/scanner-hp-sane.txt
@@ -1,8 +1,10 @@
-Oct. 19, 1999
+Copyright (C) 1999, 2000 David E. Nelson
+
+Jan. 22, 2000
CHANGES
-- Ammended for Linux-2.3.22+
+- Amended for Linux-2.3.40
INTRODUCTION
@@ -11,23 +13,26 @@ This document will hopefully provide enough info on how to get SANE
working with a Hewlett Packard USB capable scanner using the USB
interface. The majority of HP Scanners support the Scanner Control
Language (SCL) which is both published by HP and supported by SANE.
-The only HP Scanner that I'm aware of that does not support SCL is the
-4200C. All other HP scanners with USB interfaces should work (4100C,
-5200C, 6200C, and 6300C). Of course as HP releases new scanners this
-information may change.
+The only HP Scanners that I'm aware of that do not support SCL are the
+4200C and the 3300C. All other HP scanners with USB interfaces should
+work (4100C, 5200C, 6200C, and 6300C). Of course as HP releases new
+scanners this information may change.
REQUIREMENTS
In order to get this running you'll need USB support in your kernel in
-addition to USB Scanner support. Please refer to README.scanner
-for issues pertaining to Linux USB and USB Scanner support.
+addition to USB Scanner support. Please refer to scanner.txt for
+issues pertaining to Linux USB and USB Scanner support.
An installed version of SANE which is available from
http://www.mostang.com/sane/. Testing has been performed using
version SANE-1.0.1. For instructions on building and installing SANE,
refer to the various README files within the SANE distribution.
+The latest SANE HP backend available from http://www.kirchgessner.net.
+At the time of this writing, version 0.83 was available.
+
OK, I'VE INSTALLED SANE. SO WHAT DO I DO NOW?
diff --git a/Documentation/usb/scanner.txt b/Documentation/usb/scanner.txt
index 4b5de2be8..193035085 100644
--- a/Documentation/usb/scanner.txt
+++ b/Documentation/usb/scanner.txt
@@ -1,8 +1,10 @@
-Oct 19, 1999
+Copyright (C) 1999, 2000 David E. Nelson
+
+Jan. 22, 2000
CHANGES
-- Ammended for linux-2.3.22+
+- Amended for linux-2.3.40
- Appended hp_scan.c to end of this README
- Removed most references to HP
@@ -12,49 +14,63 @@ OVERVIEW
This README will address issues regarding how to configure the kernel
to access a USB scanner. Although the driver was originally conceived
for USB HP scanners, it's general enough so that it can be used with
-other scanners. Also, one can now pass the USB Vendor and
-Product ID's using module parameters for unknown scanners. Refer to
-the document README.scanner_hp_sane for guidance on how to configure
-SANE to use a USB HP Scanner.
+other scanners. Also, one can now pass the USB Vendor and Product
+ID's using module parameters for unknown scanners. Refer to the
+document scanner_hp_sane.txt for guidance on how to configure SANE to
+use a USB HP Scanner.
ADDITIONAL INFORMATION
http://www.linux-usb.org/
-http://www.dynamine.net/linux-usb/HOWTO/
REQUIREMENTS
A host with a USB port. Ideally, either a UHCI (Intel) or OHCI
(Compaq and others) hardware port should work. However, I've only
-been able to really use an OHCI controller. I did have access to a
-system with a UHCI controller but some very limited testing did not
-produce satisfactory results. Luke Ordelmans
-<postbus@ordelmans.demon.nl> has reported success using the UHCI host
-controller with kernel 2.3.18 and a ChainTech motherboard. Here
-lately I've been having better success with the ohci-hcd driver. But
-since Linux USB support is still in a state of constant development
-that may change at a later date. I am confident that eventually all
-the host contollers will perform without incident.
+been able to really use an OHCI controller. At the time of this
+writing, both uhci and ohci work with scanner.c *except* for the HP
+4100C which only works with ohci. This problem is being investigated.
-A Linux kernel with USB support (preferably linux-2.3.18+)
+A Linux development kernel (2.3.x) with USB support enabled or a
+backported version to linux-2.2.x. See http://www.linux-usb.org for
+more information on accomplishing this.
-A Linux kernel with USB Scanner support.
+A Linux kernel with USB Scanner support enabled.
+'lspci' which is only needed to determine the type of USB hardware
+available in your machine.
CONFIGURATION
-Using `make menuconfig` or your prefered method for configuring the
-kernel, select 'Support for USB', 'OHCI/OHCI-HCD/UHCI' depending on
-your hardware, 'USB hub support', and 'USB Scanner support'. Compile
-and install the modules (you may need to execute `depmod -a` to update
-the module dependencies). Testing was performed only as modules,
-YMMV.
+Using `lspci -v`, determine the type of USB hardware available.
+
+ If you see something like:
+
+ USB Controller: ......
+ Flags: .....
+ I/O ports at ....
+
+ Then you have a UHCI based controller.
+
+ If you see something like:
+
+ USB Controller: .....
+ Flags: ....
+ Memory at .....
+
+ Then you have a OHCI based controller.
+
+Using `make menuconfig` or your preferred method for configuring the
+kernel, select 'Support for USB', 'OHCI/UHCI' depending on your
+hardware (determined from the steps above), 'USB Scanner support', and
+'Preliminary USB device filesystem'. Compile and install the modules
+(you may need to execute `depmod -a` to update the module
+dependencies). Testing was performed only as modules, YMMV.
Add a device for the USB scanner:
- linux-2.3.22 and above: `mknod /dev/usbscanner c 180 48`
- linux-2.3.21 and below: `mknod /dev/usbscanner c 16 1`
+ `mknod /dev/usbscanner c 180 48`
Set appropriate permissions for /dev/usbscanner (don't forget about
group and world permissions). Both read and write permissions are
@@ -66,36 +82,71 @@ Load the appropriate modules (if compiled as modules):
modprobe usb-ohci
modprobe scanner
- OHCI-HCD:
- modprobe usb-ohci-hcd
- modprobe hub
- modprobe scanner
-
UHCI:
modprobe usb-uhci
- modprobe hub (don't know if this is required or not)
modprobe scanner
That's it. SANE should now be able to access the device.
There is a small test program (hp_scan.c -- appended below) that can
be used to test the scanner device if it's an HP scanner that supports
-SCL. Its purpose is to test the driver without having to
-retrieve/configure SANE. Hp_scan.c will scan the entire bed and put
-the output into a file called 'out.dat' in the current directory. The
-data in the file is raw data so it's not very useful for imaging.
+SCL (Scanner Control Language). Known HP scanner that support SCL are
+the 4100, 5200, 6200, the 6300 -- note that the 4200 is *not*
+supported since it does not understand SCL; it's also strongly
+suspected that the 3300 is not SCL compliant. Hp_scan.c's purpose is
+to test the driver without having to retrieve/configure SANE.
+Hp_scan.c will scan the entire bed and put the output into a file
+called 'out.dat' in the current directory. The data in the file is
+raw data so it's not very useful for imaging.
+
+
+SUPPORTED SCANNERS
+
+NOTE: Just because a product is listed here does not mean that
+applications exist that support the product. It's in the hopes that
+this will allow developers a means to produce applications that will
+support the listed USB products.
+
+At the time of this writing, the following scanners were supported by
+scanner.c:
+
+ Hewlett Packard
+
+ 3300, 4100, 4200, 5200, 6200, 6300, PhotoSmart S20
+
+ AGFA
+
+ SnapScan 1212U
+
+ Umax
+
+ Astra 2000U
+
+ Seiko/Epson
+
+ Perfection 636, Perfection 1200U
+
+ Mustek
+
+ 1200 CU
+
+ User Specified. See MODULE PARAMETERS for details.
MODULE PARAMETERS
-If you have a device that wish to experiment with or try using this
-driver with, but the Vendor and Product ID's are not coded in, don't
-despair. If the driver was compiled as a module, you can pass options
-to the driver. Simply add 'options scanner vendor=0x####
+If you have a device that you wish to experiment with or try using
+this driver with, but the Vendor and Product ID's are not coded in,
+don't despair. If the driver was compiled as a module, you can pass
+options to the driver. Simply add 'options scanner vendor=0x####
product=0x****' to the conf.modules/modules.conf file replacing the
#'s and the *'s with the correct ID's. The ID's can be retrieved from
the messages file or using `cat /proc/bus/usb/devices` if USB /proc
-support was selected during kernel configuration.
+support was selected during kernel configuration. In later kernels
+(2.3.38+), a new filesystem was introduced, usbdevfs. To mount the
+filesystem, issue the command `mount -t usbdevfs /proc/bus/usb
+/proc/bus/usb`. You can then issue ` cat /proc/bus/usb/devices` to
+extract USB device information.
BUGS
diff --git a/Documentation/usb/usb-serial.txt b/Documentation/usb/usb-serial.txt
index e046ae2e5..e9e94510b 100644
--- a/Documentation/usb/usb-serial.txt
+++ b/Documentation/usb/usb-serial.txt
@@ -59,14 +59,12 @@ Current status:
possible. The driver cleans up properly when the device is removed, or
the connection is canceled on the Visor.
- I write _should_ because communication does not seem to work properly at
- this time. I am in contact with the developers at HandSpring and am
- working at getting this to work properly.
-
- There is a webpage for this portion of the driver at
- http://milosch.net/visor/ and a project set up with mailing lists for
- it at :
- http://sourceforge.net/project/?group_id=1404
+ When the device is connected, try talking to it on the second port
+ (this is usually /dev/ttyUSB1 if you do not have any other usb-serial
+ devices in the system.)
+
+ There is a webpage and mailing lists for this portion of the driver at:
+ http://usbvisor.sourceforge.net/
Belkin single port serial converter
diff --git a/Documentation/vm/balance b/Documentation/vm/balance
new file mode 100644
index 000000000..6202e4291
--- /dev/null
+++ b/Documentation/vm/balance
@@ -0,0 +1,81 @@
+Started Jan 2000 by Kanoj Sarcar <kanoj@sgi.com>
+
+Memory balancing is needed for non __GFP_WAIT as well as for non
+__GFP_IO allocations.
+
+There are two reasons to be requesting non __GFP_WAIT allocations:
+the caller can not sleep (typically intr context), or does not want
+to incur cost overheads of page stealing and possible swap io for
+whatever reasons.
+
+__GFP_IO allocation requests are made to prevent file system deadlocks.
+
+In the absence of non sleepable allocation requests, it seems detrimental
+to be doing balancing. Page reclamation can be kicked off lazily, that
+is, only when needed (aka zone free memory is 0), instead of making it
+a proactive process.
+
+That being said, the kernel should try to fulfill requests for direct
+mapped pages from the direct mapped pool, instead of falling back on
+the dma pool, so as to keep the dma pool filled for dma requests (atomic
+or not). A similar argument applies to highmem and direct mapped pages.
+OTOH, if there is a lot of free dma pages, it is preferable to satisfy
+regular memory requests by allocating one from the dma pool, instead
+of incurring the overhead of regular zone balancing.
+
+In 2.2, memory balancing/page reclamation would kick off only when the
+_total_ number of free pages fell below 1/64 th of total memory. With the
+right ratio of dma and regular memory, it is quite possible that balancing
+would not be done even when the dma zone was completely empty. 2.2 has
+been running production machines of varying memory sizes, and seems to be
+doing fine even with the presence of this problem. In 2.3, due to
+HIGHMEM, this problem is aggravated.
+
+In 2.3, zone balancing can be done in one of two ways: depending on the
+zone size (and possibly of the size of lower class zones), we can decide
+at init time how many free pages we should aim for while balancing any
+zone. The good part is, while balancing, we do not need to look at sizes
+of lower class zones, the bad part is, we might do too frequent balancing
+due to ignoring possibly lower usage in the lower class zones. Also,
+with a slight change in the allocation routine, it is possible to reduce
+the memclass() macro to be a simple equality.
+
+Another possible solution is that we balance only when the free memory
+of a zone _and_ all its lower class zones falls below 1/64th of the
+total memory in the zone and its lower class zones. This fixes the 2.2
+balancing problem, and stays as close to 2.2 behavior as possible. Also,
+the balancing algorithm works the same way on the various architectures,
+which have different numbers and types of zones. If we wanted to get
+fancy, we could assign different weights to free pages in different
+zones in the future.
+
+Note that if the size of the regular zone is huge compared to dma zone,
+it becomes less significant to consider the free dma pages while
+deciding whether to balance the regular zone. The first solution
+becomes more attractive then.
+
+The appended patch implements the second solution. It also "fixes" two
+problems: first, kswapd is woken up as in 2.2 on low memory conditions
+for non-sleepable allocations. Second, the HIGHMEM zone is also balanced,
+so as to give a fighting chance for replace_with_highmem() to get a
+HIGHMEM page, as well as to ensure that HIGHMEM allocations do not
+fall back into regular zone. This also makes sure that HIGHMEM pages
+are not leaked (for example, in situations where a HIGHMEM page is in
+the swapcache but is not being used by anyone)
+
+kswapd also needs to know about the zones it should balance. kswapd is
+primarily needed in a situation where balancing can not be done,
+probably because all allocation requests are coming from intr context
+and all process contexts are sleeping. For 2.3, kswapd does not really
+need to balance the highmem zone, since intr context does not request
+highmem pages. A zone aware kswapd still needs to be implemented.
+
+Page stealing from process memory and shm is done if stealing the page would
+alleviate memory pressure on any zone in the page's node that has fallen below
+its watermark.
+
+(Good) Ideas that I have heard:
+1. Dynamic experience should influence balancing: number of failed requests
+for a zone can be tracked and fed into the balancing scheme (jalvo@mbay.net)
+2. Implement a replace_with_highmem()-like replace_with_regular() to preserve
+dma pages. (lkd@tantalophile.demon.co.uk)
diff --git a/MAINTAINERS b/MAINTAINERS
index 302705aec..f053d2aae 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -503,7 +503,7 @@ P: Vojtech Pavlik
M: vojtech@suse.cz
L: linux-joystick@atrey.karlin.mff.cuni.cz
W: http://www.suse.cz/development/joystick/
-S: Maintained
+S: Supported
KERNEL AUTOMOUNTER (AUTOFS)
P: H. Peter Anvin
@@ -551,11 +551,11 @@ L: linux-m68k@lists.linux-m68k.org
S: Maintained
M68K ON APPLE MACINTOSH
-P: Alan Cox
-M: Alan.Cox@linux.org
-W: http://www.mac.linux-m68k.org/home.html
-L: linux-mac68k@wave.lm.com
-S: As time permits [Michael confess, you are the mac68k maintainer 8)]
+P: Joshua Thompson
+M: funaho@jurai.org
+W: http://www.mac.linux-m68k.org/
+L: linux-mac68k@mac.linux-m68k.org
+S: Maintained
M68K ON HP9000/300
P: Philip Blundell
@@ -631,7 +631,7 @@ M: pavel@atrey.karlin.mff.cuni.cz
S: Maintained
NETWORKING [GENERAL]
-P: Networking Teak
+P: Networking Team
M: netdev@oss.sgi.com
L: linux-net@vger.rutgers.edu
W: http://www.uk.linux.org/NetNews.html (2.0 only)
@@ -979,6 +979,19 @@ L: linux-usb@suse.com
W: http://www.linux-usb.org
S: Supported
+USB ACM DRIVER
+P: Vojtech Pavlik
+M: vojtech@suse.cz
+L: linux-usb@suse.com
+S: Supported
+
+USB HID/HIDBP/INPUT DRIVERS
+P: Vojtech Pavlik
+M: vojtech@suse.cz
+L: linux-usb@suse.com
+W: http://www.suse.cz/development/input/
+S: Supported
+
USB HUB
P: Johannes Erdfelt
M: jerdfelt@sventech.com
@@ -986,12 +999,16 @@ L: linux-usb@suse.com
S: Maintained
USB OHCI DRIVER
-P: Gregory P. Smith
-M: greg@electricrain.com
-M: greg@suitenine.com
+P: Roman Weissgaerber
+M: weissg@vienna.at
+L: linux-usb@suse.com
+S: Maintained
+
+USB PRINTER DRIVER
+P: Vojtech Pavlik
+M: vojtech@suse.cz
L: linux-usb@suse.com
-S: Maintained (not yet usable)
-W: http://suitenine.com/usb/
+S: Supported
USB SERIAL DRIVER
P: Greg Kroah-Hartman
diff --git a/Makefile b/Makefile
index 86af83199..cb2ca29a9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 2
PATCHLEVEL = 3
-SUBLEVEL = 40
+SUBLEVEL = 41
EXTRAVERSION =
ARCH = mips
@@ -205,7 +205,7 @@ DRIVERS := $(DRIVERS) drivers/macintosh/macintosh.a
endif
ifeq ($(CONFIG_ISAPNP),y)
-DRIVERS := $(DRIVERS) drivers/pnp/isa-pnp.o
+DRIVERS := $(DRIVERS) drivers/pnp/pnp.o
endif
ifdef CONFIG_SGI_IP22
@@ -449,6 +449,10 @@ mrproper: clean archmrproper
rm -f drivers/net/hamradio/soundmodem/gentbl
rm -f drivers/char/hfmodem/gentbl drivers/char/hfmodem/tables.h
rm -f drivers/sound/*_boot.h drivers/sound/.*.boot
+ rm -f drivers/sound/msndinit.c
+ rm -f drivers/sound/msndperm.c
+ rm -f drivers/sound/pndsperm.c
+ rm -f drivers/sound/pndspini.c
rm -f .version .config* config.in config.old
rm -f scripts/tkparse scripts/kconfig.tk scripts/kconfig.tmp
rm -f scripts/lxdialog/*.o scripts/lxdialog/lxdialog
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 95e539d34..d9af71414 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -504,7 +504,7 @@ asmlinkage int osf_utsname(char *name)
{
int error;
- down(&uts_sem);
+ down_read(&uts_sem);
error = -EFAULT;
if (copy_to_user(name + 0, system_utsname.sysname, 32))
goto out;
@@ -519,7 +519,7 @@ asmlinkage int osf_utsname(char *name)
error = 0;
out:
- up(&uts_sem);
+ up_read(&uts_sem);
return error;
}
@@ -569,7 +569,6 @@ asmlinkage int osf_getdomainname(char *name, int namelen)
unsigned len;
int i, error;
- lock_kernel();
error = verify_area(VERIFY_WRITE, name, namelen);
if (error)
goto out;
@@ -578,15 +577,14 @@ asmlinkage int osf_getdomainname(char *name, int namelen)
if (namelen > 32)
len = 32;
- down(&uts_sem);
+ down_read(&uts_sem);
for (i = 0; i < len; ++i) {
__put_user(system_utsname.domainname[i], name + i);
if (system_utsname.domainname[i] == '\0')
break;
}
- up(&uts_sem);
+ up_read(&uts_sem);
out:
- unlock_kernel();
return error;
}
@@ -810,7 +808,6 @@ asmlinkage long osf_sysinfo(int command, char *buf, long count)
char *res;
long len, err = -EINVAL;
- lock_kernel();
offset = command-1;
if (offset >= sizeof(sysinfo_table)/sizeof(char *)) {
/* Digital UNIX has a few unpublished interfaces here */
@@ -818,7 +815,7 @@ asmlinkage long osf_sysinfo(int command, char *buf, long count)
goto out;
}
- down(&uts_sem);
+ down_read(&uts_sem);
res = sysinfo_table[offset];
len = strlen(res)+1;
if (len > count)
@@ -827,9 +824,8 @@ asmlinkage long osf_sysinfo(int command, char *buf, long count)
err = -EFAULT;
else
err = 0;
- up(&uts_sem);
+ up_read(&uts_sem);
out:
- unlock_kernel();
return err;
}
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index f9fbd2536..54d962790 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -18,7 +18,6 @@
#include <linux/stddef.h>
#include <linux/binfmts.h>
#include <linux/tty.h>
-#include <linux/highuid.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
@@ -502,7 +501,6 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
info.si_code = SI_USER;
info.si_pid = current->p_pptr->pid;
info.si_uid = current->p_pptr->uid;
- info.si_uid16 = high2lowuid(current->p_pptr->uid);
}
/* If the (new) signal is now blocked, requeue it. */
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 5e989663b..47b2930c2 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -286,9 +286,9 @@ asmlinkage int sys_uname(struct old_utsname * name)
if(!name)
return -EFAULT;
- down(&uts_sem);
+ down_read(&uts_sem);
err=copy_to_user (name, &system_utsname, sizeof (*name));
- up(&uts_sem);
+ up_read(&uts_sem);
return err?-EFAULT:0;
}
@@ -309,7 +309,7 @@ asmlinkage int sys_olduname(struct oldold_utsname * name)
if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
return -EFAULT;
- down(&uts_sem);
+ down_read(&uts_sem);
error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
@@ -322,7 +322,7 @@ asmlinkage int sys_olduname(struct oldold_utsname * name)
error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
error |= __put_user(0,name->machine+__OLD_UTS_LEN);
- up(&uts_sem);
+ up_read(&uts_sem);
error = error ? -EFAULT : 0;
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 37b2371a0..4ba71ba06 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -22,7 +22,10 @@ LDFLAGS=-e stext
LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS)
CFLAGS_PIPE := -pipe
-CFLAGS_NSR := -fno-strength-reduce
+
+# only work around strength reduction bug(s) on older gcc versions
+CFLAGS_NSR := $(shell if $(CC) -march=i486 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo ""; else echo "-fno-strength-reduce"; fi)
+
CFLAGS := $(CFLAGS) $(CFLAGS_PIPE) $(CFLAGS_NSR)
# prevent gcc from keeping the stack 16 byte aligned
@@ -57,6 +60,12 @@ CFLAGS += $(shell if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null
AFLAGS := $(AFLAGS) -DCPU=686
endif
+ifdef CONFIG_MK6
+CFLAGS := $(CFLAGS) -DCPU=586
+CFLAGS += $(shell if $(CC) -march=k6 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=k6"; fi)
+AFLAGS := $(AFLAGS) -DCPU=586
+endif
+
ifdef CONFIG_MK7
CFLAGS := $(CFLAGS) -DCPU=686 -march=pentiumpro -mpentiumpro -malign-functions=4 -fschedule-insns2 -mwide-multiply -fexpensive-optimizations
CFLAGS += $(shell if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686"; fi)
diff --git a/arch/i386/config.in b/arch/i386/config.in
index a32b43c65..0dda4d49f 100644
--- a/arch/i386/config.in
+++ b/arch/i386/config.in
@@ -20,8 +20,9 @@ choice 'Processor family' \
"386 CONFIG_M386 \
486/Cx486 CONFIG_M486 \
586/K5/5x86/6x86 CONFIG_M586 \
- Pentium/K6/TSC CONFIG_M586TSC \
+ Pentium/TSC CONFIG_M586TSC \
PPro/6x86MX CONFIG_M686 \
+ K6/II/II CONFIG_MK6 \
Athlon CONFIG_MK7" PPro
#
# Define implied options from the CPU selection here
@@ -39,6 +40,9 @@ if [ "$CONFIG_M686" = "y" ]; then
define_bool CONFIG_X86_GOOD_APIC y
define_bool CONFIG_X86_PGE y
fi
+if [ "$CONFIG_MK6" = "y" ]; then
+ define_bool CONFIG_X86_TSC y
+fi
if [ "$CONFIG_MK7" = "y" ]; then
define_bool CONFIG_X86_TSC y
define_bool CONFIG_X86_GOOD_APIC y
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 91ca9739b..0c3dcfef1 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -18,6 +18,7 @@ CONFIG_UID16=y
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
CONFIG_M686=y
+# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
@@ -123,7 +124,6 @@ CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_XD is not set
# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_PARIDE_PARPORT=y
# CONFIG_PARIDE is not set
CONFIG_BLK_DEV_IDE_MODES=y
# CONFIG_BLK_DEV_HD is not set
@@ -423,32 +423,46 @@ CONFIG_PCMCIA_SERIAL=y
# Filesystems
#
# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_BFS_FS_WRITE 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_CRAMFS is not set
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
# CONFIG_MINIX_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_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_SYSV_FS_WRITE 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_NFS_FS=y
+# CONFIG_ROOT_NFS is not set
CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
# CONFIG_SMB_FS is not set
@@ -459,8 +473,6 @@ CONFIG_LOCKD=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
#
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index a59e7c71b..6b7302f99 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -14,7 +14,8 @@ all: kernel.o head.o init_task.o
O_TARGET := kernel.o
O_OBJS := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
- ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o
+ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
+ pci-dma.o
OX_OBJS := i386_ksyms.o
MX_OBJS :=
@@ -39,8 +40,16 @@ else
endif
endif
+ifdef CONFIG_ACPI
+OX_OBJS += pm.o
+else
+ifdef CONFIG_APM
+OX_OBJS += pm.o
+endif
+endif
+
ifeq ($(CONFIG_ACPI),y)
- OX_OBJS += acpi.o
+ O_OBJS += acpi.o
endif
ifeq ($(CONFIG_APM),y)
diff --git a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c
index 3fd1704e3..5ad3106f8 100644
--- a/arch/i386/kernel/acpi.c
+++ b/arch/i386/kernel/acpi.c
@@ -39,25 +39,10 @@
#include <asm/io.h>
#include <linux/sysctl.h>
#include <linux/delay.h>
+#include <linux/pm.h>
#include <linux/acpi.h>
/*
- * Defines for 2.2.x
- */
-#ifndef __exit
-#define __exit
-#endif
-#ifndef module_init
-#define module_init(x) int init_module(void) {return x();}
-#endif
-#ifndef module_exit
-#define module_exit(x) void cleanup_module(void) {x();}
-#endif
-#ifndef DECLARE_WAIT_QUEUE_HEAD
-#define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue * x = NULL
-#endif
-
-/*
* Yes, it's unfortunate that we are relying on get_cmos_time
* because it is slow (> 1 sec.) and i386 only. It might be better
* to use some of the code from drivers/char/rtc.c in the near future
@@ -108,9 +93,6 @@ static volatile u32 acpi_gpe_level = 0;
static volatile acpi_sstate_t acpi_event_state = ACPI_S0;
static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait);
-static spinlock_t acpi_devs_lock = SPIN_LOCK_UNLOCKED;
-static LIST_HEAD(acpi_devs);
-
/* Make it impossible to enter C2/C3 until after we've initialized */
static unsigned long acpi_enter_lvl2_lat = ACPI_INFINITE_LAT;
static unsigned long acpi_enter_lvl3_lat = ACPI_INFINITE_LAT;
@@ -520,21 +502,14 @@ static void acpi_destroy_tables(void)
}
/*
- * Locate PIIX4 device and create a fake FACP
+ * Init PIIX4 device, create a fake FACP
*/
-static int __init acpi_find_piix4(void)
+static int __init acpi_init_piix4(struct pci_dev *dev)
{
- struct pci_dev *dev;
u32 base;
u16 cmd;
u8 pmregmisc;
- dev = pci_find_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_3,
- NULL);
- if (!dev)
- return -ENODEV;
-
pci_read_config_word(dev, PCI_COMMAND, &cmd);
if (!(cmd & PCI_COMMAND_IO))
return -ENODEV;
@@ -587,6 +562,124 @@ static int __init acpi_find_piix4(void)
}
/*
+ * Init VIA ACPI device and create a fake FACP
+ */
+static int __init acpi_init_via686a(struct pci_dev *dev)
+{
+ u32 base;
+ u8 tmp, irq;
+
+ pci_read_config_byte(dev, 0x41, &tmp);
+ if (!(tmp & 0x80))
+ return -ENODEV;
+
+ pci_read_config_byte(dev, PCI_CLASS_REVISION, &tmp);
+ tmp = (tmp & 0x10 ? 0x48 : 0x20);
+
+ pci_read_config_dword(dev, tmp, &base);
+ if (!(base & PCI_BASE_ADDRESS_SPACE_IO))
+ return -ENODEV;
+
+ base &= PCI_BASE_ADDRESS_IO_MASK;
+ if (!base)
+ return -ENODEV;
+
+ pci_read_config_byte(dev, 0x42, &irq);
+
+ printk(KERN_INFO "ACPI: found %s at 0x%04x\n", dev->name, base);
+
+ acpi_facp = kmalloc(sizeof(struct acpi_facp), GFP_KERNEL);
+ if (!acpi_facp)
+ return -ENOMEM;
+
+ acpi_fake_facp = 1;
+ memset(acpi_facp, 0, sizeof(struct acpi_facp));
+
+ acpi_facp->int_model = ACPI_VIA_INT_MODEL;
+ acpi_facp->sci_int = irq;
+ acpi_facp->smi_cmd = base + ACPI_VIA_SMI_CMD;
+ acpi_facp->acpi_enable = ACPI_VIA_ACPI_ENABLE;
+ acpi_facp->acpi_disable = ACPI_VIA_ACPI_DISABLE;
+ acpi_facp->pm1a_evt = base + ACPI_VIA_PM1_EVT;
+ acpi_facp->pm1a_cnt = base + ACPI_VIA_PM1_CNT;
+ acpi_facp->pm_tmr = base + ACPI_VIA_PM_TMR;
+ acpi_facp->gpe0 = base + ACPI_VIA_GPE0;
+
+ acpi_facp->pm1_evt_len = ACPI_VIA_PM1_EVT_LEN;
+ acpi_facp->pm1_cnt_len = ACPI_VIA_PM1_CNT_LEN;
+ acpi_facp->pm_tm_len = ACPI_VIA_PM_TM_LEN;
+ acpi_facp->gpe0_len = ACPI_VIA_GPE0_LEN;
+ acpi_facp->p_lvl2_lat = (__u16) ACPI_INFINITE_LAT;
+ acpi_facp->p_lvl3_lat = (__u16) ACPI_INFINITE_LAT;
+
+ acpi_facp->duty_offset = ACPI_VIA_DUTY_OFFSET;
+ acpi_facp->duty_width = ACPI_VIA_DUTY_WIDTH;
+
+ acpi_facp->day_alarm = ACPI_VIA_DAY_ALARM;
+ acpi_facp->mon_alarm = ACPI_VIA_MON_ALARM;
+ acpi_facp->century = ACPI_VIA_CENTURY;
+
+ acpi_facp_addr = virt_to_phys(acpi_facp);
+ acpi_dsdt_addr = 0;
+
+ acpi_p_blk = base + ACPI_VIA_P_BLK;
+
+ return 0;
+}
+
+typedef enum
+{
+ CH_UNKNOWN = 0,
+ CH_INTEL_PIIX4,
+ CH_VIA_686A,
+} acpi_chip_t;
+
+/* indexed by value of each enum in acpi_chip_t */
+const static struct
+{
+ int (*chip_init)(struct pci_dev *dev);
+} acpi_chip_info[] =
+{
+ {NULL,},
+ {acpi_init_piix4},
+ {acpi_init_via686a},
+};
+
+const static struct pci_device_id acpi_pci_tbl[] =
+{
+ {0x8086, 0x7113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_INTEL_PIIX4},
+ {0x1106, 0x3057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_686A},
+ {0,}, /* terminate list */
+};
+
+static int __init acpi_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ return acpi_chip_info[id->driver_data].chip_init(dev);
+}
+
+static struct pci_driver acpi_driver =
+{
+ name: "acpi",
+ id_table: acpi_pci_tbl,
+ probe: acpi_probe,
+};
+static int pci_driver_registered = 0;
+
+/*
+ * Locate a known ACPI chipset
+ */
+static int __init acpi_find_chipset(void)
+{
+ if (pci_register_driver(&acpi_driver) < 1)
+ return -ENODEV;
+
+ pci_driver_registered = 1;
+
+ return 0;
+}
+
+/*
* Handle an ACPI SCI (fixed or general purpose event)
*/
static void acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
@@ -693,7 +786,7 @@ static void wake_on_busmaster(struct acpi_facp *facp)
/* The ACPI timer is just the low 24 bits */
#define TIME_BEGIN(tmr) inl(tmr)
-#define TIME_END(tmr, begin) ((inl(tmr) - (begin)) & 0x00ffffff)
+#define TIME_END(tmr, begin) ((inl(tmr) - (begin)) & 0x00ffffff)
/*
@@ -836,24 +929,11 @@ out:
static int acpi_enter_dx(acpi_dstate_t state)
{
int status = 0;
- struct list_head *i = acpi_devs.next;
-
- while (i != &acpi_devs) {
- struct acpi_dev *dev = list_entry(i, struct acpi_dev, entry);
- if (dev->state != state) {
- int dev_status = 0;
- if (dev->info.transition)
- dev_status = dev->info.transition(dev, state);
- if (!dev_status) {
- // put hardware into D-state
- dev->state = state;
- }
- if (dev_status)
- status = dev_status;
- }
-
- i = i->next;
- }
+
+ if (state == ACPI_D0)
+ status = pm_send_request(PM_RESUME, (void*) state);
+ else
+ status = pm_send_request(PM_SUSPEND, (void*) state);
return status;
}
@@ -1208,6 +1288,7 @@ static int acpi_do_sleep(ctl_table *ctl,
return 0;
}
+
/*
* Initialize and enable ACPI
*/
@@ -1218,17 +1299,17 @@ static int __init acpi_init(void)
if (acpi_disabled)
return -ENODEV;
- if (acpi_find_tables() && acpi_find_piix4()) {
- // no ACPI tables and not PIIX4
+ if (acpi_find_tables() && acpi_find_chipset()) {
+ // no ACPI tables and not recognized chipset
return -ENODEV;
}
- /*
- * Internally we always keep latencies in timer
- * ticks, which is simpler and more consistent (what is
- * an uS to us?). Besides, that gives people more
- * control in the /proc interfaces.
- */
+ /*
+ * Internally we always keep latencies in timer
+ * ticks, which is simpler and more consistent (what is
+ * an uS to us?). Besides, that gives people more
+ * control in the /proc interfaces.
+ */
if (acpi_facp->p_lvl2_lat
&& acpi_facp->p_lvl2_lat <= ACPI_MAX_P_LVL2_LAT) {
acpi_p_lvl2_lat = ACPI_uS_TO_TMR_TICKS(acpi_facp->p_lvl2_lat);
@@ -1249,7 +1330,11 @@ static int __init acpi_init(void)
acpi_facp)) {
printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n",
acpi_facp->sci_int);
+
+ if (pci_driver_registered)
+ pci_unregister_driver(&acpi_driver);
acpi_destroy_tables();
+
return -ENODEV;
}
@@ -1296,8 +1381,14 @@ static void __exit acpi_exit(void)
free_irq(acpi_facp->sci_int, acpi_facp);
acpi_destroy_tables();
+
+ if (pci_driver_registered)
+ pci_unregister_driver(&acpi_driver);
}
+/*
+ * Parse kernel command line options
+ */
static int __init acpi_setup(char *str)
{
while (str && *str) {
@@ -1315,53 +1406,6 @@ static int __init acpi_setup(char *str)
__setup("acpi=", acpi_setup);
/*
- * Register a device with the ACPI subsystem
- */
-struct acpi_dev* acpi_register(struct acpi_dev_info *info, unsigned long adr)
-{
- struct acpi_dev *dev = NULL;
- if (info) {
- dev = kmalloc(sizeof(struct acpi_dev), GFP_KERNEL);
- if (dev) {
- unsigned long flags;
-
- memset(dev, 0, sizeof(*dev));
- memcpy(&dev->info, info, sizeof(dev->info));
- dev->adr = adr;
-
- spin_lock_irqsave(&acpi_devs_lock, flags);
- list_add(&dev->entry, &acpi_devs);
- spin_unlock_irqrestore(&acpi_devs_lock, flags);
- }
- }
- return dev;
-}
-
-/*
- * Unregister a device with ACPI
- */
-void acpi_unregister(struct acpi_dev *dev)
-{
- if (dev) {
- unsigned long flags;
-
- spin_lock_irqsave(&acpi_devs_lock, flags);
- list_del(&dev->entry);
- spin_unlock_irqrestore(&acpi_devs_lock, flags);
-
- kfree(dev);
- }
-}
-
-/*
- * Wake up a device
- */
-void acpi_wakeup(struct acpi_dev *dev)
-{
- // run _PS0 or tell parent bus to wake device up
-}
-
-/*
* Manage idle devices
*/
static int acpi_control_thread(void *context)
@@ -1382,11 +1426,3 @@ static int acpi_control_thread(void *context)
}
__initcall(acpi_init);
-
-/*
- * Module visible symbols
- */
-EXPORT_SYMBOL(acpi_control_wait);
-EXPORT_SYMBOL(acpi_register);
-EXPORT_SYMBOL(acpi_unregister);
-EXPORT_SYMBOL(acpi_wakeup);
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 8f3d24645..daa7226cd 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -1413,18 +1413,11 @@ static int __init apm_setup(char *str)
__setup("apm=", apm_setup);
static struct file_operations apm_bios_fops = {
- NULL, /* lseek */
- do_read,
- NULL, /* write */
- NULL, /* readdir */
- do_poll,
- do_ioctl,
- NULL, /* mmap */
- do_open,
- NULL, /* flush */
- do_release,
- NULL, /* fsync */
- NULL /* fasync */
+ read: do_read,
+ poll: do_poll,
+ ioctl: do_ioctl,
+ open: do_open,
+ release: do_release,
};
static struct miscdevice apm_device = {
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index e91602aba..f93765754 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -617,6 +617,7 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_setgid)
.long SYMBOL_NAME(sys_setfsuid) /* 215 */
.long SYMBOL_NAME(sys_setfsgid)
+ .long SYMBOL_NAME(sys_pivot_root)
/*
@@ -625,6 +626,6 @@ ENTRY(sys_call_table)
* entries. Don't panic if you notice that this hasn't
* been shrunk every time we add a new system call.
*/
- .rept NR_syscalls-216
+ .rept NR_syscalls-217
.long SYMBOL_NAME(sys_ni_syscall)
.endr
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
index 2df82ff21..456f4bab2 100644
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -9,6 +9,7 @@
#include <linux/interrupt.h>
#include <linux/smp_lock.h>
#include <linux/acpi.h>
+#include <linux/pci.h>
#include <asm/semaphore.h>
#include <asm/processor.h>
@@ -86,6 +87,9 @@ EXPORT_SYMBOL(__generic_copy_from_user);
EXPORT_SYMBOL(__generic_copy_to_user);
EXPORT_SYMBOL(strnlen_user);
+EXPORT_SYMBOL(pci_alloc_consistent);
+EXPORT_SYMBOL(pci_free_consistent);
+
#ifdef CONFIG_X86_USE_3DNOW
EXPORT_SYMBOL(_mmx_memcpy);
EXPORT_SYMBOL(mmx_clear_page);
diff --git a/arch/i386/kernel/pci-dma.c b/arch/i386/kernel/pci-dma.c
new file mode 100644
index 000000000..18b203228
--- /dev/null
+++ b/arch/i386/kernel/pci-dma.c
@@ -0,0 +1,51 @@
+/*
+ * Dynamic DMA mapping support.
+ *
+ * On i386 there is no hardware dynamic DMA address translation,
+ * so consistent alloc/free are merely page allocation/freeing.
+ * The rest of the dynamic DMA mapping interface is implemented
+ * in asm/pci.h.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+/* Pure 2^n version of get_order */
+extern __inline__ int __get_order(unsigned long size)
+{
+ int order;
+
+ size = (size-1) >> (PAGE_SHIFT-1);
+ order = -1;
+ do {
+ size >>= 1;
+ order++;
+ } while (size);
+ return order;
+}
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+ dma_addr_t *dma_handle)
+{
+ void *ret;
+ int gfp = GFP_ATOMIC;
+
+ if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
+ gfp |= GFP_DMA;
+ ret = (void *)__get_free_pages(gfp, __get_order(size));
+
+ if (ret != NULL) {
+ memset(ret, 0, size);
+ *dma_handle = virt_to_bus(ret);
+ }
+ return ret;
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ free_pages((unsigned long)vaddr, __get_order(size));
+}
diff --git a/arch/i386/kernel/pm.c b/arch/i386/kernel/pm.c
new file mode 100644
index 000000000..35ec0f489
--- /dev/null
+++ b/arch/i386/kernel/pm.c
@@ -0,0 +1,104 @@
+/*
+ * pm.c - Power management interface
+ *
+ * Copyright (C) 2000 Andrew Henroid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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/spinlock.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
+
+static spinlock_t pm_devs_lock = SPIN_LOCK_UNLOCKED;
+static LIST_HEAD(pm_devs);
+
+/*
+ * Register a device with power management
+ */
+struct pm_dev *pm_register(pm_dev_t type,
+ unsigned long id,
+ pm_callback callback)
+{
+ struct pm_dev *dev = kmalloc(sizeof(struct pm_dev), GFP_KERNEL);
+ if (dev) {
+ unsigned long flags;
+
+ memset(dev, 0, sizeof(*dev));
+ dev->type = type;
+ dev->id = id;
+ dev->callback = callback;
+
+ spin_lock_irqsave(&pm_devs_lock, flags);
+ list_add(&dev->entry, &pm_devs);
+ spin_unlock_irqrestore(&pm_devs_lock, flags);
+ }
+ return dev;
+}
+
+/*
+ * Unregister a device with power management
+ */
+void pm_unregister(struct pm_dev *dev)
+{
+ if (dev) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&pm_devs_lock, flags);
+ list_del(&dev->entry);
+ spin_unlock_irqrestore(&pm_devs_lock, flags);
+
+ kfree(dev);
+ }
+}
+
+/*
+ * Send a request to all devices
+ */
+int pm_send_request(pm_request_t rqst, void *data)
+{
+ struct list_head *entry = pm_devs.next;
+ while (entry != &pm_devs) {
+ struct pm_dev *dev = list_entry(entry, struct pm_dev, entry);
+ if (dev->callback) {
+ int status = (*dev->callback)(dev, rqst, data);
+ if (status)
+ return status;
+ }
+ entry = entry->next;
+ }
+ return 0;
+}
+
+/*
+ * Find a device
+ */
+struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from)
+{
+ struct list_head *entry = from ? from->entry.next:pm_devs.next;
+ while (entry != &pm_devs) {
+ struct pm_dev *dev = list_entry(entry, struct pm_dev, entry);
+ if (type == PM_UNKNOWN_DEV || dev->type == type)
+ return dev;
+ entry = entry->next;
+ }
+ return 0;
+}
+
+EXPORT_SYMBOL(pm_register);
+EXPORT_SYMBOL(pm_unregister);
+EXPORT_SYMBOL(pm_send_request);
+EXPORT_SYMBOL(pm_find);
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index 18de47dd4..a973746b9 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -19,7 +19,6 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
-#include <linux/highuid.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
@@ -643,7 +642,6 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
info.si_code = SI_USER;
info.si_pid = current->p_pptr->pid;
info.si_uid = current->p_pptr->uid;
- info.si_uid16 = high2lowuid(current->p_pptr->uid);
}
/* If the (new) signal is now blocked, requeue it. */
diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c
index 8a0c6dbda..362ee64c0 100644
--- a/arch/i386/kernel/sys_i386.c
+++ b/arch/i386/kernel/sys_i386.c
@@ -218,9 +218,9 @@ asmlinkage int sys_uname(struct old_utsname * name)
int err;
if (!name)
return -EFAULT;
- down(&uts_sem);
+ down_read(&uts_sem);
err=copy_to_user(name, &system_utsname, sizeof (*name));
- up(&uts_sem);
+ up_read(&uts_sem);
return err?-EFAULT:0;
}
@@ -233,7 +233,7 @@ asmlinkage int sys_olduname(struct oldold_utsname * name)
if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
return -EFAULT;
- down(&uts_sem);
+ down_read(&uts_sem);
error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
@@ -246,7 +246,7 @@ asmlinkage int sys_olduname(struct oldold_utsname * name)
error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
error |= __put_user(0,name->machine+__OLD_UTS_LEN);
- up(&uts_sem);
+ up_read(&uts_sem);
error = error ? -EFAULT : 0;
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index b20ddc2d5..70520b99d 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -196,7 +196,7 @@ void __init kmap_init(void)
kmap_prot = PAGE_KERNEL;
}
-#endif
+#endif /* CONFIG_HIGHMEM */
void show_mem(void)
{
diff --git a/arch/m68k/amiga/amisound.c b/arch/m68k/amiga/amisound.c
index 170d28948..faba5841b 100644
--- a/arch/m68k/amiga/amisound.c
+++ b/arch/m68k/amiga/amisound.c
@@ -42,7 +42,7 @@ static u_long clock_constant;
void __init amiga_init_sound(void)
{
- snd_data = amiga_chip_alloc(sizeof(sine_data));
+ snd_data = amiga_chip_alloc(sizeof(sine_data), "Beep");
if (!snd_data) {
printk (KERN_CRIT "amiga init_sound: failed to allocate chipmem\n");
return;
diff --git a/arch/m68k/amiga/chipram.c b/arch/m68k/amiga/chipram.c
index 80bc3c408..1ea26c631 100644
--- a/arch/m68k/amiga/chipram.c
+++ b/arch/m68k/amiga/chipram.c
@@ -8,6 +8,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/zorro.h>
#include <asm/amigahw.h>
struct chip_desc {
@@ -23,6 +24,8 @@ struct chip_desc {
u_long amiga_chip_size;
static unsigned long chipavail;
+static struct resource chipram = { "Chip RAM", 0 };
+
unsigned long amiga_chip_avail( void )
{
#ifdef DEBUG
@@ -39,6 +42,9 @@ void __init amiga_chip_init (void)
if (!AMIGAHW_PRESENT(CHIP_RAM))
return;
+ chipram.end = amiga_chip_size;
+ request_resource(&iomem_resource, &chipram);
+
/* initialize start boundary */
dp = DP(chipaddr);
@@ -61,7 +67,7 @@ void __init amiga_chip_init (void)
#endif
}
-void *amiga_chip_alloc (long size)
+void *amiga_chip_alloc(long size, const char *name)
{
/* last chunk */
struct chip_desc *dp;
@@ -71,7 +77,7 @@ void *amiga_chip_alloc (long size)
size = (size + 7) & ~7;
#ifdef DEBUG
- printk("chip_alloc: allocate %ld bytes\n", size);
+ printk("amiga_chip_alloc: allocate %ld bytes\n", size);
#endif
/*
@@ -97,14 +103,14 @@ void *amiga_chip_alloc (long size)
dp = DP((unsigned long)ptr + dp->length);
dp->alloced = 1;
#ifdef DEBUG
- printk ("chip_alloc: no split\n");
+ printk ("amiga_chip_alloc: no split\n");
#endif
} else {
/* split the extent; use the end part */
long newsize = dp->length - (2*sizeof(*dp) + size);
#ifdef DEBUG
- printk ("chip_alloc: splitting %d to %ld\n", dp->length,
+ printk ("amiga_chip_alloc: splitting %d to %ld\n", dp->length,
newsize);
#endif
dp->length = newsize;
@@ -123,14 +129,18 @@ void *amiga_chip_alloc (long size)
}
#ifdef DEBUG
- printk ("chip_alloc: returning %p\n", ptr);
+ printk ("amiga_chip_alloc: returning %p\n", ptr);
#endif
if ((unsigned long)ptr & 7)
- panic("chip_alloc: alignment violation\n");
+ panic("amiga_chip_alloc: alignment violation\n");
chipavail -= size + (2*sizeof(*dp)); /*MILAN*/
+ if (!request_mem_region(ZTWO_PADDR(ptr), size, name))
+ printk(KERN_WARNING "amiga_chip_alloc: region of size %ld at 0x%08lx "
+ "is busy\n", size, ZTWO_PADDR(ptr));
+
return ptr;
}
@@ -145,6 +155,7 @@ void amiga_chip_free (void *ptr)
#endif
/* deallocate the chunk */
sdp->alloced = edp->alloced = 0;
+ release_mem_region(ZTWO_PADDR(ptr), sdp->length);
/* check if we should merge with the previous chunk */
if (!sdp->first && !sdp[-1].alloced) {
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
index 95eaa76f3..3eca427f5 100644
--- a/arch/m68k/amiga/config.c
+++ b/arch/m68k/amiga/config.c
@@ -116,6 +116,23 @@ static char amiga_sysrq_xlate[128] =
extern void (*kd_mksound)(unsigned int, unsigned int);
+
+ /*
+ * Motherboard Resources present in all Amiga models
+ */
+
+static struct resource mb_resource[] = {
+ { "CIA B", 0x00bfd000, 0x00bfdfff },
+ { "CIA A", 0x00bfe000, 0x00bfefff },
+ { "Custom I/O", 0x00dff000, 0x00dfffff },
+ { "Kickstart ROM", 0x00f80000, 0x00ffffff }
+};
+
+static struct resource rtc_resource = {
+ NULL, 0x00dc0000, 0x00dcffff
+};
+
+
/*
* Parse an Amiga-specific record in the bootinfo
*/
@@ -151,11 +168,15 @@ int amiga_parse_bootinfo(const struct bi_record *record)
break;
case BI_AMIGA_AUTOCON:
- if (zorro_num_autocon < ZORRO_NUM_AUTO)
- memcpy(&zorro_autocon[zorro_num_autocon++],
- (const struct ConfigDev *)data,
- sizeof(struct ConfigDev));
- else
+ if (zorro_num_autocon < ZORRO_NUM_AUTO) {
+ const struct ConfigDev *cd = (struct ConfigDev *)data;
+ struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++];
+ dev->rom = cd->cd_Rom;
+ dev->slotaddr = cd->cd_SlotAddr;
+ dev->slotsize = cd->cd_SlotSize;
+ dev->resource.start = (unsigned long)cd->cd_BoardAddr;
+ dev->resource.end = dev->resource.start+cd->cd_BoardSize-1;
+ } else
printk("amiga_parse_bootinfo: too many AutoConfig devices\n");
break;
@@ -336,9 +357,16 @@ static void __init amiga_identify(void)
void __init config_amiga(void)
{
+ int i;
+
amiga_debug_init();
amiga_identify();
+ /* Yuk, we don't have PCI memory */
+ iomem_resource.name = "Memory";
+ for (i = 0; i < sizeof(mb_resource)/sizeof(mb_resource[0]); i++)
+ request_resource(&iomem_resource, &mb_resource[i]);
+
mach_sched_init = amiga_sched_init;
mach_keyb_init = amiga_keyb_init;
mach_kbdrate = amiga_kbdrate;
@@ -354,9 +382,13 @@ void __init config_amiga(void)
mach_gettimeoffset = amiga_gettimeoffset;
if (AMIGAHW_PRESENT(A3000_CLK)){
mach_gettod = a3000_gettod;
+ rtc_resource.name = "A3000 RTC";
+ request_resource(&iomem_resource, &rtc_resource);
}
else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */
mach_gettod = a2000_gettod;
+ rtc_resource.name = "A2000 RTC";
+ request_resource(&iomem_resource, &rtc_resource);
}
mach_max_dma_address = 0xffffffff; /*
@@ -798,7 +830,7 @@ static void amiga_mem_console_write(struct console *co, const char *s,
static void amiga_savekmsg_init(void)
{
- savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM);
+ savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM, "Debug");
savekmsg->magic1 = SAVEKMSG_MAGIC1;
savekmsg->magic2 = SAVEKMSG_MAGIC2;
savekmsg->magicptr = virt_to_phys(savekmsg);
@@ -973,8 +1005,9 @@ static int amiga_get_hardware_list(char *buffer)
AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick");
AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot");
if (AMIGAHW_PRESENT(ZORRO))
- len += sprintf(buffer+len, "\tZorro%s AutoConfig: %d Expansion Device%s\n",
- AMIGAHW_PRESENT(ZORRO3) ? " III" : "",
+ len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion "
+ "Device%s\n",
+ AMIGAHW_PRESENT(ZORRO3) ? "I" : "",
zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
#undef AMIGAHW_ANNOUNCE
diff --git a/arch/m68k/apollo/Makefile b/arch/m68k/apollo/Makefile
index 530be849c..ba57e005d 100644
--- a/arch/m68k/apollo/Makefile
+++ b/arch/m68k/apollo/Makefile
@@ -8,7 +8,7 @@
# Note 2! The CFLAGS definitions are now in the main makefile...
O_TARGET := apollo.o
-O_OBJS := config.o dn_ints.o \
+O_OBJS := config.o dn_ints.o dma.o \
include $(TOPDIR)/Rules.make
diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c
index e3b54b40e..b94875cbf 100644
--- a/arch/m68k/apollo/config.c
+++ b/arch/m68k/apollo/config.c
@@ -7,19 +7,26 @@
#include <linux/console.h>
#include <asm/setup.h>
+#include <asm/bootinfo.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/apollohw.h>
#include <asm/irq.h>
#include <asm/machdep.h>
+u_long sio01_physaddr;
+u_long sio23_physaddr;
+u_long rtc_physaddr;
+u_long pica_physaddr;
+u_long picb_physaddr;
+u_long cpuctrl_physaddr;
+u_long timer_physaddr;
+u_long apollo_model;
+
extern void dn_sched_init(void (*handler)(int,void *,struct pt_regs *));
extern int dn_keyb_init(void);
extern int dn_dummy_kbdrate(struct kbd_repeat *);
extern void dn_init_IRQ(void);
-#if 0
-extern void (*dn_default_handler[])(int,void *,struct pt_regs *);
-#endif
extern int dn_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
extern void dn_free_irq(unsigned int irq, void *dev_id);
extern void dn_enable_irq(unsigned int);
@@ -37,20 +44,93 @@ extern void dn_dummy_debug_init(void);
extern void (*kd_mksound)(unsigned int, unsigned int);
extern void dn_dummy_video_setup(char *,int *);
extern void dn_process_int(int irq, struct pt_regs *fp);
-
-static struct console dn_console_driver;
-static void dn_debug_init(void);
+#ifdef CONFIG_HEARTBEAT
+static void dn_heartbeat(int on);
+#endif
static void dn_timer_int(int irq,void *, struct pt_regs *);
static void (*sched_timer_handler)(int, void *, struct pt_regs *)=NULL;
+static void dn_get_model(char *model);
+static int dn_cpuctrl=0xff00;
+static const char *apollo_models[] = {
+ "DN3000 (Otter)",
+ "DN3010 (Otter)",
+ "DN3500 (Cougar II)",
+ "DN4000 (Mink)",
+ "DN4500 (Roadrunner)" };
+
+int apollo_parse_bootinfo(const struct bi_record *record) {
+
+ int unknown = 0;
+ const unsigned long *data = record->data;
+
+ switch(record->tag) {
+ case BI_APOLLO_MODEL:
+ apollo_model=*data;
+ break;
+
+ default:
+ unknown=1;
+ }
+
+ return unknown;
+}
+
+void dn_setup_model(void) {
+
-int dn_serial_console_wait_key(void) {
+ printk("Apollo hardware found: ");
+ printk("[%s]\n", apollo_models[apollo_model - APOLLO_DN3000]);
+
+ switch(apollo_model) {
+ case APOLLO_UNKNOWN:
+ panic("Unknown apollo model");
+ break;
+ case APOLLO_DN3000:
+ case APOLLO_DN3010:
+ sio01_physaddr=SAU8_SIO01_PHYSADDR;
+ rtc_physaddr=SAU8_RTC_PHYSADDR;
+ pica_physaddr=SAU8_PICA;
+ picb_physaddr=SAU8_PICB;
+ cpuctrl_physaddr=SAU8_CPUCTRL;
+ timer_physaddr=SAU8_TIMER;
+ break;
+ case APOLLO_DN4000:
+ sio01_physaddr=SAU7_SIO01_PHYSADDR;
+ sio23_physaddr=SAU7_SIO23_PHYSADDR;
+ rtc_physaddr=SAU7_RTC_PHYSADDR;
+ pica_physaddr=SAU7_PICA;
+ picb_physaddr=SAU7_PICB;
+ cpuctrl_physaddr=SAU7_CPUCTRL;
+ timer_physaddr=SAU7_TIMER;
+ break;
+ case APOLLO_DN4500:
+ panic("Apollo model not yet supported");
+ break;
+ case APOLLO_DN3500:
+ sio01_physaddr=SAU7_SIO01_PHYSADDR;
+ sio23_physaddr=SAU7_SIO23_PHYSADDR;
+ rtc_physaddr=SAU7_RTC_PHYSADDR;
+ pica_physaddr=SAU7_PICA;
+ picb_physaddr=SAU7_PICB;
+ cpuctrl_physaddr=SAU7_CPUCTRL;
+ timer_physaddr=SAU7_TIMER;
+ break;
+ default:
+ panic("Undefined apollo model");
+ break;
+ }
+
+
+}
+
+int dn_serial_console_wait_key(struct console *co) {
while(!(sio01.srb_csrb & 1))
barrier();
return sio01.rhrb_thrb;
}
-void dn_serial_console_write (const char *str,unsigned int count)
+void dn_serial_console_write (struct console *co, const char *str,unsigned int count)
{
while(count--) {
if (*str == '\n') {
@@ -80,12 +160,9 @@ void dn_serial_print (const char *str)
void config_apollo(void) {
- dn_serial_print("Config apollo !\n");
-#if 0
- dn_debug_init();
-#endif
- printk("Config apollo !\n");
+ int i;
+ dn_setup_model();
mach_sched_init=dn_sched_init; /* */
mach_keyb_init=dn_keyb_init;
@@ -109,13 +186,19 @@ void config_apollo(void) {
#endif
mach_reset = dn_dummy_reset; /* */
#ifdef CONFIG_DUMMY_CONSOLE
- conswitchp = &dummy_con;
-#endif
-#if 0
- mach_fb_init = dn_fb_init;
- mach_video_setup = dn_dummy_video_setup;
+ conswitchp = &dummy_con;
#endif
kd_mksound = dn_mksound;
+#ifdef CONFIG_HEARTBEAT
+ mach_heartbeat = dn_heartbeat;
+#endif
+ mach_get_model = dn_get_model;
+
+ cpuctrl=0xaa00;
+
+ /* clear DMA translation table */
+ for(i=0;i<0x400;i++)
+ addr_xlat_map[i]=0;
}
@@ -125,44 +208,30 @@ void dn_timer_int(int irq, void *dev_id, struct pt_regs *fp) {
sched_timer_handler(irq,dev_id,fp);
- x=*(volatile unsigned char *)(IO_BASE+0x10803);
- x=*(volatile unsigned char *)(IO_BASE+0x10805);
+ x=*(volatile unsigned char *)(timer+3);
+ x=*(volatile unsigned char *)(timer+5);
}
void dn_sched_init(void (*timer_routine)(int, void *, struct pt_regs *)) {
- dn_serial_print("dn sched_init\n");
-
-#if 0
- /* program timer 2 */
- *(volatile unsigned char *)(IO_BASE+0x10803)=0x00;
- *(volatile unsigned char *)(IO_BASE+0x10809)=0;
- *(volatile unsigned char *)(IO_BASE+0x1080b)=50;
-
- /* program timer 3 */
- *(volatile unsigned char *)(IO_BASE+0x10801)=0x00;
- *(volatile unsigned char *)(IO_BASE+0x1080c)=0;
- *(volatile unsigned char *)(IO_BASE+0x1080f)=50;
-#endif
/* program timer 1 */
- *(volatile unsigned char *)(IO_BASE+0x10803)=0x01;
- *(volatile unsigned char *)(IO_BASE+0x10801)=0x40;
- *(volatile unsigned char *)(IO_BASE+0x10805)=0x09;
- *(volatile unsigned char *)(IO_BASE+0x10807)=0xc4;
+ *(volatile unsigned char *)(timer+3)=0x01;
+ *(volatile unsigned char *)(timer+1)=0x40;
+ *(volatile unsigned char *)(timer+5)=0x09;
+ *(volatile unsigned char *)(timer+7)=0xc4;
/* enable IRQ of PIC B */
- *(volatile unsigned char *)(IO_BASE+PICA+1)&=(~8);
-
-
+ *(volatile unsigned char *)(pica+1)&=(~8);
- printk("*(0x10803) %02x\n",*(volatile unsigned char *)(IO_BASE+0x10803));
- printk("*(0x10803) %02x\n",*(volatile unsigned char *)(IO_BASE+0x10803));
+#if 0
+ printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3));
+ printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3));
+#endif
sched_timer_handler=timer_routine;
request_irq(0,dn_timer_int,0,NULL,NULL);
-
}
unsigned long dn_gettimeoffset(void) {
@@ -187,7 +256,6 @@ printk("gettod: %d %d %d %d %d %d\n",*yearp,*monp,*dayp,*hourp,*minp,*secp);
int dn_dummy_hwclk(int op, struct hwclk_time *t) {
- dn_serial_print("hwclk !\n");
if(!op) { /* read */
t->sec=rtc->second;
@@ -208,7 +276,6 @@ int dn_dummy_hwclk(int op, struct hwclk_time *t) {
rtc->year=t->year;
}
- dn_serial_print("hwclk end!\n");
return 0;
}
@@ -235,11 +302,25 @@ void dn_dummy_waitbut(void) {
}
-#if 0
-void dn_debug_init(void) {
-
- dn_console_driver.write=dn_serial_console_write;
- register_console(&dn_console_driver);
+static void dn_get_model(char *model)
+{
+ strcpy(model, "Apollo ");
+ if (apollo_model >= APOLLO_DN3000 && apollo_model <= APOLLO_DN4500)
+ strcat(model, apollo_models[apollo_model - APOLLO_DN3000]);
+}
+#ifdef CONFIG_HEARTBEAT
+static void dn_heartbeat(int on) {
+
+ if(on) {
+ dn_cpuctrl&=~0x100;
+ cpuctrl=dn_cpuctrl;
+ }
+ else {
+ dn_cpuctrl&=~0x100;
+ dn_cpuctrl|=0x100;
+ cpuctrl=dn_cpuctrl;
+ }
}
#endif
+
diff --git a/arch/m68k/apollo/dma.c b/arch/m68k/apollo/dma.c
new file mode 100644
index 000000000..634e4367f
--- /dev/null
+++ b/arch/m68k/apollo/dma.c
@@ -0,0 +1,49 @@
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/kd.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+
+#include <asm/setup.h>
+#include <asm/bootinfo.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/apollodma.h>
+
+/* note only works for 16 Bit 1 page DMA's */
+
+static unsigned short next_free_xlat_entry=0;
+
+unsigned short dma_map_page(unsigned long phys_addr,int count,int type) {
+
+ unsigned long page_aligned_addr=phys_addr & (~((1<<12)-1));
+ unsigned short start_map_addr=page_aligned_addr >> 10;
+ unsigned short free_xlat_entry, *xlat_map_entry;
+ int i;
+
+ free_xlat_entry=next_free_xlat_entry;
+ for(i=0,xlat_map_entry=addr_xlat_map+(free_xlat_entry<<2);i<8;i++,xlat_map_entry++) {
+#if 0
+ printk("phys_addr: %x, page_aligned_addr: %x, start_map_addr: %x\n",phys_addr,page_aligned_addr,start_map_addr+i);
+#endif
+ outw(start_map_addr+i, xlat_map_entry);
+ }
+
+ next_free_xlat_entry+=2;
+ if(next_free_xlat_entry>125)
+ next_free_xlat_entry=0;
+
+#if 0
+ printk("next_free_xlat_entry: %d\n",next_free_xlat_entry);
+#endif
+
+ return free_xlat_entry<<10;
+}
+
+void dma_unmap_page(unsigned short dma_addr) {
+
+ return ;
+
+}
+
diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c
index 18e29814e..e3a628107 100644
--- a/arch/m68k/apollo/dn_ints.c
+++ b/arch/m68k/apollo/dn_ints.c
@@ -16,30 +16,19 @@ extern void write_keyb_cmd(u_short length, u_char *cmd);
static char BellOnCommand[] = { 0xFF, 0x21, 0x81 },
BellOffCommand[] = { 0xFF, 0x21, 0x82 };
+extern void dn_serial_print (const char *str);
void dn_process_int(int irq, struct pt_regs *fp) {
-#if 0
- unsigned char x;
-#endif
-
-#if 0
- printk("Aha DN interrupt ! : %d\n",irq);
-#endif
if(dn_irqs[irq-160].handler) {
dn_irqs[irq-160].handler(irq,dn_irqs[irq-160].dev_id,fp);
}
else {
- printk("spurious irq %d occurred\n",irq);
+ printk("spurious irq %d occured\n",irq);
}
-#if 0
- printk("*(0x10803) %02x\n",*(volatile unsigned char *)(IO_BASE+0x10803));
- x=*(volatile unsigned char *)(IO_BASE+0x10805);
-#endif
-
- *(volatile unsigned char *)(IO_BASE+0x11000)=0x20;
- *(volatile unsigned char *)(IO_BASE+0x11100)=0x20;
+ *(volatile unsigned char *)(pica)=0x20;
+ *(volatile unsigned char *)(picb)=0x20;
}
@@ -47,8 +36,6 @@ void dn_init_IRQ(void) {
int i;
- printk("Init IRQ\n");
-
for(i=0;i<16;i++) {
dn_irqs[i].handler=NULL;
dn_irqs[i].flags=IRQ_FLG_STD;
@@ -60,8 +47,6 @@ void dn_init_IRQ(void) {
int dn_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) {
- printk("dn request IRQ\n");
-
if((irq<0) || (irq>15)) {
printk("Trying to request illegal IRQ\n");
return -ENXIO;
@@ -73,9 +58,10 @@ int dn_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs
dn_irqs[irq].dev_id=dev_id;
dn_irqs[irq].devname=devname;
if(irq<8)
- *(volatile unsigned char *)(IO_BASE+PICA+1)&=~(1<<irq);
+ *(volatile unsigned char *)(pica+1)&=~(1<<irq);
else
- *(volatile unsigned char *)(IO_BASE+PICB+1)&=~(1<<(irq-8));
+ *(volatile unsigned char *)(picb+1)&=~(1<<(irq-8));
+
return 0;
}
else {
@@ -87,17 +73,15 @@ int dn_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs
void dn_free_irq(unsigned int irq, void *dev_id) {
- printk("dn free irq\n");
-
if((irq<0) || (irq>15)) {
printk("Trying to free illegal IRQ\n");
return ;
}
if(irq<8)
- *(volatile unsigned char *)(IO_BASE+PICA+1)|=(1<<irq);
+ *(volatile unsigned char *)(pica+1)|=(1<<irq);
else
- *(volatile unsigned char *)(IO_BASE+PICB+1)|=(1<<(irq-8));
+ *(volatile unsigned char *)(picb+1)|=(1<<(irq-8));
dn_irqs[irq].handler=NULL;
dn_irqs[irq].flags=IRQ_FLG_STD;
diff --git a/arch/m68k/atari/Makefile b/arch/m68k/atari/Makefile
index dcd6170c6..bfc82284a 100644
--- a/arch/m68k/atari/Makefile
+++ b/arch/m68k/atari/Makefile
@@ -12,4 +12,10 @@ O_OBJS := config.o time.o debug.o atakeyb.o ataints.o stdma.o atasound.o \
joystick.o stram.o
OX_OBJS := atari_ksyms.o
+ifdef CONFIG_PCI
+ifdef CONFIG_HADES
+O_OBJS += hades-pci.o
+endif
+endif
+
include $(TOPDIR)/Rules.make
diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index 53f2c7509..3acfeff7a 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -30,6 +30,7 @@
#include <linux/console.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/ioport.h>
#include <asm/bootinfo.h>
#include <asm/setup.h>
@@ -246,6 +247,9 @@ void __init config_atari(void)
atari_debug_init();
+ ioport_resource.end = 0xFFFFFFFF; /* Change size of I/O space from 64KB
+ to 4GB. */
+
mach_sched_init = atari_sched_init;
mach_keyb_init = atari_keyb_init;
mach_kbdrate = atari_kbdrate;
@@ -508,24 +512,6 @@ void __init config_atari(void)
}
- /*
- * On the Hades map the PCI memory, I/O and configuration areas
- * (0x80000000 - 0xbfffffff).
- *
- * Settings: supervisor only, non-cacheable, serialized, read and write.
- */
-
- if (MACH_IS_HADES) {
- __asm__ __volatile__ ("movel %0,%/d0\n\t"
- ".chip 68040\n\t"
- "movec %%d0,%%itt0\n\t"
- "movec %%d0,%%dtt0\n\t"
- ".chip 68k\n\t"
- : /* no outputs */
- : "g" (0x803fa040)
- : "d0");
- }
-
/* Fetch tos version at Physical 2 */
/* We my not be able to access this address if the kernel is
loaded to st ram, since the first page is unmapped. On the
diff --git a/arch/m68k/atari/hades-pci.c b/arch/m68k/atari/hades-pci.c
new file mode 100644
index 000000000..2c82e4a7b
--- /dev/null
+++ b/arch/m68k/atari/hades-pci.c
@@ -0,0 +1,437 @@
+/*
+ * hades-pci.c - Hardware specific PCI BIOS functions the Hades Atari clone.
+ *
+ * Written by Wout Klaren.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+
+#if 0
+# define DBG_DEVS(args) printk args
+#else
+# define DBG_DEVS(args)
+#endif
+
+#if defined(CONFIG_PCI) && defined(CONFIG_HADES)
+
+#include <linux/malloc.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+
+#include <asm/atarihw.h>
+#include <asm/atariints.h>
+#include <asm/byteorder.h>
+#include <asm/pci.h>
+
+#define HADES_MEM_BASE 0x80000000
+#define HADES_MEM_SIZE 0x20000000
+#define HADES_CONFIG_BASE 0xA0000000
+#define HADES_CONFIG_SIZE 0x10000000
+#define HADES_IO_BASE 0xB0000000
+#define HADES_IO_SIZE 0x10000000
+#define HADES_VIRT_IO_SIZE 0x00010000 /* Only 64k is remapped and actually used. */
+
+#define N_SLOTS 4 /* Number of PCI slots. */
+
+static const char pci_mem_name[] = "PCI memory space";
+static const char pci_io_name[] = "PCI I/O space";
+static const char pci_config_name[] = "PCI config space";
+
+static struct resource config_space = { pci_config_name, HADES_CONFIG_BASE,
+ HADES_CONFIG_BASE + HADES_CONFIG_SIZE - 1 };
+static struct resource io_space = { pci_io_name, HADES_IO_BASE, HADES_IO_BASE +
+ HADES_IO_SIZE - 1 };
+
+static const unsigned long pci_conf_base_phys[] = { 0xA0080000, 0xA0040000,
+ 0xA0020000, 0xA0010000 };
+static unsigned long pci_conf_base_virt[N_SLOTS];
+static unsigned long pci_io_base_virt;
+
+/*
+ * static void *mk_conf_addr(unsigned char bus, unsigned char device_fn,
+ * unsigned char where)
+ *
+ * Calculate the address of the PCI configuration area of the given
+ * device.
+ *
+ * BUG: boards with multiple functions are probably not correctly
+ * supported.
+ */
+
+static void *mk_conf_addr(struct pci_dev *dev, int where)
+{
+ int device = dev->devfn >> 3, function = dev->devfn & 7;
+ void *result;
+
+ DBG_DEVS(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p)\n",
+ dev->bus->number, dev->devfn, where, pci_addr));
+
+ if (device > 3)
+ {
+ DBG_DEVS(("mk_conf_addr: device (%d) > 3, returning NULL\n", device));
+ return NULL;
+ }
+
+ if (dev->bus->number != 0)
+ {
+ DBG_DEVS(("mk_conf_addr: bus (%d) > 0, returning NULL\n", device));
+ return NULL;
+ }
+
+ result = (void *) (pci_conf_base_virt[device] | (function << 8) | (where));
+ DBG_DEVS(("mk_conf_addr: returning pci_addr 0x%lx\n", (unsigned long) result));
+ return result;
+}
+
+static int hades_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+ volatile unsigned char *pci_addr;
+
+ *value = 0xff;
+
+ if ((pci_addr = (unsigned char *) mk_conf_addr(dev, where)) == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = *pci_addr;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int hades_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+ volatile unsigned short *pci_addr;
+
+ *value = 0xffff;
+
+ if (where & 0x1)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if ((pci_addr = (unsigned short *) mk_conf_addr(dev, where)) == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = le16_to_cpu(*pci_addr);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int hades_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+ volatile unsigned int *pci_addr;
+ unsigned char header_type;
+ int result;
+
+ *value = 0xffffffff;
+
+ if (where & 0x3)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if ((pci_addr = (unsigned int *) mk_conf_addr(dev, where)) == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = le32_to_cpu(*pci_addr);
+
+ /*
+ * Check if the value is an address on the bus. If true, add the
+ * base address of the PCI memory or PCI I/O area on the Hades.
+ */
+
+ if ((result = hades_read_config_byte(dev, PCI_HEADER_TYPE,
+ &header_type)) != PCIBIOS_SUCCESSFUL)
+ return result;
+
+ if (((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_1)) ||
+ ((header_type != PCI_HEADER_TYPE_BRIDGE) && ((where >= PCI_BASE_ADDRESS_2) &&
+ (where <= PCI_BASE_ADDRESS_5))))
+ {
+ if ((*value & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
+ {
+ /*
+ * Base address register that contains an I/O address. If the
+ * address is valid on the Hades (0 <= *value < HADES_VIRT_IO_SIZE),
+ * add 'pci_io_base_virt' to the value.
+ */
+
+ if (*value < HADES_VIRT_IO_SIZE)
+ *value += pci_io_base_virt;
+ }
+ else
+ {
+ /*
+ * Base address register that contains an memory address. If the
+ * address is valid on the Hades (0 <= *value < HADES_MEM_SIZE),
+ * add HADES_MEM_BASE to the value.
+ */
+
+ if (*value == 0)
+ {
+ /*
+ * Base address is 0. Test if this base
+ * address register is used.
+ */
+
+ *pci_addr = 0xffffffff;
+ if (*pci_addr != 0)
+ {
+ *pci_addr = *value;
+ if (*value < HADES_MEM_SIZE)
+ *value += HADES_MEM_BASE;
+ }
+ }
+ else
+ {
+ if (*value < HADES_MEM_SIZE)
+ *value += HADES_MEM_BASE;
+ }
+ }
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int hades_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+ volatile unsigned char *pci_addr;
+
+ if ((pci_addr = (unsigned char *) mk_conf_addr(dev, where)) == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *pci_addr = value;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int hades_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+ volatile unsigned short *pci_addr;
+
+ if ((pci_addr = (unsigned short *) mk_conf_addr(dev, where)) == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *pci_addr = cpu_to_le16(value);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int hades_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+ volatile unsigned int *pci_addr;
+ unsigned char header_type;
+ int result;
+
+ if ((pci_addr = (unsigned int *) mk_conf_addr(dev, where)) == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ /*
+ * Check if the value is an address on the bus. If true, subtract the
+ * base address of the PCI memory or PCI I/O area on the Hades.
+ */
+
+ if ((result = hades_read_config_byte(dev, PCI_HEADER_TYPE,
+ &header_type)) != PCIBIOS_SUCCESSFUL)
+ return result;
+
+ if (((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_1)) ||
+ ((header_type != PCI_HEADER_TYPE_BRIDGE) && ((where >= PCI_BASE_ADDRESS_2) &&
+ (where <= PCI_BASE_ADDRESS_5))))
+ {
+ if ((value & PCI_BASE_ADDRESS_SPACE) ==
+ PCI_BASE_ADDRESS_SPACE_IO)
+ {
+ /*
+ * I/O address. Check if the address is valid address on
+ * the Hades (pci_io_base_virt <= value < pci_io_base_virt +
+ * HADES_VIRT_IO_SIZE) or if the value is 0xffffffff. If not
+ * true do not write the base address register. If it is a
+ * valid base address subtract 'pci_io_base_virt' from the value.
+ */
+
+ if ((value >= pci_io_base_virt) && (value < (pci_io_base_virt +
+ HADES_VIRT_IO_SIZE)))
+ value -= pci_io_base_virt;
+ else
+ {
+ if (value != 0xffffffff)
+ return PCIBIOS_SET_FAILED;
+ }
+ }
+ else
+ {
+ /*
+ * Memory address. Check if the address is valid address on
+ * the Hades (HADES_MEM_BASE <= value < HADES_MEM_BASE + HADES_MEM_SIZE) or
+ * if the value is 0xffffffff. If not true do not write
+ * the base address register. If it is a valid base address
+ * subtract HADES_MEM_BASE from the value.
+ */
+
+ if ((value >= HADES_MEM_BASE) && (value < (HADES_MEM_BASE + HADES_MEM_SIZE)))
+ value -= HADES_MEM_BASE;
+ else
+ {
+ if (value != 0xffffffff)
+ return PCIBIOS_SET_FAILED;
+ }
+ }
+ }
+
+ *pci_addr = cpu_to_le32(value);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * static inline void hades_fixup(void)
+ *
+ * Assign IRQ numbers as used by Linux to the interrupt pins
+ * of the PCI cards.
+ */
+
+static void __init hades_fixup(int pci_modify)
+{
+ char irq_tab[4] = {
+ IRQ_TT_MFP_IO0, /* Slot 0. */
+ IRQ_TT_MFP_IO1, /* Slot 1. */
+ IRQ_TT_MFP_SCC, /* Slot 2. */
+ IRQ_TT_MFP_SCSIDMA /* Slot 3. */
+ };
+ struct pci_dev *dev;
+ unsigned char slot;
+
+ /*
+ * Go through all devices, fixing up irqs as we see fit:
+ */
+
+ for (dev = pci_devices; dev; dev = dev->next)
+ {
+ if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE)
+ {
+ slot = PCI_SLOT(dev->devfn); /* Determine slot number. */
+ dev->irq = irq_tab[slot];
+ if (pci_modify)
+ pcibios_write_config_byte(dev->bus->number, dev->devfn,
+ PCI_INTERRUPT_LINE, dev->irq);
+ }
+ }
+}
+
+/*
+ * static void hades_conf_device(unsigned char bus, unsigned char device_fn)
+ *
+ * Machine dependent Configure the given device.
+ *
+ * Parameters:
+ *
+ * bus - bus number of the device.
+ * device_fn - device and function number of the device.
+ */
+
+static void __init hades_conf_device(unsigned char bus, unsigned char device_fn)
+{
+ pcibios_write_config_byte(bus, device_fn, PCI_CACHE_LINE_SIZE, 0);
+}
+
+static struct pci_ops hades_pci_ops = {
+ read_byte: hades_read_config_byte
+ read_word: hades_read_config_word
+ read_dword: hades_read_config_dword
+ write_byte: hades_write_config_byte
+ write_word: hades_write_config_word
+ write_dword: hades_write_config_dword
+};
+
+/*
+ * struct pci_bus_info *init_hades_pci(void)
+ *
+ * Machine specific initialisation:
+ *
+ * - Allocate and initialise a 'pci_bus_info' structure
+ * - Initialise hardware
+ *
+ * Result: pointer to 'pci_bus_info' structure.
+ */
+
+struct pci_bus_info * __init init_hades_pci(void)
+{
+ struct pci_bus_info *bus;
+ int i;
+
+ /*
+ * Remap I/O and configuration space.
+ */
+
+ pci_io_base_virt = (unsigned long) ioremap(HADES_IO_BASE, HADES_VIRT_IO_SIZE);
+
+ for (i = 0; i < N_SLOTS; i++)
+ pci_conf_base_virt[i] = (unsigned long) ioremap(pci_conf_base_phys[i], 0x10000);
+
+ /*
+ * Allocate memory for bus info structure.
+ */
+
+ bus = kmalloc(sizeof(struct pci_bus_info), GFP_KERNEL);
+ memset(bus, 0, sizeof(struct pci_bus_info));
+
+ /*
+ * Claim resources. The m68k has no seperate I/O space, both
+ * PCI memory space and PCI I/O space are in memory space. Therefore
+ * the I/O resources are requested in memory space as well.
+ */
+
+ if (request_resource(&iomem_resource, &config_space) != 0)
+ {
+ kfree(bus);
+ return NULL;
+ }
+
+ if (request_resource(&iomem_resource, &io_space) != 0)
+ {
+ release_resource(&config_space);
+ kfree(bus);
+ return NULL;
+ }
+
+ bus->mem_space.start = HADES_MEM_BASE;
+ bus->mem_space.end = HADES_MEM_BASE + HADES_MEM_SIZE - 1;
+ bus->mem_space.name = pci_mem_name;
+#if 1
+ if (request_resource(&iomem_resource, &bus->mem_space) != 0)
+ {
+ release_resource(&io_space);
+ release_resource(&config_space);
+ kfree(bus);
+ return NULL;
+ }
+#endif
+ bus->io_space.start = pci_io_base_virt;
+ bus->io_space.end = pci_io_base_virt + HADES_VIRT_IO_SIZE - 1;
+ bus->io_space.name = pci_io_name;
+#if 1
+ if (request_resource(&ioport_resource, &bus->io_space) != 0)
+ {
+ release_resource(&bus->mem_space);
+ release_resource(&io_space);
+ release_resource(&config_space);
+ kfree(bus);
+ return NULL;
+ }
+#endif
+ /*
+ * Set hardware dependent functions.
+ */
+
+ bus->m68k_pci_ops = &hades_pci_ops;
+ bus->fixup = hades_fixup;
+ bus->conf_device = hades_conf_device;
+
+ /*
+ * Select high to low edge for PCI interrupts.
+ */
+
+ tt_mfp.active_edge &= ~0x27;
+
+ return bus;
+}
+#endif
diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
index cbccf3956..77053421e 100644
--- a/arch/m68k/atari/stram.c
+++ b/arch/m68k/atari/stram.c
@@ -715,7 +715,7 @@ static inline void unswap_pte(struct vm_area_struct * vma, unsigned long
else {
DPRINTK( "unswap_pte: replacing entry %08lx by new page %08lx",
entry, page );
- set_pte(dir, pte_mkdirty(mk_pte(page,vma->vm_page_prot)));
+ set_pte(dir, pte_mkdirty(__mk_pte(page,vma->vm_page_prot)));
atomic_inc(&mem_map[MAP_NR(page)].count);
++vma->vm_mm->rss;
}
diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c
index dabb9bcf8..bbe808d3f 100644
--- a/arch/m68k/bvme6000/config.c
+++ b/arch/m68k/bvme6000/config.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/major.h>
+#include <asm/bootinfo.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/setup.h>
@@ -63,6 +64,15 @@ static unsigned char bin2bcd (unsigned char b);
static void (*tick_handler)(int, void *, struct pt_regs *);
+
+int bvme6000_parse_bootinfo(const struct bi_record *bi)
+{
+ if (bi->tag == BI_VME_TYPE)
+ return 0;
+ else
+ return 1;
+}
+
int bvme6000_kbdrate (struct kbd_repeat *k)
{
return 0;
@@ -107,6 +117,13 @@ void __init config_bvme6000(void)
{
volatile PitRegsPtr pit = (PitRegsPtr)BVME_PIT_BASE;
+ /* Board type is only set by newer versions of vmelilo/tftplilo */
+ if (!vme_brdtype) {
+ if (m68k_cputype == CPU_68060)
+ vme_brdtype = VME_TYPE_BVME6000;
+ else
+ vme_brdtype = VME_TYPE_BVME4000;
+ }
#if 0
/* Call bvme6000_set_vectors() so ABORT will work, along with BVMBug
* debugger. Note trap_init() will splat the abort vector, but
diff --git a/arch/m68k/bvme6000/rtc.c b/arch/m68k/bvme6000/rtc.c
index f1ad19b0c..282a2871d 100644
--- a/arch/m68k/bvme6000/rtc.c
+++ b/arch/m68k/bvme6000/rtc.c
@@ -71,8 +71,9 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
}
case RTC_SET_TIME: /* Set the RTC */
{
- unsigned char leap_yr;
struct rtc_time rtc_tm;
+ unsigned char mon, day, hrs, min, sec, leap_yr;
+ unsigned int yrs;
if (!suser())
return -EACCES;
@@ -81,34 +82,46 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
sizeof(struct rtc_time)))
return -EFAULT;
- leap_yr = ((!(rtc_tm.tm_year % 4) && (rtc_tm.tm_year % 100)) || !(rtc_tm.tm_year % 400));
+ yrs = rtc_tm.tm_year;
+ if (yrs < 1900)
+ yrs += 1900;
+ mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */
+ day = rtc_tm.tm_mday;
+ hrs = rtc_tm.tm_hour;
+ min = rtc_tm.tm_min;
+ sec = rtc_tm.tm_sec;
- if ((rtc_tm.tm_mon > 12) || (rtc_tm.tm_mday == 0))
+ leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
+
+ if ((mon > 12) || (day == 0))
return -EINVAL;
- if (rtc_tm.tm_mday > (days_in_mo[rtc_tm.tm_mon] + ((rtc_tm.tm_mon == 2) && leap_yr)))
+ if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
return -EINVAL;
-
- if ((rtc_tm.tm_hour >= 24) || (rtc_tm.tm_min >= 60) || (rtc_tm.tm_sec >= 60))
+
+ if ((hrs >= 24) || (min >= 60) || (sec >= 60))
return -EINVAL;
+ if (yrs >= 2070)
+ return -EINVAL;
+
save_flags(flags);
cli();
/* Ensure clock and real-time-mode-register are accessible */
msr = rtc->msr & 0xc0;
rtc->msr = 0x40;
- rtc->t0cr_rtmr = rtc_tm.tm_year%4;
+ rtc->t0cr_rtmr = yrs%4;
rtc->bcd_tenms = 0;
- rtc->bcd_sec = BIN2BCD(rtc_tm.tm_sec);
- rtc->bcd_min = BIN2BCD(rtc_tm.tm_min);
- rtc->bcd_hr = BIN2BCD(rtc_tm.tm_hour);
- rtc->bcd_dom = BIN2BCD(rtc_tm.tm_mday);
- rtc->bcd_mth = BIN2BCD(rtc_tm.tm_mon + 1);
- rtc->bcd_year = BIN2BCD(rtc_tm.tm_year%100);
+ rtc->bcd_sec = BIN2BCD(sec);
+ rtc->bcd_min = BIN2BCD(min);
+ rtc->bcd_hr = BIN2BCD(hrs);
+ rtc->bcd_dom = BIN2BCD(day);
+ rtc->bcd_mth = BIN2BCD(mon);
+ rtc->bcd_year = BIN2BCD(yrs%100);
if (rtc_tm.tm_wday >= 0)
rtc->bcd_dow = BIN2BCD(rtc_tm.tm_wday+1);
- rtc->t0cr_rtmr = rtc_tm.tm_year%4 | 0x08;
+ rtc->t0cr_rtmr = yrs%4 | 0x08;
rtc->msr = msr;
restore_flags(flags);
diff --git a/arch/m68k/config.in b/arch/m68k/config.in
index 52a083750..ce8260504 100644
--- a/arch/m68k/config.in
+++ b/arch/m68k/config.in
@@ -23,6 +23,9 @@ if [ "$CONFIG_ATARI" = "y" ]; then
define_bool CONFIG_PCI y
fi
fi
+if [ "$CONFIG_HADES" != "y" ]; then
+ define_bool CONFIG_PCI n
+fi
bool 'Macintosh support' CONFIG_MAC
if [ "$CONFIG_MAC" = "y" ]; then
define_bool CONFIG_NUBUS y
@@ -127,7 +130,9 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
fi
fi
-source drivers/pci/Config.in
+if [ "$CONFIG_PCI" = "y" ]; then
+ source drivers/pci/Config.in
+fi
endmenu
@@ -192,7 +197,7 @@ if [ "$CONFIG_SCSI" != "n" ]; then
bool 'WarpEngine SCSI support (EXPERIMENTAL)' CONFIG_WARPENGINE_SCSI
bool 'Blizzard PowerUP 603e+ SCSI (EXPERIMENTAL)' CONFIG_BLZ603EPLUS_SCSI
dep_tristate 'BSC Oktagon SCSI support (EXPERIMENTAL)' CONFIG_OKTAGON_SCSI $CONFIG_SCSI
- bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI
+# bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI
# bool 'GVP Turbo 040/060 SCSI support (EXPERIMENTAL)' CONFIG_GVP_TURBO_SCSI
fi
fi
@@ -201,8 +206,8 @@ if [ "$CONFIG_SCSI" != "n" ]; then
if [ "$CONFIG_ATARI_SCSI" != "n" ]; then
bool ' Long delays for Toshiba CD-ROMs' CONFIG_ATARI_SCSI_TOSHIBA_DELAY
bool ' Reset SCSI-devices at boottime' CONFIG_ATARI_SCSI_RESET_BOOT
- if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_HADES" = "y" ]; then
- bool ' Hades SCSI DMA emulator (EXPERIMENTAL)' CONFIG_TT_DMA_EMUL
+ if [ "$CONFIG_HADES" = "y" ]; then
+ bool ' Hades SCSI DMA emulator' CONFIG_TT_DMA_EMUL
fi
fi
fi
@@ -469,5 +474,4 @@ comment 'Kernel hacking'
#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
-bool 'Remote debugging support' CONFIG_KGDB
endmenu
diff --git a/arch/m68k/defconfig b/arch/m68k/defconfig
index b88a48984..cbea6ba63 100644
--- a/arch/m68k/defconfig
+++ b/arch/m68k/defconfig
@@ -197,6 +197,7 @@ CONFIG_NFS_FS=y
# CONFIG_AFFS_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_CRAMFS is not set
#
# Frame buffer devices
diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile
index 3d2000724..6d10ca35f 100644
--- a/arch/m68k/kernel/Makefile
+++ b/arch/m68k/kernel/Makefile
@@ -21,10 +21,6 @@ O_OBJS := entry.o process.o traps.o ints.o signal.o ptrace.o \
sys_m68k.o time.o semaphore.o
OX_OBJS := setup.o m68k_ksyms.o
-ifdef CONFIG_KGDB
-O_OBJS += kgdb.o
-endif
-
ifdef CONFIG_PCI
O_OBJS += bios32.o
endif
diff --git a/arch/m68k/kernel/bios32.c b/arch/m68k/kernel/bios32.c
index 082fda543..c3b5dacba 100644
--- a/arch/m68k/kernel/bios32.c
+++ b/arch/m68k/kernel/bios32.c
@@ -1,6 +1,5 @@
/*
- * bios32.c - PCI BIOS functions for Alpha systems not using BIOS
- * emulation code.
+ * bios32.c - PCI BIOS functions for m68k systems.
*
* Written by Wout Klaren.
*
@@ -22,25 +21,16 @@
/*
* PCI support for Linux/m68k. Currently only the Hades is supported.
*
- * Notes:
- *
- * 1. The PCI memory area starts at address 0x80000000 and the
- * I/O area starts at 0xB0000000. Therefore these offsets
- * are added to the base addresses when they are read and
- * substracted when they are written.
- *
- * 2. The support for PCI bridges in the DEC Alpha version has
- * been removed in this version.
+ * The support for PCI bridges in the DEC Alpha version has
+ * been removed in this version.
*/
#include <linux/pci.h>
#include <linux/malloc.h>
#include <linux/mm.h>
-#include <asm/atarihw.h>
-#include <asm/atariints.h>
-#include <asm/byteorder.h>
#include <asm/io.h>
+#include <asm/pci.h>
#include <asm/uaccess.h>
#define KB 1024
@@ -48,14 +38,7 @@
#define GB (1024*MB)
#define MAJOR_REV 0
-#define MINOR_REV 1
-
-/*
- * Base addresses of the PCI memory and I/O areas on the Hades.
- */
-
-static unsigned long pci_mem_base = 0;
-static unsigned long pci_io_base = 0;
+#define MINOR_REV 5
/*
* Align VAL to ALIGN, which must be a power of two.
@@ -63,181 +46,51 @@ static unsigned long pci_io_base = 0;
#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1))
+#define MAX(val1, val2) (((val1) > (val2)) ? val1 : val2)
+
/*
- * Calculate the address of the PCI configuration area of the given
- * device.
- *
- * BUG: boards with multiple functions are probably not correctly
- * supported.
+ * Offsets relative to the I/O and memory base addresses from where resources
+ * are allocated.
*/
-static int mk_conf_addr(unsigned char bus, unsigned char device_fn,
- unsigned char where, unsigned long *pci_addr)
-{
- static const unsigned long pci_conf_base[] = { 0xA0080000, 0xA0040000,
- 0xA0020000, 0xA0010000 };
- int device = device_fn >> 3;
-
- DBG_DEVS(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p)\n",
- bus, device_fn, where, pci_addr));
-
- if (device > 3) {
- DBG_DEVS(("mk_conf_addr: device (%d) > 3, returning -1\n", device));
- return -1;
- }
-
- *pci_addr = pci_conf_base[device] | (where);
- DBG_DEVS(("mk_conf_addr: returning pci_addr 0x%lx\n", *pci_addr));
- return 0;
-}
-
-int pcibios_read_config_byte(unsigned char bus, unsigned char device_fn,
- unsigned char where, unsigned char *value)
-{
- unsigned long pci_addr;
-
- *value = 0xff;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- *value = *((unsigned char *)pci_addr);
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-int pcibios_read_config_word(unsigned char bus, unsigned char device_fn,
- unsigned char where, unsigned short *value)
-{
- unsigned long pci_addr;
-
- *value = 0xffff;
-
- if (where & 0x1)
- return PCIBIOS_BAD_REGISTER_NUMBER;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- *value = le16_to_cpu(*((unsigned short *)pci_addr));
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-int pcibios_read_config_dword(unsigned char bus, unsigned char device_fn,
- unsigned char where, unsigned int *value)
-{
- unsigned long pci_addr;
-
- *value = 0xffffffff;
-
- if (where & 0x3)
- return PCIBIOS_BAD_REGISTER_NUMBER;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr))
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- *value = le32_to_cpu(*((unsigned int *)pci_addr));
-
- if ((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_5))
- {
- if ((*value & PCI_BASE_ADDRESS_SPACE) ==
- PCI_BASE_ADDRESS_SPACE_IO)
- *value += pci_io_base;
- else
- {
- if (*value == 0)
- {
- /*
- * Base address is 0. Test if this base
- * address register is used.
- */
-
- *((unsigned long *)pci_addr) = 0xffffffff;
- if (*((unsigned long *)pci_addr) != 0)
- *value += pci_mem_base;
- }
- else
- *value += pci_mem_base;
- }
- }
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-int pcibios_write_config_byte(unsigned char bus, unsigned char device_fn,
- unsigned char where, unsigned char value)
-{
- unsigned long pci_addr;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- *((unsigned char *)pci_addr) = value;
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-int pcibios_write_config_word(unsigned char bus, unsigned char device_fn,
- unsigned char where, unsigned short value)
-{
- unsigned long pci_addr;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- *((unsigned short *)pci_addr) = cpu_to_le16(value);
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-int pcibios_write_config_dword(unsigned char bus, unsigned char device_fn,
- unsigned char where, unsigned int value)
-{
- unsigned long pci_addr;
-
- if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- if ((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_5))
- {
- if ((value & PCI_BASE_ADDRESS_SPACE) ==
- PCI_BASE_ADDRESS_SPACE_IO)
- value -= pci_io_base;
- else
- value -= pci_mem_base;
- }
-
- *((unsigned int *)pci_addr) = cpu_to_le32(value);
-
- return PCIBIOS_SUCCESSFUL;
-}
+#define IO_ALLOC_OFFSET 0x00004000
+#define MEM_ALLOC_OFFSET 0x04000000
/*
- * Macro to enable programming of the PCI devices. On the Hades this
- * define should be true, because the Hades has no PCI BIOS.
+ * Declarations of hardware specific initialisation functions.
*/
-#define PCI_MODIFY 1
-
-#if PCI_MODIFY
+extern struct pci_bus_info *init_hades_pci(void);
/*
- * Leave some room for a VGA card. We assume that the VGA card is
- * always in the first 32M of PCI memory. For the time being we do
- * not program the VGA card, because to make this work we also
- * need to change the frame buffer device.
+ * Bus info structure of the PCI bus. A pointer to this structure is
+ * put in the sysdata member of the pci_bus structure.
*/
-#define FIRST_IO_ADDR 0x10000
-#define FIRST_MEM_ADDR 0x02000000
+static struct pci_bus_info *bus_info;
-static unsigned int io_base = FIRST_IO_ADDR; /* Skip first 64K. */
-static unsigned int mem_base = FIRST_MEM_ADDR; /* Skip first 32M. */
+static int pci_modify = 1; /* If set, layout the PCI bus ourself. */
+static int skip_vga = 0; /* If set do not modify base addresses
+ of vga cards.*/
+static int disable_pci_burst = 0; /* If set do not allow PCI bursts. */
+
+static unsigned int io_base;
+static unsigned int mem_base;
+
+struct pci_fixup pcibios_fixups[] =
+{
+ { 0 }
+};
/*
+ * static void disable_dev(struct pci_dev *dev)
+ *
* Disable PCI device DEV so that it does not respond to I/O or memory
* accesses.
+ *
+ * Parameters:
+ *
+ * dev - device to disable.
*/
static void __init disable_dev(struct pci_dev *dev)
@@ -245,9 +98,9 @@ static void __init disable_dev(struct pci_dev *dev)
struct pci_bus *bus;
unsigned short cmd;
- if (dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA ||
- dev->class >> 8 == PCI_CLASS_DISPLAY_VGA ||
- dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)
+ if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) ||
+ (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) ||
+ (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga)
return;
bus = dev->bus;
@@ -258,13 +111,16 @@ static void __init disable_dev(struct pci_dev *dev)
}
/*
- * Layout memory and I/O for a device:
+ * static void layout_dev(struct pci_dev *dev)
+ *
+ * Layout memory and I/O for a device.
+ *
+ * Parameters:
+ *
+ * device - device to layout memory and I/O for.
*/
-#define MAX(val1, val2) ( ((val1) > (val2)) ? val1 : val2)
-
-static void __init layout_dev(struct pci_dev *dev, unsigned long pci_mem_base,
- unsigned long pci_io_base)
+static void __init layout_dev(struct pci_dev *dev)
{
struct pci_bus *bus;
unsigned short cmd;
@@ -273,12 +129,12 @@ static void __init layout_dev(struct pci_dev *dev, unsigned long pci_mem_base,
int i;
/*
- * Skip video cards for the time being.
+ * Skip video cards if requested.
*/
- if (dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA ||
- dev->class >> 8 == PCI_CLASS_DISPLAY_VGA ||
- dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)
+ if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) ||
+ (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) ||
+ (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga)
return;
bus = dev->bus;
@@ -298,7 +154,9 @@ static void __init layout_dev(struct pci_dev *dev, unsigned long pci_mem_base,
if (!base)
{
/* this base-address register is unused */
- dev->base_address[i] = 0;
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
continue;
}
@@ -318,13 +176,21 @@ static void __init layout_dev(struct pci_dev *dev, unsigned long pci_mem_base,
base &= PCI_BASE_ADDRESS_IO_MASK;
mask = (~base << 1) | 0x1;
size = (mask & base) & 0xffffffff;
- /* align to multiple of size of minimum base */
- alignto = MAX(0x400, size) ;
+
+ /*
+ * Align to multiple of size of minimum base.
+ */
+
+ alignto = MAX(0x040, size) ;
base = ALIGN(io_base, alignto);
io_base = base + size;
pcibios_write_config_dword(bus->number, dev->devfn,
- reg, base | 0x1);
- dev->base_address[i] = (pci_io_base + base) | 1;
+ reg, base | PCI_BASE_ADDRESS_SPACE_IO);
+
+ dev->resource[i].start = base;
+ dev->resource[i].end = dev->resource[i].start + size - 1;
+ dev->resource[i].flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
+
DBG_DEVS(("layout_dev: IO address: %lX\n", base));
}
else
@@ -343,16 +209,8 @@ static void __init layout_dev(struct pci_dev *dev, unsigned long pci_mem_base,
switch (type)
{
case PCI_BASE_ADDRESS_MEM_TYPE_32:
- break;
-
case PCI_BASE_ADDRESS_MEM_TYPE_64:
- printk("bios32 WARNING: "
- "ignoring 64-bit device in "
- "slot %d, function %d: \n",
- PCI_SLOT(dev->devfn),
- PCI_FUNC(dev->devfn));
- reg += 4; /* skip extra 4 bytes */
- continue;
+ break;
case PCI_BASE_ADDRESS_MEM_TYPE_1M:
printk("bios32 WARNING: slot %d, function %d "
@@ -364,7 +222,7 @@ static void __init layout_dev(struct pci_dev *dev, unsigned long pci_mem_base,
}
/*
- * Align to multiple of size of minimum base
+ * Align to multiple of size of minimum base.
*/
alignto = MAX(0x1000, size) ;
@@ -372,7 +230,27 @@ static void __init layout_dev(struct pci_dev *dev, unsigned long pci_mem_base,
mem_base = base + size;
pcibios_write_config_dword(bus->number, dev->devfn,
reg, base);
- dev->base_address[i] = pci_mem_base + base;
+
+ dev->resource[i].start = base;
+ dev->resource[i].end = dev->resource[i].start + size - 1;
+ dev->resource[i].flags = IORESOURCE_MEM;
+
+ if (type == PCI_BASE_ADDRESS_MEM_TYPE_64)
+ {
+ /*
+ * 64-bit address, set the highest 32 bits
+ * to zero.
+ */
+
+ reg += 4;
+ pcibios_write_config_dword(bus->number, dev->devfn,
+ reg, 0);
+
+ i++;
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ }
}
}
@@ -396,13 +274,30 @@ static void __init layout_dev(struct pci_dev *dev, unsigned long pci_mem_base,
pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND,
cmd | PCI_COMMAND_MASTER);
+
+ pcibios_write_config_byte(bus->number, dev->devfn, PCI_LATENCY_TIMER,
+ (disable_pci_burst) ? 0 : 32);
+
+ if (bus_info != NULL)
+ bus_info->conf_device(bus->number, dev->devfn); /* Machine dependent configuration. */
+
DBG_DEVS(("layout_dev: bus %d slot 0x%x VID 0x%x DID 0x%x class 0x%x\n",
bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device, dev->class));
}
-static void __init layout_bus(struct pci_bus *bus, unsigned long pci_mem_base,
- unsigned long pci_io_base)
+/*
+ * static void layout_bus(struct pci_bus *bus)
+ *
+ * Layout memory and I/O for all devices on the given bus.
+ *
+ * Parameters:
+ *
+ * bus - bus.
+ */
+
+static void __init layout_bus(struct pci_bus *bus)
{
+ unsigned int bio, bmem;
struct pci_dev *dev;
DBG_DEVS(("layout_bus: starting bus %d\n", bus->number));
@@ -415,22 +310,25 @@ static void __init layout_bus(struct pci_bus *bus, unsigned long pci_mem_base,
* IO and 1MB for memory).
*/
- io_base = ALIGN(io_base, 4*KB);
- mem_base = ALIGN(mem_base, 1*MB);
+ bio = io_base = ALIGN(io_base, 4*KB);
+ bmem = mem_base = ALIGN(mem_base, 1*MB);
/*
* PCI devices might have been setup by a PCI BIOS emulation
* running under TOS. In these cases there is a
* window during which two devices may have an overlapping
- * address range. To avoid this causing trouble, we first
+ * address range. To avoid this causing trouble, we first
* turn off the I/O and memory address decoders for all PCI
* devices. They'll be re-enabled only once all address
* decoders are programmed consistently.
*/
+ DBG_DEVS(("layout_bus: disable_dev for bus %d\n", bus->number));
+
for (dev = bus->devices; dev; dev = dev->sibling)
{
- if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE)
+ if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) ||
+ (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA))
disable_dev(dev);
}
@@ -442,94 +340,193 @@ static void __init layout_bus(struct pci_bus *bus, unsigned long pci_mem_base,
for (dev = bus->devices; dev; dev = dev->sibling)
{
- if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE)
- layout_dev(dev, pci_mem_base, pci_io_base);
+ if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) ||
+ (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA))
+ layout_dev(dev);
}
+
+ DBG_DEVS(("layout_bus: bus %d finished\n", bus->number));
}
-#endif /* !PCI_MODIFY */
+/*
+ * static void pcibios_fixup(void)
+ *
+ * Layout memory and I/O of all devices on the PCI bus if 'pci_modify' is
+ * true. This might be necessary because not every m68k machine with a PCI
+ * bus has a PCI BIOS. This function should be called right after
+ * pci_scan_bus() in pcibios_init().
+ */
-void __init pcibios_init(void)
+static void __init pcibios_fixup(void)
{
- printk("Linux/m68k PCI BIOS32 revision %x.%02x\n", MAJOR_REV, MINOR_REV);
+ if (pci_modify)
+ {
+ /*
+ * Set base addresses for allocation of I/O and memory space.
+ */
-#if !PCI_MODIFY
- printk("...NOT modifying existing PCI configuration\n");
-#endif
+ io_base = bus_info->io_space.start + IO_ALLOC_OFFSET;
+ mem_base = bus_info->mem_space.start + MEM_ALLOC_OFFSET;
- pci_mem_base = 0x80000000;
- pci_io_base = 0xB0000000;
+ /*
+ * Scan the tree, allocating PCI memory and I/O space.
+ */
+
+ layout_bus(pci_bus_b(pci_root.next));
+ }
+
+ /*
+ * Fix interrupt assignments, etc.
+ */
+
+ bus_info->fixup(pci_modify);
}
/*
- * static inline void hades_fixup(void)
+ * static void pcibios_claim_resources(struct pci_bus *bus)
+ *
+ * Claim all resources that are assigned to devices on the given bus.
*
- * Assign IRQ numbers as used by Linux to the interrupt pins
- * of the PCI cards.
+ * Parameters:
+ *
+ * bus - bus.
*/
-static inline void __init hades_fixup(void)
+static void __init pcibios_claim_resources(struct pci_bus *bus)
{
- char irq_tab[4] = {
- IRQ_TT_MFP_IO0, /* Slot 0. */
- IRQ_TT_MFP_IO1, /* Slot 1. */
- IRQ_TT_MFP_SCC, /* Slot 2. */
- IRQ_TT_MFP_SCSIDMA /* Slot 3. */
- };
struct pci_dev *dev;
- unsigned char slot;
-
- /*
- * Go through all devices, fixing up irqs as we see fit:
- */
+ int i;
- for (dev = pci_devices; dev; dev = dev->next)
+ while (bus)
{
- if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE)
+ for (dev = bus->devices; (dev != NULL); dev = dev->sibling)
{
- slot = PCI_SLOT(dev->devfn); /* Determine slot number. */
- dev->irq = irq_tab[slot];
-#if PCI_MODIFY
- pcibios_write_config_byte(dev->bus->number, dev->devfn,
- PCI_INTERRUPT_LINE, dev->irq);
+ for (i = 0; i < PCI_NUM_RESOURCES; i++)
+ {
+ struct resource *r = &dev->resource[i];
+ struct resource *pr;
+ struct pci_bus_info *bus_info = (struct pci_bus_info *) dev->sysdata;
+
+ if ((r->start == 0) || (r->parent != NULL))
+ continue;
+#if 1
+ if (r->flags & IORESOURCE_IO)
+ pr = &bus_info->io_space;
+ else
+ pr = &bus_info->mem_space;
+#else
+ if (r->flags & IORESOURCE_IO)
+ pr = &ioport_resource;
+ else
+ pr = &iomem_resource;
#endif
+ if (request_resource(pr, r) < 0)
+ {
+ printk(KERN_ERR "PCI: Address space collision on region %d of device %s\n", i, dev->name);
+ }
+ }
}
+
+ if (bus->children)
+ pcibios_claim_resources(bus->children);
+
+ bus = bus->next;
}
}
-void __init pcibios_fixup(void)
+/*
+ * int pcibios_assign_resource(struct pci_dev *dev, int i)
+ *
+ * Assign a new address to a PCI resource.
+ *
+ * Parameters:
+ *
+ * dev - device.
+ * i - resource.
+ *
+ * Result: 0 if successfull.
+ */
+
+int __init pcibios_assign_resource(struct pci_dev *dev, int i)
{
-#if PCI_MODIFY
- unsigned long orig_mem_base, orig_io_base;
+ struct resource *r = &dev->resource[i];
+ struct resource *pr = pci_find_parent_resource(dev, r);
+ unsigned long size = r->end + 1;
- orig_mem_base = pci_mem_base;
- orig_io_base = pci_io_base;
- pci_mem_base = 0;
- pci_io_base = 0;
+ if (!pr)
+ return -EINVAL;
- /*
- * Scan the tree, allocating PCI memory and I/O space.
- */
+ if (r->flags & IORESOURCE_IO)
+ {
+ if (size > 0x100)
+ return -EFBIG;
- layout_bus(pci_bus_b(pci_root.next), orig_mem_base, orig_io_base);
+ if (allocate_resource(pr, r, size, bus_info->io_space.start +
+ IO_ALLOC_OFFSET, bus_info->io_space.end, 1024))
+ return -EBUSY;
+ }
+ else
+ {
+ if (allocate_resource(pr, r, size, bus_info->mem_space.start +
+ MEM_ALLOC_OFFSET, bus_info->mem_space.end, size))
+ return -EBUSY;
+ }
- pci_mem_base = orig_mem_base;
- pci_io_base = orig_io_base;
-#endif
+ if (i < 6)
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, r->start);
- /*
- * Now is the time to do all those dirty little deeds...
- */
-
- hades_fixup();
+ return 0;
}
void __init pcibios_fixup_bus(struct pci_bus *bus)
{
+ struct pci_dev *dev;
+ void *sysdata;
+
+ sysdata = (bus->parent) ? bus->parent->sysdata : bus->sysdata;
+
+ for (dev = bus->devices; (dev != NULL); dev = dev->sibling)
+ dev->sysdata = sysdata;
+}
+
+void __init pcibios_init(void)
+{
+ printk("Linux/m68k PCI BIOS32 revision %x.%02x\n", MAJOR_REV, MINOR_REV);
+
+ bus_info = NULL;
+#ifdef CONFIG_HADES
+ if (MACH_IS_HADES)
+ bus_info = init_hades_pci();
+#endif
+ if (bus_info != NULL)
+ {
+ printk("PCI: Probing PCI hardware\n");
+ pci_scan_bus(0, bus_info->m68k_pci_ops, bus_info);
+ pcibios_fixup();
+ pcibios_claim_resources(pci_root);
+ }
+ else
+ printk("PCI: No PCI bus detected\n");
}
char * __init pcibios_setup(char *str)
{
+ if (!strcmp(str, "nomodify"))
+ {
+ pci_modify = 0;
+ return NULL;
+ }
+ else if (!strcmp(str, "skipvga"))
+ {
+ skip_vga = 1;
+ return NULL;
+ }
+ else if (!strcmp(str, "noburst"))
+ {
+ disable_pci_burst = 1;
+ return NULL;
+ }
+
return str;
}
#endif /* CONFIG_PCI */
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index b3ef8ded3..021652201 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -83,18 +83,22 @@ ENTRY(ret_from_fork)
jra SYMBOL_NAME(ret_from_exception)
badsys:
- movel #-ENOSYS,PT_D0(%sp)
+ movel #-ENOSYS,%sp@(PT_D0)
jra SYMBOL_NAME(ret_from_exception)
do_trace:
- movel #-ENOSYS,PT_D0(%sp) | needed for strace
+ movel #-ENOSYS,%sp@(PT_D0) | needed for strace
subql #4,%sp
SAVE_SWITCH_STACK
jbsr SYMBOL_NAME(syscall_trace)
RESTORE_SWITCH_STACK
addql #4,%sp
- jbsr @(SYMBOL_NAME(sys_call_table),%d2:l:4)@(0)
- movel %d0,%sp@(PT_D0) | save the return value
+ movel %sp@(PT_ORIG_D0),%d1
+ movel #-ENOSYS,%d0
+ cmpl #NR_syscalls,%d1
+ jcc 1f
+ jbsr @(SYMBOL_NAME(sys_call_table),%d1:l:4)@(0)
+1: movel %d0,%sp@(PT_D0) | save the return value
subql #4,%sp | dummy return address
SAVE_SWITCH_STACK
jbsr SYMBOL_NAME(syscall_trace)
@@ -106,17 +110,16 @@ SYMBOL_NAME_LABEL(ret_from_signal)
ENTRY(system_call)
SAVE_ALL_SYS
- movel %d0,%d2
- GET_CURRENT(%d0)
+ GET_CURRENT(%d1)
| save top of frame
movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
- cmpl #NR_syscalls,%d2
- jcc badsys
btst #PF_TRACESYS_BIT,%curptr@(TASK_FLAGS+PF_TRACESYS_OFF)
jne do_trace
- jbsr @(SYMBOL_NAME(sys_call_table),%d2:l:4)@(0)
+ cmpl #NR_syscalls,%d0
+ jcc badsys
+ jbsr @(SYMBOL_NAME(sys_call_table),%d0:l:4)@(0)
movel %d0,%sp@(PT_D0) | save the return value
SYMBOL_NAME_LABEL(ret_from_exception)
@@ -604,24 +607,27 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_mmap2)
.long SYMBOL_NAME(sys_truncate64)
.long SYMBOL_NAME(sys_ftruncate64)
- .long SYMBOL_NAME(sys_chown) /* 195 */
+ .long SYMBOL_NAME(sys_stat64) /* 195 */
+ .long SYMBOL_NAME(sys_lstat64)
+ .long SYMBOL_NAME(sys_fstat64)
+ .long SYMBOL_NAME(sys_chown)
.long SYMBOL_NAME(sys_getuid)
- .long SYMBOL_NAME(sys_getgid)
+ .long SYMBOL_NAME(sys_getgid) /* 200 */
.long SYMBOL_NAME(sys_geteuid)
.long SYMBOL_NAME(sys_getegid)
- .long SYMBOL_NAME(sys_setreuid) /* 200 */
+ .long SYMBOL_NAME(sys_setreuid)
.long SYMBOL_NAME(sys_setregid)
- .long SYMBOL_NAME(sys_getgroups)
+ .long SYMBOL_NAME(sys_getgroups) /* 205 */
.long SYMBOL_NAME(sys_setgroups)
.long SYMBOL_NAME(sys_fchown)
- .long SYMBOL_NAME(sys_setresuid) /* 205 */
+ .long SYMBOL_NAME(sys_setresuid)
.long SYMBOL_NAME(sys_getresuid)
- .long SYMBOL_NAME(sys_setresgid)
+ .long SYMBOL_NAME(sys_setresgid) /* 210 */
.long SYMBOL_NAME(sys_getresgid)
.long SYMBOL_NAME(sys_lchown)
- .long SYMBOL_NAME(sys_setuid) /* 210 */
+ .long SYMBOL_NAME(sys_setuid)
.long SYMBOL_NAME(sys_setgid)
- .long SYMBOL_NAME(sys_setfsuid)
+ .long SYMBOL_NAME(sys_setfsuid) /* 215 */
.long SYMBOL_NAME(sys_setfsgid)
.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S
index 49285b86d..461bf9c9b 100644
--- a/arch/m68k/kernel/head.S
+++ b/arch/m68k/kernel/head.S
@@ -259,7 +259,9 @@
#include <linux/init.h>
#include <asm/bootinfo.h>
#include <asm/setup.h>
+#include <asm/entry.h>
#include <asm/pgtable.h>
+#include <asm/page.h>
#include "m68k_defs.h"
#ifdef CONFIG_MAC
@@ -305,7 +307,7 @@
.globl SYMBOL_NAME(m68k_pgtable_cachemode)
.globl SYMBOL_NAME(m68k_supervisor_cachemode)
#ifdef CONFIG_MVME16x
-.globl SYMBOL_NAME(mvme_bdid_ptr)
+.globl SYMBOL_NAME(mvme_bdid)
#endif
#ifdef CONFIG_Q40
.globl SYMBOL_NAME(q40_mem_cptr)
@@ -386,6 +388,12 @@ PAGE_INDEX_SHIFT = 12
#endif
#endif
+/* The __INITDATA stuff is a no-op when ftrace or kgdb are turned on */
+#ifndef __INITDATA
+#define __INITDATA .data
+#define __FINIT .previous
+#endif
+
/* Several macros to make the writing of subroutines easier:
* - func_start marks the beginning of the routine which setups the frame
* register and saves the registers, it also defines another macro
@@ -503,18 +511,10 @@ func_define putn,1
.macro puts string
#if defined(CONSOLE) || defined(SERIAL_DEBUG)
-/* The __INITDATA stuff is a no-op when ftrace or kgdb are turned on */
-#if defined(CONFIG_FTRACE) || defined(CONFIG_KGDB)
- bra 1f
-#endif
__INITDATA
.Lstr\@:
.string "\string"
__FINIT
-#if defined(CONFIG_FTRACE) || defined(CONFIG_KGDB)
- .align 2
-1:
-#endif
pea %pc@(.Lstr\@)
func_call puts
addql #4,%sp
@@ -533,10 +533,20 @@ func_define putn,1
#define is_not_mvme147(lab) cmpl &MACH_MVME147,%pc@(m68k_machtype); jne lab
#define is_not_mvme16x(lab) cmpl &MACH_MVME16x,%pc@(m68k_machtype); jne lab
#define is_not_bvme6000(lab) cmpl &MACH_BVME6000,%pc@(m68k_machtype); jne lab
+#define is_mvme147(lab) cmpl &MACH_MVME147,%pc@(m68k_machtype); jeq lab
+#define is_mvme16x(lab) cmpl &MACH_MVME16x,%pc@(m68k_machtype); jeq lab
+#define is_bvme6000(lab) cmpl &MACH_BVME6000,%pc@(m68k_machtype); jeq lab
#define is_not_hp300(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); jne lab
+#define is_not_apollo(lab) cmpl &MACH_APOLLO,%pc@(m68k_machtype); jne lab
#define is_not_q40(lab) cmpl &MACH_Q40,%pc@(m68k_machtype); jne lab
#define is_not_sun3x(lab) cmpl &MACH_SUN3X,%pc@(m68k_machtype); jne lab
+#define hasnt_leds(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); \
+ jeq 42f; \
+ cmpl &MACH_APOLLO,%pc@(m68k_machtype); \
+ jne lab ;\
+ 42:\
+
#define is_040_or_060(lab) btst &CPUTYPE_0460,%pc@(L(cputype)+3); jne lab
#define is_not_040_or_060(lab) btst &CPUTYPE_0460,%pc@(L(cputype)+3); jeq lab
#define is_040(lab) btst &CPUTYPE_040,%pc@(L(cputype)+3); jne lab
@@ -549,8 +559,8 @@ func_define putn,1
the console is running. Writing a 1 bit turns the corresponding LED
_off_ - on the 340 bit 7 is towards the back panel of the machine. */
.macro leds mask
-#ifdef CONFIG_HP300
- is_not_hp300(.Lled\@)
+#if defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
+ hasnt_leds(.Lled\@)
pea \mask
func_call set_leds
addql #4,%sp
@@ -809,6 +819,57 @@ L(save_cachetype):
L(notypetest):
#endif
+#ifdef CONFIG_VME
+ is_mvme147(L(getvmetype))
+ is_bvme6000(L(getvmetype))
+ is_not_mvme16x(L(gvtdone))
+
+ /* See if the loader has specified the BI_VME_TYPE tag. Recent
+ * versions of VMELILO and TFTPLILO do this. We have to do this
+ * early so we know how to handle console output. If the tag
+ * doesn't exist then we use the Bug for output on MVME16x.
+ */
+L(getvmetype):
+ get_bi_record BI_VME_TYPE
+ tstl %d0
+ jbmi 1f
+ movel %a0@,%d3
+ lea %pc@(SYMBOL_NAME(vme_brdtype)),%a0
+ movel %d3,%a0@
+1:
+#ifdef CONFIG_MVME16x
+ is_not_mvme16x(L(gvtdone))
+
+ /* Need to get the BRD_ID info to diferentiate between 162, 167,
+ * etc. This is available as a BI_VME_BRDINFO tag with later
+ * versions of VMELILO and TFTPLILO, otherwise we call the Bug.
+ */
+ get_bi_record BI_VME_BRDINFO
+ tstl %d0
+ jpl 1f
+
+ /* Get pointer to board ID data from Bug */
+ movel %d2,%sp@-
+ trap #15
+ .word 0x70 /* trap 0x70 - .BRD_ID */
+ movel %sp@+,%a0
+1:
+ lea %pc@(SYMBOL_NAME(mvme_bdid)),%a1
+ /* Structure is 32 bytes long */
+ movel %a0@+,%a1@+
+ movel %a0@+,%a1@+
+ movel %a0@+,%a1@+
+ movel %a0@+,%a1@+
+ movel %a0@+,%a1@+
+ movel %a0@+,%a1@+
+ movel %a0@+,%a1@+
+ movel %a0@+,%a1@+
+#endif
+
+L(gvtdone):
+
+#endif
+
/*
* Initialize serial port
*/
@@ -843,6 +904,7 @@ L(nocon):
lea %pc@(L(phys_kernel_start)),%a0
lea %pc@(SYMBOL_NAME(_stext)),%a1
subl #SYMBOL_NAME(_stext),%a1
+ addl #PAGE_OFFSET,%a1
movel %a1,%a0@
putc 'B'
@@ -857,7 +919,7 @@ L(nocon):
* First map the first 4 MB of kernel code & data
*/
- mmu_map #0,%pc@(L(phys_kernel_start)),#4*1024*1024,\
+ mmu_map #PAGE_OFFSET,%pc@(L(phys_kernel_start)),#4*1024*1024,\
%pc@(SYMBOL_NAME(m68k_supervisor_cachemode))
putc 'C'
@@ -1006,14 +1068,6 @@ L(not147):
is_not_mvme16x(L(not16x))
- /* Get pointer to board ID data */
- movel %d2,%sp@-
- trap #15
- .word 0x70 /* trap 0x70 - .BRD_ID */
- movel %sp@+,%d2
- lea %pc@(SYMBOL_NAME(mvme_bdid_ptr)),%a0
- movel %d2,%a0@
-
/*
* On MVME16x we have already created kernel page tables for
* 4MB of RAM at address 0, so now need to do a transparent
@@ -1126,8 +1180,18 @@ L(mmu_init_not_mac):
/* setup tt1 for I/O */
mmu_map_tt #1,#0x40000000,#0x40000000,#_PAGE_NOCACHE_S
+ jbra L(mmu_init_done)
L(notsun3x):
+#endif
+
+#ifdef CONFIG_APOLLO
+ is_not_apollo(L(notapollo))
+
+ putc 'P'
+ mmu_map #0x80000000,#0,#0x02000000,#_PAGE_NOCACHE030
+
+L(notapollo):
jbra L(mmu_init_done)
#endif
@@ -1161,6 +1225,7 @@ L(mmu_fixup):
* contains also kernel_pg_dir.
*/
movel %pc@(L(phys_kernel_start)),%d0
+ subl #PAGE_OFFSET,%d0
lea %pc@(SYMBOL_NAME(_stext)),%a0
subl %d0,%a0
mmu_fixup_page_mmu_cache %a0
@@ -1249,6 +1314,14 @@ L(mmu_fixup_done):
mmu_engage
+/*
+ * After this point no new memory is allocated and
+ * the start of available memory is stored in availmem.
+ * (The bootmem allocator requires now the physicall address.)
+ */
+
+ movel L(memory_start),availmem
+
#ifdef CONFIG_AMIGA
is_not_amiga(1f)
/* fixup the Amiga custom register location before printing */
@@ -1294,20 +1367,19 @@ L(mmu_fixup_done):
1:
#endif
-/*
- * Fixup the addresses for the kernel pointer table and availmem.
- * Convert them from physical addresses to virtual addresses.
- */
+#ifdef CONFIG_APOLLO
+ is_not_apollo(1f)
+ /*
+ * Fix up the iobase before printing
+ */
+ movel #0x80000000,L(iobase)
+1:
+#endif
+
putc 'I'
leds 0x10
- /* do the same conversion on the first available memory
- * address (in a6).
- */
- movel L(memory_start),%d0
- movel %d0,SYMBOL_NAME(availmem)
-
/*
* Enable caches
*/
@@ -1352,14 +1424,23 @@ L(cache_done):
/*
* Setup initial stack pointer
*/
- lea SYMBOL_NAME(init_task_union),%a2
- lea 0x2000(%a2),%sp
+ lea SYMBOL_NAME(init_task_union),%curptr
+ lea 0x2000(%curptr),%sp
+
+ putc 'K'
+
+ subl %a6,%a6 /* clear a6 for gdb */
+
+/*
+ * The new 64bit printf support requires an early exception initialization.
+ */
+ jbsr SYMBOL_NAME(base_trap_init)
/* jump to the kernel start */
+
putc '\n'
leds 0x55
- subl %a6,%a6 /* clear a6 for gdb */
jbsr SYMBOL_NAME(start_kernel)
/*
@@ -2355,12 +2436,12 @@ L(mmu_engage_030):
.chip 68k
L(mmu_engage_cleanup):
+ subl #PAGE_OFFSET,%d2
subl %d2,%a2
movel %a2,L(kernel_pgdir_ptr)
subl %d2,%fp
subl %d2,%sp
subl %d2,ARG0
- subl %d2,L(memory_start)
func_return mmu_engage
@@ -2810,6 +2891,10 @@ L(serial_init_not_mac):
2:
#endif
+#ifdef CONFIG_APOLLO
+/* We count on the PROM initializing SIO1 */
+#endif
+
L(serial_init_done):
func_return serial_init
@@ -2911,13 +2996,54 @@ func_start serial_putc,%d0/%d1/%a0/%a1
#ifdef CONFIG_MVME16x
is_not_mvme16x(2f)
/*
- * The VME 16x class has PROM support for serial output
- * of some kind; the TRAP table is still valid.
+ * If the loader gave us a board type then we can use that to
+ * select an appropriate output routine; otherwise we just use
+ * the Bug code. If we haev to use the Bug that means the Bug
+ * workspace has to be valid, which means the Bug has to use
+ * the SRAM, which is non-standard.
*/
moveml %d0-%d7/%a2-%a6,%sp@-
+ movel SYMBOL_NAME(vme_brdtype),%d1
+ jeq 1f | No tag - use the Bug
+ cmpi #VME_TYPE_MVME162,%d1
+ jeq 6f
+ cmpi #VME_TYPE_MVME172,%d1
+ jne 5f
+ /* 162/172; it's an SCC */
+6: btst #2,M162_SCC_CTRL_A
+ nop
+ nop
+ nop
+ jeq 6b
+ moveb #8,M162_SCC_CTRL_A
+ nop
+ nop
+ nop
+ moveb %d0,M162_SCC_CTRL_A
+ jra 3f
+5:
+ /* 166/167/177; its a CD2401 */
+ moveb #0,M167_CYCAR
+ moveb M167_CYIER,%d2
+ moveb #0x02,M167_CYIER
+7:
+ btst #5,M167_PCSCCTICR
+ jeq 7b
+ moveb M167_PCTPIACKR,%d1
+ moveb M167_CYLICR,%d1
+ jeq 8f
+ moveb #0x08,M167_CYTEOIR
+ jra 7b
+8:
+ moveb %d0,M167_CYTDR
+ moveb #0,M167_CYTEOIR
+ moveb %d2,M167_CYIER
+ jra 3f
+1:
moveb %d0,%sp@-
trap #15
.word 0x0020 /* TRAP 0x020 */
+3:
moveml %sp@+,%d0-%d7/%a2-%a6
jbra L(serial_putc_done)
2:
@@ -2944,9 +3070,20 @@ func_start serial_putc,%d0/%d1/%a0/%a1
move.b %d0,%a0@
addq.l #4,%a0
move.l %a0,%a1@
+ jbra L(serial_putc_done)
2:
#endif
+#ifdef CONFIG_APOLLO
+ is_not_apollo(2f)
+ movl %pc@(L(iobase)),%a1
+ moveb %d0,%a1@(LTHRB0)
+1: moveb %a1@(LSRB0),%d0
+ andb #0x4,%d0
+ beq 1b
+2:
+#endif
+
L(serial_putc_done):
func_return serial_putc
@@ -3029,11 +3166,23 @@ ENTRY(mac_serial_print)
rts
#endif /* CONFIG_MAC */
-#ifdef CONFIG_HP300
+#if defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
func_start set_leds,%d0/%a0
movel ARG1,%d0
- movel %pc@(Lcustom),%a0
+#ifdef CONFIG_HP300
+ is_not_hp300(1f)
+ movel %pc@(L(custom)),%a0
moveb %d0,%a0@(0x1ffff)
+ jra 2f
+#endif
+1:
+#ifdef CONFIG_APOLLO
+ movel %pc@(L(iobase)),%a0
+ lsll #8,%d0
+ eorw #0xff00,%d0
+ moveb %d0,%a0@(LCPUCTRL)
+#endif
+2:
func_return set_leds
#endif
@@ -3605,6 +3754,17 @@ M147_SCC_CTRL_A = 0xfffe3002
M147_SCC_DATA_A = 0xfffe3003
#endif
+#if defined (CONFIG_MVME16x)
+M162_SCC_CTRL_A = 0xfff45005
+M167_CYCAR = 0xfff450ee
+M167_CYIER = 0xfff45011
+M167_CYLICR = 0xfff45026
+M167_CYTEOIR = 0xfff45085
+M167_CYTDR = 0xfff450f8
+M167_PCSCCTICR = 0xfff4201e
+M167_PCTPIACKR = 0xfff42025
+#endif
+
#if defined (CONFIG_BVME6000)
BVME_SCC_CTRL_A = 0xffb0000b
BVME_SCC_DATA_A = 0xffb0000f
@@ -3627,6 +3787,14 @@ L(mac_sccbase):
#endif /* MAC_SERIAL_DEBUG */
#endif
+#if defined (CONFIG_APOLLO)
+LSRB0 = 0x10412
+LTHRB0 = 0x10416
+LCPUCTRL = 0x10100
+L(iobase):
+ .long 0
+#endif
+
__FINIT
.data
.align 4
@@ -3638,8 +3806,8 @@ SYMBOL_NAME_LABEL(m68k_pgtable_cachemode)
SYMBOL_NAME_LABEL(m68k_supervisor_cachemode)
.long 0
#if defined(CONFIG_MVME16x)
-SYMBOL_NAME_LABEL(mvme_bdid_ptr)
- .long 0
+SYMBOL_NAME_LABEL(mvme_bdid)
+ .long 0,0,0,0,0,0,0,0
#endif
#if defined(CONFIG_Q40)
SYMBOL_NAME_LABEL(q40_mem_cptr)
diff --git a/arch/m68k/kernel/kgdb.c b/arch/m68k/kernel/kgdb.c
deleted file mode 100644
index be75defdb..000000000
--- a/arch/m68k/kernel/kgdb.c
+++ /dev/null
@@ -1,1362 +0,0 @@
-/*
- * arch/m68k/kernel/kgdb.c -- Stub for GDB remote debugging protocol
- *
- * Originally written by Glenn Engel, Lake Stevens Instrument Division
- *
- * Contributed by HP Systems
- *
- * Modified for SPARC by Stu Grossman, Cygnus Support.
- * Modified for Linux/MIPS (and MIPS in general) by Andreas Busse
- * Modified and extended for Linux/68k by Roman Hodek
- *
- * Send complaints, suggestions etc. to
- * <Roman.Hodek@informatik.uni-erlangen.de>
- *
- * Copyright (C) 1996-97 Roman Hodek
- */
-
-/*
- * kgdb usage notes:
- * -----------------
- *
- * If you select CONFIG_KGDB in the configuration, the kernel will be built
- * with different gccc flags: "-g" is added to get debug infos, and
- * "-fomit-frame-pointer" is omitted to make debugging easier. Since the
- * resulting kernel will be quite big (approx. > 7 MB), it will be stripped
- * before compresion. Such a kernel will behave just as usually, except if
- * given a "debug=<device>" command line option. (Only serial devices are
- * allowed for <device>, i.e. no printers or the like; possible values are
- * machine depedend and are the same as for the usual debug device, the one
- * for logging kernel messages.) If that option is given and the device can be
- * initialized, the kernel will connect to the remote gdb in trap_init(). The
- * serial parameters are fixed to 8N1 and 9600bps, for easyness of
- * implementation.
- *
- * Of course, you need a remote machine a suitable gdb there. I.e., it must
- * have support for a m68k-linux target built in. If the remote machine
- * doesn't run Linux/68k itself, you have to build a cross gdb. This is done
- * by
- * ./configure --target=m68k-linux
- * in the gdb source directory. Until gdb comes with m68k-linux support by
- * default, you have to apply some patches before. The remote debugging
- * protocol itself is always built into gdb anyway, so you don't have to take
- * special care about it.
- *
- * To start a debugging session, start that gdb with the debugging kernel
- * image (the one with the symbols, vmlinux.debug) named on the command line.
- * This file will be used by gdb to get symbol and debugging infos about the
- * kernel. Next, select remote debug mode by
- * target remote <device>
- * where <device> is the name of the serial device over which the debugged
- * machine is connected. Maybe you have to adjust the baud rate by
- * set remotebaud <rate>
- * or also other parameters with stty:
- * shell stty ... </dev/...
- * If the kernel to debug has already booted, it waited for gdb and now
- * connects, and you'll see a breakpoint being reported. If the kernel isn't
- * running yet, start it now. The order of gdb and the kernel doesn't matter.
- * Another thing worth knowing about in the getting-started phase is how to
- * debug the remote protocol itself. This is activated with
- * set remotedebug 1
- * gdb will then print out each packet sent or received. You'll also get some
- * messages about the gdb stub on the console of the debugged machine.
- *
- * If all that works, you can use lots of the usual debugging techniques on
- * the kernel, e.g. inspecting and changing variables/memory, setting
- * breakpoints, single stepping and so on. It's also possible to interrupt the
- * debugged kernel by pressing C-c in gdb. Have fun! :-)
- *
- * The gdb stub is entered (and thus the remote gdb gets control) in the
- * following situations:
- *
- * - If breakpoint() is called. This is just after kgdb initialization, or if
- * a breakpoint() call has been put somewhere into the kernel source.
- * (Breakpoints can of course also be set the usual way in gdb.)
- *
- * - If there is a kernel exception, i.e. bad_super_trap() or die_if_kernel()
- * are entered. All the CPU exceptions are mapped to (more or less..., see
- * the hard_trap_info array below) appropriate signal, which are reported
- * to gdb. die_if_kernel() is usually called after some kind of access
- * error and thus is reported as SIGSEGV.
- *
- * - When panic() is called. This is reported as SIGABRT.
- *
- * - If C-c is received over the serial line, which is treated as
- * SIGINT.
- *
- * Of course, all these signals are just faked for gdb, since there is no
- * signal concept as such for the kernel. It also isn't possible --obviously--
- * to set signal handlers from inside gdb, or restart the kernel with a
- * signal.
- *
- * Current limitations:
- *
- * - While the kernel is stopped, interrupts are disabled for safety reasons
- * (i.e., variables not changing magically or the like). But this also
- * means that the clock isn't running anymore, and that interrupts from the
- * hardware may get lost/not be served in time. This can cause some device
- * errors...
- *
- * - When single-stepping, only one instruction of the current thread is
- * executed, but interrupts are allowed for that time and will be serviced
- * if pending. Be prepared for that.
- *
- * - All debugging happens in kernel virtual address space. There's no way to
- * access physical memory not mapped in kernel space, or to access user
- * space. A way to work around this is using get_user_long & Co. in gdb
- * expressions, but only for the current process.
- *
- * - Interrupting the kernel only works if interrupts are currently allowed,
- * and the interrupt of the serial line isn't blocked by some other means
- * (IPL too high, disabled, ...)
- *
- * - The gdb stub is currently not reentrant, i.e. errors that happen therein
- * (e.g. accesing invalid memory) may not be caught correctly. This could
- * be removed in future by introducing a stack of struct registers.
- *
- */
-
-/*
- * To enable debugger support, two things need to happen. One, a
- * call to kgdb_init() is necessary in order to allow any breakpoints
- * or error conditions to be properly intercepted and reported to gdb.
- * (Linux/68k note: Due to the current design, kgdb has to be initialized
- * after traps and interrupts.)
- * Two, a breakpoint needs to be generated to begin communication. This
- * is most easily accomplished by a call to breakpoint(). Breakpoint()
- * simulates a breakpoint by executing a TRAP #15 instruction.
- *
- *
- * The following gdb commands are supported:
- *
- * command function Return value
- *
- * g return the value of the CPU registers hex data or ENN
- * G set the value of the CPU registers OK or ENN
- *
- * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
- * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
- *
- * c Resume at current address SNN ( signal NN)
- * cAA..AA Continue at address AA..AA SNN
- *
- * s Step one instruction SNN
- * sAA..AA Step one instruction from AA..AA SNN
- *
- * k kill
- *
- * ? What was the last sigval ? SNN (signal NN)
- *
- * bBB..BB Set baud rate to BB..BB OK or BNN, then sets
- * baud rate
- *
- * All commands and responses are sent with a packet which includes a
- * checksum. A packet consists of
- *
- * $<packet info>#<checksum>.
- *
- * where
- * <packet info> :: <characters representing the command or response>
- * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
- *
- * When a packet is received, it is first acknowledged with either '+' or '-'.
- * '+' indicates a successful transfer. '-' indicates a failed transfer.
- *
- * Example:
- *
- * Host: Reply:
- * $m0,10#2a +$00010203040506070809101112131415#42
- *
- */
-
-#include <linux/config.h>
-#include <linux/string.h>
-#include <linux/signal.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/linkage.h>
-
-#include <asm/setup.h>
-#include <asm/ptrace.h>
-#include <asm/traps.h>
-#include <asm/machdep.h>
-#include <asm/kgdb.h>
-#ifdef CONFIG_ATARI
-#include <asm/atarihw.h>
-#include <asm/atariints.h>
-#endif
-#ifdef CONFIG_AMIGA
-#include <asm/amigahw.h>
-#include <asm/amigaints.h>
-#endif
-#ifdef CONFIG_MAC
-#include <linux/tty.h>
-#include <asm/bootinfo.h>
-#include <asm/macints.h>
-#endif
-
-
-#undef DEBUG
-
-/*
- * global variable: register structure
- */
-
-struct gdb_regs kgdb_registers;
-
-/*
- * serial i/o functions
- */
-
-static int (*serial_out)( unsigned char c );
-static unsigned char (*serial_in)( void );
-static unsigned char (*serial_intr)( void );
-
-#define putDebugChar(c) serial_out(c)
-#define getDebugChar() serial_in()
-
-
-/***************************** Prototypes *****************************/
-
-static int hex( unsigned char ch);
-static void getpacket( char *buffer);
-static void putpacket( char *buffer, int expect_ack);
-static inline unsigned long *get_vbr( void );
-static int protected_read( char *p, unsigned long *vbr );
-static int protected_write( char *p, char val, unsigned long *vbr );
-static unsigned char *mem2hex( char *mem, char *buf, int count, int
- may_fault);
-static char *hex2mem( char *buf, char *mem, int count, int may_fault);
-static int computeSignal( int tt);
-static int hexToInt( char **ptr, int *intValue);
-extern asmlinkage void kgdb_intr( int intno, void *data, struct pt_regs *fp );
-static asmlinkage void handle_exception( void );
-static void show_gdbregs( void );
-#ifdef CONFIG_ATARI
-static int atari_mfp_out( unsigned char c );
-static unsigned char atari_mfp_in( void );
-static unsigned char atari_mfp_intr( void );
-static int atari_scc_out( unsigned char c );
-static unsigned char atari_scc_in( void );
-static unsigned char atari_scc_intr( void );
-#endif
-#ifdef CONFIG_AMIGA
-extern int amiga_ser_out( unsigned char c );
-extern unsigned char amiga_ser_in( void );
-#endif
-#ifdef CONFIG_MAC
-static unsigned char mac_scca_in( void );
-static unsigned char mac_scca_out( unsigned char c );
-static unsigned char mac_scca_intr( void );
-static unsigned char mac_sccb_in( void );
-static unsigned char mac_sccb_out( unsigned char c);
-static unsigned char mac_sccb_intr( void );
-extern void mac_init_scc_port( int cflag, int port );
-#endif
-
-/************************* End of Prototypes **************************/
-
-
-int kgdb_initialized = 0; /* !0 means we've been initialized */
-
-/*
- * BUFMAX defines the maximum number of characters in inbound/outbound buffers
- * at least NUMREGBYTES*2 are needed for register packets
- */
-#define BUFMAX 2048
-
-static char input_buffer[BUFMAX];
-static char output_buffer[BUFMAX];
-static const char hexchars[]="0123456789abcdef";
-/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
-static int remote_debug = 0;
-
-/* sizes (in bytes) of CPU stack frames */
-static int frame_sizes[16] = {
- 8, 8, 12, 12, /* $0..$3 */
- 16, 8, 8, 60, /* $4..$7 */
- 8, 20, 32, 92, /* $8..$B */
- 12, 4, 4, 4 /* $C..$F */
-};
-
-/*
- * Convert ch from a hex digit to an int
- */
-static int hex(unsigned char ch)
-{
- if (ch >= 'a' && ch <= 'f')
- return ch-'a'+10;
- if (ch >= '0' && ch <= '9')
- return ch-'0';
- if (ch >= 'A' && ch <= 'F')
- return ch-'A'+10;
- return -1;
-}
-
-/*
- * scan for the sequence $<data>#<checksum>
- */
-static void getpacket(char *buffer)
-{
- unsigned char checksum;
- unsigned char xmitcsum;
- int i;
- int count;
- unsigned char ch;
-
- do {
- /*
- * wait around for the start character,
- * ignore all other characters
- */
- while ((ch = (getDebugChar() & 0x7f)) != '$') ;
-
- checksum = 0;
- xmitcsum = -1;
- count = 0;
-
- /*
- * now, read until a # or end of buffer is found
- */
- while (count < BUFMAX) {
- ch = getDebugChar() & 0x7f;
- if (ch == '#')
- break;
- checksum = checksum + ch;
- buffer[count] = ch;
- count = count + 1;
- }
-
- if (count >= BUFMAX)
- continue;
-
- buffer[count] = 0;
-#ifdef DEBUG
- printk( "kgdb: received packet %s\n", buffer );
-#endif
-
- if (ch == '#') {
- xmitcsum = hex(getDebugChar() & 0x7f) << 4;
- xmitcsum |= hex(getDebugChar() & 0x7f);
-
- if (checksum != xmitcsum) {
- if (remote_debug)
- printk( "kgdb: bad checksum. count = 0x%x sent=0x%x "
- "buf=%s\n", checksum, xmitcsum, buffer );
- putDebugChar('-'); /* failed checksum */
- }
- else {
- putDebugChar('+'); /* successful transfer */
-
- /*
- * if a sequence char is present,
- * reply the sequence ID
- */
- if (buffer[2] == ':') {
- putDebugChar(buffer[0]);
- putDebugChar(buffer[1]);
-
- /*
- * remove sequence chars from buffer
- */
- count = strlen(buffer);
- for (i=3; i <= count; i++)
- buffer[i-3] = buffer[i];
- }
- }
- }
- }
- while (checksum != xmitcsum);
-}
-
-/*
- * send the packet in buffer.
- */
-static void putpacket(char *buffer, int expect_ack)
-{
- unsigned char checksum;
- int count;
- unsigned char ch;
-
- /*
- * $<packet info>#<checksum>.
- */
-
-#ifdef DEBUG
- printk( "kgdb: sending packet %s\n", buffer );
-#endif
- do {
- putDebugChar('$');
- checksum = 0;
- count = 0;
-
- while ((ch = buffer[count]) != 0) {
- if (!(putDebugChar(ch)))
- return;
- checksum += ch;
- count += 1;
- }
-
- putDebugChar('#');
- putDebugChar(hexchars[checksum >> 4]);
- putDebugChar(hexchars[checksum & 0xf]);
-
- }
- while (expect_ack && (getDebugChar() & 0x7f) != '+');
-}
-
-
-static inline unsigned long *get_vbr( void )
-
-{ unsigned long *vbr;
-
- __asm__ __volatile__ ( "movec %/vbr,%0" : "=d" (vbr) : );
- return( vbr );
-}
-
-static int protected_read( char *p, unsigned long *vbr )
-
-{ unsigned char val;
- int rv;
-
- __asm__ __volatile__
- ( "movel %3@(8),%/a0\n\t"
- "movel #Lberr1,%3@(8)\n\t"
- "movel %/sp,%/a1\n\t"
- "moveq #1,%1\n\t"
- "moveb %2@,%0\n"
- "nop \n\t"
- "moveq #0,%1\n\t"
- "Lberr1:\t"
- "movel %/a1,%/sp\n\t"
- "movel %/a0,%3@(8)"
- : "=&d" (val), "=&r" (rv)
- : "a" (p), "a" (vbr)
- : "a0", "a1" );
-
- return( rv ? -1 : val );
-}
-
-static int protected_write( char *p, char val, unsigned long *vbr )
-
-{ int rv;
-
- __asm__ __volatile__
- ( "movel %3@(8),%/a0\n\t"
- "movel #Lberr2,%3@(8)\n\t"
- "movel %/sp,%/a1\n\t"
- "moveq #1,%0\n\t"
- "moveb %2,%1@\n"
- "nop \n\t"
- "moveq #0,%0\n\t"
- "Lberr2:\t"
- "movel %/a1,%/sp\n\t"
- "movel %/a0,%3@(8)"
- : "=&r" (rv)
- : "a" (p), "d" (val), "a" (vbr)
- : "a0", "a1" );
-
- return( rv );
-}
-
-/*
- * Convert the memory pointed to by mem into hex, placing result in buf.
- * Return a pointer to the last char put in buf (null), in case of mem fault,
- * return 0.
- * If MAY_FAULT is non-zero, then we will handle memory faults by returning
- * a 0, else treat a fault like any other fault in the stub.
- */
-static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault)
-{
- int ch;
- unsigned long *vbr = get_vbr();
-
- for( ; count-- > 0; ++mem ) {
- if ((ch = protected_read( mem, vbr )) < 0) {
- /* bus error happened */
- if (may_fault)
- return 0;
- else {
- /* ignore, but print a warning */
- printk( "Bus error on read from %p\n", mem );
- ch = 0;
- }
- }
- *buf++ = hexchars[(ch >> 4) & 0xf];
- *buf++ = hexchars[ch & 0xf];
- }
-
- *buf = 0;
-
- return buf;
-}
-
-/*
- * convert the hex array pointed to by buf into binary to be placed in mem
- * return a pointer to the character AFTER the last byte written
- */
-static char *hex2mem(char *buf, char *mem, int count, int may_fault)
-{
- int i;
- unsigned char ch;
- unsigned long *vbr = get_vbr();
-
- for( i = 0; i < count; i++, mem++ ) {
- ch = hex(*buf++) << 4;
- ch |= hex(*buf++);
- if (protected_write( mem, ch, vbr )) {
- /* bus error happened */
- if (may_fault)
- return 0;
- else
- /* ignore, but print a warning */
- printk( "Bus error on write to %p\n", mem );
- }
- }
-
- return mem;
-}
-
-/*
- * This table contains the mapping between SPARC hardware trap types, and
- * signals, which are primarily what GDB understands. It also indicates
- * which hardware traps we need to commandeer when initializing the stub.
- */
-static struct hard_trap_info
-{
- unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */
- unsigned char signo; /* Signal that we map this trap into */
-} hard_trap_info[] = {
- { 1, SIGINT }, /* excep. 1 is used to fake SIGINT */
- { VEC_BUSERR, SIGSEGV }, /* bus/access error */
- { VEC_ADDRERR, SIGBUS }, /* address error */
- { VEC_ILLEGAL, SIGILL }, /* illegal insn */
- { VEC_ZERODIV, SIGFPE }, /* (integer) divison by zero */
- { VEC_CHK, SIGILL }, /* CHK insn */
- { VEC_TRAP, SIGFPE }, /* [F]TRAPcc insn */
- { VEC_PRIV, SIGILL }, /* priviledge violation (cannot happen) */
- { VEC_TRACE, SIGTRAP }, /* trace trap (single-stepping) */
- { VEC_LINE10, SIGILL }, /* A-line insn */
- { VEC_LINE11, SIGILL }, /* F-line insn */
- { VEC_COPROC, SIGIOT }, /* coprocessor protocol error */
- { VEC_FORMAT, SIGIOT }, /* frame format error */
- { VEC_UNINT, SIGIOT }, /* uninitialized intr. (should not happen) */
- { VEC_SYS, SIGILL }, /* TRAP #0 = system call (illegal in kernel) */
- { VEC_TRAP1, SIGILL }, /* TRAP #1 */
- { VEC_TRAP2, SIGILL }, /* TRAP #2 */
- { VEC_TRAP3, SIGILL }, /* TRAP #3 */
- { VEC_TRAP4, SIGILL }, /* TRAP #4 */
- { VEC_TRAP5, SIGILL }, /* TRAP #5 */
- { VEC_TRAP6, SIGILL }, /* TRAP #6 */
- { VEC_TRAP7, SIGILL }, /* TRAP #7 */
- { VEC_TRAP8, SIGILL }, /* TRAP #8 */
- { VEC_TRAP9, SIGILL }, /* TRAP #9 */
- { VEC_TRAP10, SIGILL }, /* TRAP #10 */
- { VEC_TRAP11, SIGILL }, /* TRAP #11 */
- { VEC_TRAP12, SIGILL }, /* TRAP #12 */
- { VEC_TRAP13, SIGILL }, /* TRAP #13 */
- { VEC_TRAP14, SIGABRT }, /* TRAP #14 (used by kgdb_abort) */
- { VEC_TRAP15, SIGTRAP }, /* TRAP #15 (breakpoint) */
- { VEC_FPBRUC, SIGFPE }, /* FPU */
- { VEC_FPIR, SIGFPE }, /* FPU */
- { VEC_FPDIVZ, SIGFPE }, /* FPU */
- { VEC_FPUNDER, SIGFPE }, /* FPU */
- { VEC_FPOE, SIGFPE }, /* FPU */
- { VEC_FPOVER, SIGFPE }, /* FPU */
- { VEC_FPNAN, SIGFPE }, /* FPU */
- { VEC_FPUNSUP, SIGFPE }, /* FPU */
- { VEC_UNIMPEA, SIGILL }, /* unimpl. effective address */
- { VEC_UNIMPII, SIGILL }, /* unimpl. integer insn */
-
- { 0, 0 } /* Must be last */
-};
-
-
-/*
- * Set up exception handlers for tracing and breakpoints
- */
-void kgdb_init(void)
-{
- extern char m68k_debug_device[];
-
- /* fake usage to avoid gcc warnings about unused stuff (they're used in
- * assembler code) The local variables will be optimized away... */
- void (*fake1)(void) = handle_exception;
- int *fake2 = frame_sizes;
- (void)fake1; (void)fake2;
-
- /* We don't modify the real exception vectors here for the m68k.
- * handle_exception() will be called from bad_kernel_trap() or
- * die_if_kernel() as needed. */
-
- /*
- * Initialize the serial port (name in 'm68k_debug_device')
- */
-
- serial_in = NULL;
- serial_out = NULL;
- serial_intr = NULL;
-
-#ifdef CONFIG_ATARI
- if (MACH_IS_ATARI) {
- if (!strcmp( m68k_debug_device, "ser" )) {
- /* defaults to ser2 for a Falcon and ser1 otherwise */
- strcpy( m68k_debug_device,
- ((atari_mch_cookie>>16) == ATARI_MCH_FALCON) ?
- "ser2" : "ser1" );
- }
-
- if (!strcmp( m68k_debug_device, "ser1" )) {
- /* ST-MFP Modem1 serial port init */
- mfp.trn_stat &= ~0x01; /* disable TX */
- mfp.rcv_stat &= ~0x01; /* disable RX */
- mfp.usart_ctr = 0x88; /* clk 1:16, 8N1 */
- mfp.tim_ct_cd &= 0x70; /* stop timer D */
- mfp.tim_dt_d = 2; /* 9600 bps */
- mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */
- mfp.trn_stat |= 0x01; /* enable TX */
- mfp.rcv_stat |= 0x01; /* enable RX */
-
- /* set function pointers */
- serial_in = atari_mfp_in;
- serial_out = atari_mfp_out;
- serial_intr = atari_mfp_intr;
-
- /* allocate interrupt */
- request_irq( IRQ_MFP_RECFULL, kgdb_intr, IRQ_TYPE_FAST, "kgdb",
- NULL );
- }
- else if (!strcmp( m68k_debug_device, "ser2" )) {
- extern int atari_SCC_reset_done;
-
- /* SCC Modem2 serial port init */
- static unsigned char *p, scc_table[] = {
- 9, 0xc0, /* Reset */
- 4, 0x44, /* x16, 1 stopbit, no parity */
- 3, 0xc0, /* receiver: 8 bpc */
- 5, 0xe2, /* transmitter: 8 bpc, assert dtr/rts */
- 2, 0x60, /* base int vector */
- 9, 0x09, /* int enab, with status low */
- 10, 0, /* NRZ */
- 11, 0x50, /* use baud rate generator */
- 12, 24, 13, 0, /* 9600 baud */
- 14, 2, 14, 3, /* use master clock for BRG, enable */
- 3, 0xc1, /* enable receiver */
- 5, 0xea, /* enable transmitter */
- 15, 0, /* no stat ints */
- 1, 0x10, /* Rx int every char, other ints off */
- 0
- };
-
- (void)scc.cha_b_ctrl; /* reset reg pointer */
- MFPDELAY();
- for( p = scc_table; *p != 0; ) {
- scc.cha_b_ctrl = *p++;
- MFPDELAY();
- scc.cha_b_ctrl = *p++;
- MFPDELAY();
- if (p[-2] == 9)
- udelay(40); /* extra delay after WR9 access */
- }
- /* avoid that atari_SCC.c resets the whole SCC again */
- atari_SCC_reset_done = 1;
-
- /* set function pointers */
- serial_in = atari_scc_in;
- serial_out = atari_scc_out;
- serial_intr = atari_scc_intr;
-
- /* allocate rx and spcond ints */
- request_irq( IRQ_SCCB_RX, kgdb_intr, IRQ_TYPE_FAST, "kgdb", NULL );
- request_irq( IRQ_SCCB_SPCOND, kgdb_intr, IRQ_TYPE_FAST, "kgdb",
- NULL );
- }
- }
-#endif
-
-#ifdef CONFIG_AMIGA
- if (MACH_IS_AMIGA) {
- /* always use built-in serial port, no init required */
- serial_in = amiga_ser_in;
- serial_out = amiga_ser_out;
- }
-#endif
-
-#ifdef CONFIG_MAC
- if (MACH_IS_MAC) {
- if (!strcmp( m68k_debug_device, "ser" ) ||
- !strcmp( m68k_debug_device, "ser1" )) {
- mac_init_scc_port( B9600|CS8, 0 );
- serial_in = mac_scca_in;
- serial_out = mac_scca_out;
- serial_intr = mac_scca_intr;
- } else if (!strcmp( m68k_debug_device, "ser2" )) {
- mac_init_scc_port( B9600|CS8, 1 );
- serial_in = mac_sccb_in;
- serial_out = mac_sccb_out;
- serial_intr = mac_sccb_intr;
- }
- }
- if (!serial_in || !serial_out) {
- if (*m68k_debug_device)
- printk( "kgdb_init failed: no valid serial device!\n" );
- else
- printk( "kgdb not enabled\n" );
- return;
- }
- request_irq(4, kgdb_intr, IRQ_TYPE_FAST, "kgdb", NULL);
-#endif
-
-#ifdef CONFIG_ATARI
- if (!serial_in || !serial_out) {
- if (*m68k_debug_device)
- printk( "kgdb_init failed: no valid serial device!\n" );
- else
- printk( "kgdb not enabled\n" );
- return;
- }
-#endif
-
- /*
- * In case GDB is started before us, ack any packets
- * (presumably "$?#xx") sitting there.
- */
-
- putDebugChar ('+');
- kgdb_initialized = 1;
- printk( KERN_INFO "kgdb initialized.\n" );
-}
-
-
-/*
- * Convert the MIPS hardware trap type code to a unix signal number.
- */
-static int computeSignal(int tt)
-{
- struct hard_trap_info *ht;
-
- for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
- if (ht->tt == tt)
- return ht->signo;
-
- return SIGHUP; /* default for things we don't know about */
-}
-
-/*
- * While we find nice hex chars, build an int.
- * Return number of chars processed.
- */
-static int hexToInt(char **ptr, int *intValue)
-{
- int numChars = 0;
- int hexValue;
-
- *intValue = 0;
-
- while (**ptr)
- {
- hexValue = hex(**ptr);
- if (hexValue < 0)
- break;
-
- *intValue = (*intValue << 4) | hexValue;
- numChars ++;
-
- (*ptr)++;
- }
-
- return (numChars);
-}
-
-
-/*
- * This assembler stuff copies a struct frame (passed as argument) into struct
- * gdb_regs registers and then calls handle_exception. After return from
- * there, register and the like are restored from 'registers', the stack is
- * set up and execution is continued where registers->pc tells us.
- */
-
-/* offsets in struct frame */
-#define FRAMEOFF_D1 "0" /* d1..d5 */
-#define FRAMEOFF_A0 "5*4" /* a0..a2 */
-#define FRAMEOFF_D0 "8*4"
-#define FRAMEOFF_SR "11*4"
-#define FRAMEOFF_PC "11*4+2"
-#define FRAMEOFF_VECTOR "12*4+2"
-
-/* offsets in struct gdb_regs */
-#define GDBOFF_D0 "0"
-#define GDBOFF_D1 "1*4"
-#define GDBOFF_D6 "6*4"
-#define GDBOFF_A0 "8*4"
-#define GDBOFF_A3 "11*4"
-#define GDBOFF_A7 "15*4"
-#define GDBOFF_VECTOR "16*4"
-#define GDBOFF_SR "16*4+2"
-#define GDBOFF_PC "17*4"
-#define GDBOFF_FP0 "18*4"
-#define GDBOFF_FPCTL "42*4"
-
-__asm__
-( " .globl " SYMBOL_NAME_STR(enter_kgdb) "\n"
- SYMBOL_NAME_STR(enter_kgdb) ":\n"
- /* return if not initialized */
- " tstl "SYMBOL_NAME_STR(kgdb_initialized)"\n"
- " bne 1f\n"
- " rts \n"
- "1: orw #0x700,%sr\n" /* disable interrupts while in stub */
- " tstl %sp@+\n" /* pop off return address */
- " movel %sp@+,%a0\n" /* get pointer to fp->ptregs (param) */
- " movel #"SYMBOL_NAME_STR(kgdb_registers)",%a1\n" /* destination */
- /* copy d0-d5/a0-a1 into gdb_regs */
- " movel %a0@("FRAMEOFF_D0"),%a1@("GDBOFF_D0")\n"
- " moveml %a0@("FRAMEOFF_D1"),%d1-%d5\n"
- " moveml %d1-%d5,%a1@("GDBOFF_D1")\n"
- " moveml %a0@("FRAMEOFF_A0"),%d0-%d2\n"
- " moveml %d0-%d2,%a1@("GDBOFF_A0")\n"
- /* copy sr and pc */
- " movel %a0@("FRAMEOFF_PC"),%a1@("GDBOFF_PC")\n"
- " movew %a0@("FRAMEOFF_SR"),%a1@("GDBOFF_SR")\n"
- /* copy format/vector word */
- " movew %a0@("FRAMEOFF_VECTOR"),%a1@("GDBOFF_VECTOR")\n"
- /* save FPU regs */
-#ifndef CONFIG_M68KFPU_EMU_ONLY
-#ifdef CONFIG_M68KFPU_EMU
- " tstl "SYMBOL_NAME_STR(m68k_fputype)"\n"
- " jeq 1f\n"
-#endif
- " fmovemx %fp0-%fp7,%a1@("GDBOFF_FP0")\n"
- " fmoveml %fpcr/%fpsr/%fpiar,%a1@("GDBOFF_FPCTL")\n"
- "1:\n"
-#endif /* CONFIG_M68KFPU_EMU_ONLY */
-
- /* set stack to CPU frame */
- " addl #"FRAMEOFF_SR",%a0\n"
- " movel %a0,%sp\n"
- " movew %sp@(6),%d0\n"
- " andl #0xf000,%d0\n"
- " lsrl #8,%d0\n"
- " lsrl #2,%d0\n" /* get frame format << 2 */
- " lea "SYMBOL_NAME_STR(frame_sizes)",%a2\n"
- " addl %a2@(%d0),%sp\n"
- " movel %sp,%a1@("GDBOFF_A7")\n" /* save a7 now */
-
- /* call handle_exception() now that the stack is set up */
- "Lcall_handle_excp:"
- " jsr "SYMBOL_NAME_STR(handle_exception)"\n"
-
- /* after return, first restore FPU registers */
- " movel #"SYMBOL_NAME_STR(kgdb_registers)",%a0\n" /* source */
-#ifndef CONFIG_M68KFPU_EMU_ONLY
-#ifdef CONFIG_M68KFPU_EMU
- " tstl "SYMBOL_NAME_STR(m68k_fputype)"\n"
- " jeq 1f\n"
-#endif
- " fmovemx %a0@("GDBOFF_FP0"),%fp0-%fp7\n"
- " fmoveml %a0@("GDBOFF_FPCTL"),%fpcr/%fpsr/%fpiar\n"
- "1:\n"
-#endif /* CONFIG_M68KFPU_EMU_ONLY */
- /* set new stack pointer */
- " movel %a0@("GDBOFF_A7"),%sp\n"
- " clrw %sp@-\n" /* fake format $0 frame */
- " movel %a0@("GDBOFF_PC"),%sp@-\n" /* new PC into frame */
- " movew %a0@("GDBOFF_SR"),%sp@-\n" /* new SR into frame */
- /* restore general registers */
- " moveml %a0@("GDBOFF_D0"),%d0-%d7/%a0-%a6\n"
- /* and jump to new PC */
- " rte"
- );
-
-
-/*
- * This is the entry point for the serial interrupt handler. It calls the
- * machine specific function pointer 'serial_intr' to get the char that
- * interrupted. If that was C-c, the stub is entered as above, but based on
- * just a struct intframe, not a struct frame.
- */
-
-__asm__
-( SYMBOL_NAME_STR(kgdb_intr) ":\n"
- /* return if not initialized */
- " tstl "SYMBOL_NAME_STR(kgdb_initialized)"\n"
- " bne 1f\n"
- "2: rts \n"
- "1: movel "SYMBOL_NAME_STR(serial_intr)",%a0\n"
- " jsr (%a0)\n" /* get char from serial */
- " cmpb #3,%d0\n" /* is it C-c ? */
- " bne 2b\n" /* no -> just ignore */
- " orw #0x700,%sr\n" /* disable interrupts */
- " subql #1,"SYMBOL_NAME_STR(local_irq_count)"\n"
- " movel %sp@(12),%sp\n" /* revert stack to where 'inthandler' set
- * it up */
- /* restore regs from frame */
- " moveml %sp@+,%d1-%d5/%a0-%a2\n"
- " movel %sp@+,%d0\n"
- " addql #8,%sp\n" /* throw away orig_d0 and stkadj */
- /* save them into 'registers' */
- " moveml %d0-%d7/%a0-%a6,"SYMBOL_NAME_STR(kgdb_registers)"\n"
- " movel #"SYMBOL_NAME_STR(kgdb_registers)",%a1\n" /* destination */
- /* copy sr and pc */
- " movel %sp@(2),%a1@("GDBOFF_PC")\n"
- " movew %sp@,%a1@("GDBOFF_SR")\n"
- /* fake format 0 and vector 1 (translated to SIGINT) */
- " movew #4,%a1@("GDBOFF_VECTOR")\n"
- /* save FPU regs */
-#ifndef CONFIG_M68KFPU_EMU_ONLY
-#ifdef CONFIG_M68KFPU_EMU
- " tstl "SYMBOL_NAME_STR(m68k_fputype)"\n"
- " jeq 1f\n"
-#endif
- " fmovemx %fp0-%fp7,%a1@("GDBOFF_FP0")\n"
- " fmoveml %fpcr/%fpsr/%fpiar,%a1@("GDBOFF_FPCTL")\n"
- "1:\n"
-#endif /* CONFIG_M68KFPU_EMU_ONLY */
- /* pop off the CPU stack frame */
- " addql #8,%sp\n"
- " movel %sp,%a1@("GDBOFF_A7")\n" /* save a7 now */
- /* proceed as in enter_kgdb */
- " jbra Lcall_handle_excp\n"
- );
-
-/*
- * This function does all command processing for interfacing to gdb. It
- * returns 1 if you should skip the instruction at the trap address, 0
- * otherwise.
- */
-static asmlinkage void handle_exception( void )
-{
- int trap; /* Trap type */
- int sigval;
- int addr;
- int length;
- char *ptr;
-
- trap = kgdb_registers.vector >> 2;
- sigval = computeSignal(trap);
- /* clear upper half of vector/sr word */
- kgdb_registers.vector = 0;
- kgdb_registers.format = 0;
-
-#ifndef DEBUG
- if (remote_debug) {
-#endif
- printk("in handle_exception() trap=%d sigval=%d\n", trap, sigval );
- show_gdbregs();
-#ifndef DEBUG
- }
-#endif
-
- /*
- * reply to host that an exception has occurred
- */
- ptr = output_buffer;
-
- /*
- * Send trap type (converted to signal)
- */
- *ptr++ = 'T';
- *ptr++ = hexchars[sigval >> 4];
- *ptr++ = hexchars[sigval & 0xf];
-
- /*
- * Send Error PC
- */
- *ptr++ = hexchars[GDBREG_PC >> 4];
- *ptr++ = hexchars[GDBREG_PC & 0xf];
- *ptr++ = ':';
- ptr = mem2hex((char *)&kgdb_registers.pc, ptr, 4, 0);
- *ptr++ = ';';
-
- /*
- * Send frame pointer
- */
- *ptr++ = hexchars[GDBREG_A6 >> 4];
- *ptr++ = hexchars[GDBREG_A6 & 0xf];
- *ptr++ = ':';
- ptr = mem2hex((char *)&kgdb_registers.regs[GDBREG_A6], ptr, 4, 0);
- *ptr++ = ';';
-
- /*
- * Send stack pointer
- */
- *ptr++ = hexchars[GDBREG_SP >> 4];
- *ptr++ = hexchars[GDBREG_SP & 0xf];
- *ptr++ = ':';
- ptr = mem2hex((char *)&kgdb_registers.regs[GDBREG_SP], ptr, 4, 0);
- *ptr++ = ';';
-
- *ptr++ = 0;
- putpacket(output_buffer,1); /* send it off... */
-
- /*
- * Wait for input from remote GDB
- */
- for(;;) {
- output_buffer[0] = 0;
- getpacket(input_buffer);
-
- switch (input_buffer[0]) {
- case '?':
- output_buffer[0] = 'S';
- output_buffer[1] = hexchars[sigval >> 4];
- output_buffer[2] = hexchars[sigval & 0xf];
- output_buffer[3] = 0;
- break;
-
- case 'd':
- /* toggle debug flag */
- remote_debug = !remote_debug;
- break;
-
- /*
- * Return the value of the CPU registers
- */
- case 'g':
- ptr = output_buffer;
- ptr = mem2hex((char *)&kgdb_registers, ptr, NUMREGSBYTES, 0);
- break;
-
- /*
- * set the value of the CPU registers - return OK
- */
- case 'G':
- ptr = &input_buffer[1];
- ptr = hex2mem(ptr, (char *)&kgdb_registers, NUMREGSBYTES, 0);
- strcpy(output_buffer,"OK");
- break;
-
- /*
- * Pn...=r... Write register n
- */
- case 'P':
- ptr = &input_buffer[1];
- if (hexToInt(&ptr, &addr) && *ptr++ == '=') {
- if (addr >= 0 && addr <= GDBREG_PC)
- hex2mem(ptr, (char *)&kgdb_registers.regs[addr], 4, 0);
- else if (addr >= GDBREG_FP0 && addr <= GDBREG_FP7)
- hex2mem(ptr, (char *)&kgdb_registers.fpregs[addr-GDBREG_FP0],
- 12, 0);
- else if (addr >= GDBREG_FPCR && addr <= GDBREG_FPIAR)
- hex2mem(ptr, (char *)&kgdb_registers.fpcntl[addr-GDBREG_FPCR],
- 4, 0);
- }
- else
- strcpy(output_buffer,"E01");
- break;
-
- /*
- * mAA..AA,LLLL Read LLLL bytes at address AA..AA
- */
- case 'm':
- ptr = &input_buffer[1];
-
- if (hexToInt(&ptr, &addr)
- && *ptr++ == ','
- && hexToInt(&ptr, &length)) {
- if (mem2hex((char *)addr, output_buffer, length, 1))
- break;
- strcpy (output_buffer, "E03");
- } else
- strcpy(output_buffer,"E01");
- break;
-
- /*
- * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK
- */
- case 'M':
- ptr = &input_buffer[1];
-
- if (hexToInt(&ptr, &addr)
- && *ptr++ == ','
- && hexToInt(&ptr, &length)
- && *ptr++ == ':') {
- if (hex2mem(ptr, (char *)addr, length, 1))
- strcpy(output_buffer, "OK");
- else
- strcpy(output_buffer, "E03");
- }
- else
- strcpy(output_buffer, "E02");
- break;
-
- /*
- * cAA..AA Continue at address AA..AA(optional)
- * sAA..AA Step one instruction from AA..AA(optional)
- */
- case 'c':
- case 's':
- /* try to read optional parameter, pc unchanged if no parm */
-
- ptr = &input_buffer[1];
- if (hexToInt(&ptr, &addr))
- kgdb_registers.pc = addr;
-
- kgdb_registers.sr &= 0x7fff; /* clear Trace bit */
- if (input_buffer[0] == 's')
- kgdb_registers.sr |= 0x8000; /* set it if step command */
-
- if (remote_debug)
- printk( "cont; new PC=0x%08lx SR=0x%04x\n",
- kgdb_registers.pc, kgdb_registers.sr );
-
- /*
- * Need to flush the instruction cache here, as we may
- * have deposited a breakpoint, and the icache probably
- * has no way of knowing that a data ref to some location
- * may have changed something that is in the instruction
- * cache.
- */
-
- if (m68k_is040or060)
- __asm__ __volatile__
- ( ".word 0xf4f8\n\t" /* CPUSHA I/D */
- ".word 0xf498" /* CINVA I */
- );
- else
- __asm__ __volatile__
- ( "movec %/cacr,%/d0\n\t"
- "oriw #0x0008,%/d0\n\t"
- "movec %/d0,%/cacr"
- : : : "d0" );
-
- return;
-
- /*
- * kill the program means reset the machine
- */
- case 'k' :
- case 'r':
- if (mach_reset) {
- /* reply OK before actual reset */
- strcpy(output_buffer,"OK");
- putpacket(output_buffer,0);
- mach_reset();
- }
- else
- strcpy(output_buffer,"E01");
- break;
-
- /*
- * Set baud rate (bBB)
- * FIXME: Needs to be written (in gdb, too...)
- */
- case 'b':
- strcpy(output_buffer,"E01");
- break;
-
- } /* switch */
-
- /*
- * reply to the request
- */
-
- putpacket(output_buffer,1);
-
- }
-}
-
-
-/*
- * Print registers (on target console)
- * Used only to debug the stub...
- */
-static void show_gdbregs( void )
-{
- printk( "d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
- kgdb_registers.regs[0], kgdb_registers.regs[1],
- kgdb_registers.regs[2], kgdb_registers.regs[3] );
- printk( "d4: %08lx d5: %08lx d6: %08lx d7: %08lx\n",
- kgdb_registers.regs[4], kgdb_registers.regs[5],
- kgdb_registers.regs[6], kgdb_registers.regs[7] );
- printk( "a0: %08lx a1: %08lx a2: %08lx a3: %08lx\n",
- kgdb_registers.regs[8], kgdb_registers.regs[9],
- kgdb_registers.regs[10], kgdb_registers.regs[11] );
- printk( "a4: %08lx a5: %08lx a6: %08lx a7: %08lx\n",
- kgdb_registers.regs[12], kgdb_registers.regs[13],
- kgdb_registers.regs[14], kgdb_registers.regs[15] );
- printk( "pc: %08lx sr: %04x\n", kgdb_registers.pc, kgdb_registers.sr );
-}
-
-
-/* -------------------- Atari serial I/O -------------------- */
-
-#ifdef CONFIG_ATARI
-
-static int atari_mfp_out( unsigned char c )
-
-{
- while( !(mfp.trn_stat & 0x80) ) /* wait for tx buf empty */
- barrier();
- mfp.usart_dta = c;
- return( 1 );
-}
-
-
-static unsigned char atari_mfp_in( void )
-
-{
- while( !(mfp.rcv_stat & 0x80) ) /* wait for rx buf filled */
- barrier();
- return( mfp.usart_dta );
-}
-
-
-static unsigned char atari_mfp_intr( void )
-
-{
- return( mfp.usart_dta );
-}
-
-
-static int atari_scc_out( unsigned char c )
-
-{
- do {
- MFPDELAY();
- } while( !(scc.cha_b_ctrl & 0x04) ); /* wait for tx buf empty */
- MFPDELAY();
- scc.cha_b_data = c;
- return( 1 );
-}
-
-
-static unsigned char atari_scc_in( void )
-
-{
- do {
- MFPDELAY();
- } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */
- MFPDELAY();
- return( scc.cha_b_data );
-}
-
-
-static unsigned char atari_scc_intr( void )
-
-{ unsigned char c, stat;
-
- MFPDELAY();
- scc.cha_b_ctrl = 1; /* RR1 */
- MFPDELAY();
- stat = scc.cha_b_ctrl;
- MFPDELAY();
- c = scc.cha_b_data;
- MFPDELAY();
- if (stat & 0x30) {
- scc.cha_b_ctrl = 0x30; /* error reset for overrun and parity */
- MFPDELAY();
- }
- scc.cha_b_ctrl = 0x38; /* reset highest IUS */
- MFPDELAY();
- return( c );
-}
-
-#endif
-
-/* -------------------- Macintosh serial I/O -------------------- */
-
-#ifdef CONFIG_MAC
-
-struct SCC
- {
- u_char cha_b_ctrl;
- u_char char_dummy1;
- u_char cha_a_ctrl;
- u_char char_dummy2;
- u_char cha_b_data;
- u_char char_dummy3;
- u_char cha_a_data;
- };
-
-#define scc (*((volatile struct SCC*)mac_bi_data.sccbase))
-
-#define uSEC 1
-#define LONG_DELAY() \
- do { \
- int i; \
- for( i = 60*uSEC; i > 0; --i ) \
- barrier(); \
- } while(0)
-
-static unsigned char mac_sccb_out (unsigned char c)
-{
- int i;
- do {
- LONG_DELAY();
- } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */
- for( i = uSEC; i > 0; --i )
- barrier();
- scc.cha_b_data = c;
-}
-
-static unsigned char mac_scca_out (unsigned char c)
-{
- int i;
- do {
- LONG_DELAY();
- } while (!(scc.cha_a_ctrl & 0x04)); /* wait for tx buf empty */
- for( i = uSEC; i > 0; --i )
- barrier();
- scc.cha_a_data = c;
-}
-
-static unsigned char mac_sccb_in( void )
-{
- do {
- LONG_DELAY();
- } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */
- LONG_DELAY();
- return( scc.cha_b_data );
-}
-
-static unsigned char mac_scca_in( void )
-
-{
- do {
- LONG_DELAY();
- } while( !(scc.cha_a_ctrl & 0x01) ); /* wait for rx buf filled */
- LONG_DELAY();
- return( scc.cha_a_data );
-}
-
-static unsigned char mac_sccb_intr( void )
-
-{ unsigned char c, stat;
-
- LONG_DELAY();
- scc.cha_b_ctrl = 1; /* RR1 */
- LONG_DELAY();
- stat = scc.cha_b_ctrl;
- LONG_DELAY();
- c = scc.cha_b_data;
- LONG_DELAY();
- if (stat & 0x30) {
- scc.cha_b_ctrl = 0x30; /* error reset for overrun and parity */
- LONG_DELAY();
- }
- scc.cha_b_ctrl = 0x38; /* reset highest IUS */
- LONG_DELAY();
- return( c );
-}
-
-static unsigned char mac_scca_intr( void )
-
-{ unsigned char c, stat;
-
- LONG_DELAY();
- scc.cha_a_ctrl = 1; /* RR1 */
- LONG_DELAY();
- stat = scc.cha_a_ctrl;
- LONG_DELAY();
- c = scc.cha_a_data;
- LONG_DELAY();
- if (stat & 0x30) {
- scc.cha_a_ctrl = 0x30; /* error reset for overrun and parity */
- LONG_DELAY();
- }
- scc.cha_a_ctrl = 0x38; /* reset highest IUS */
- LONG_DELAY();
- return( c );
-}
-
-#endif
diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c
index d9750560f..790d153ab 100644
--- a/arch/m68k/kernel/m68k_ksyms.c
+++ b/arch/m68k/kernel/m68k_ksyms.c
@@ -11,7 +11,7 @@
#include <asm/setup.h>
#include <asm/machdep.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/semaphore.h>
@@ -21,6 +21,7 @@
#include <asm/m68kserial.h>
asmlinkage long long __ashrdi3 (long long, int);
+asmlinkage long long __lshrdi3 (long long, int);
extern char m68k_debug_device[];
extern void dump_thread(struct pt_regs *, struct user *);
@@ -57,6 +58,9 @@ EXPORT_SYMBOL(local_bh_count);
EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);
EXPORT_SYMBOL(kernel_thread);
+#ifdef CONFIG_VME
+EXPORT_SYMBOL(vme_brdtype);
+#endif
/* Networking helper routines. */
EXPORT_SYMBOL(csum_partial_copy);
@@ -66,6 +70,7 @@ EXPORT_SYMBOL(csum_partial_copy);
their interface isn't gonna change any time soon now, so
it's OK to leave it out of version control. */
EXPORT_SYMBOL_NOVERS(__ashrdi3);
+EXPORT_SYMBOL_NOVERS(__lshrdi3);
EXPORT_SYMBOL_NOVERS(memcpy);
EXPORT_SYMBOL_NOVERS(memset);
EXPORT_SYMBOL_NOVERS(memcmp);
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index 7db64849d..0dd5870f2 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -87,210 +87,6 @@ static inline int put_reg(struct task_struct *task, int regno,
return 0;
}
-/*
- * This routine gets a long from any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- *
- */
-static unsigned long get_long(struct task_struct * tsk,
- struct vm_area_struct * vma, unsigned long addr)
-{
- pgd_t * pgdir;
- pmd_t * pgmiddle;
- pte_t * pgtable;
- unsigned long page;
-
-repeat:
- pgdir = pgd_offset(vma->vm_mm, addr);
- if (pgd_none(*pgdir)) {
- handle_mm_fault(tsk, vma, addr, 0);
- goto repeat;
- }
- if (pgd_bad(*pgdir)) {
- printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir));
- pgd_clear(pgdir);
- return 0;
- }
- pgmiddle = pmd_offset(pgdir,addr);
- if (pmd_none(*pgmiddle)) {
- handle_mm_fault(tsk, vma, addr, 0);
- goto repeat;
- }
- if (pmd_bad(*pgmiddle)) {
- printk("ptrace: bad page directory %08lx\n",
- pmd_val(*pgmiddle));
- pmd_clear(pgmiddle);
- return 0;
- }
- pgtable = pte_offset(pgmiddle, addr);
- if (!pte_present(*pgtable)) {
- handle_mm_fault(tsk, vma, addr, 0);
- goto repeat;
- }
- page = pte_page(*pgtable);
-/* this is a hack for non-kernel-mapped video buffers and similar */
- if (MAP_NR(page) >= max_mapnr)
- return 0;
- page += addr & ~PAGE_MASK;
- return *(unsigned long *) page;
-}
-
-/*
- * This routine puts a long into any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- *
- * Now keeps R/W state of page so that a text page stays readonly
- * even if a debugger scribbles breakpoints into it. -M.U-
- */
-static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, unsigned long addr,
- unsigned long data)
-{
- pgd_t *pgdir;
- pmd_t *pgmiddle;
- pte_t *pgtable;
- unsigned long page;
-
-repeat:
- pgdir = pgd_offset(vma->vm_mm, addr);
- if (!pgd_present(*pgdir)) {
- handle_mm_fault(tsk, vma, addr, 1);
- goto repeat;
- }
- if (pgd_bad(*pgdir)) {
- printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir));
- pgd_clear(pgdir);
- return;
- }
- pgmiddle = pmd_offset(pgdir,addr);
- if (pmd_none(*pgmiddle)) {
- handle_mm_fault(tsk, vma, addr, 1);
- goto repeat;
- }
- if (pmd_bad(*pgmiddle)) {
- printk("ptrace: bad page directory %08lx\n",
- pmd_val(*pgmiddle));
- pmd_clear(pgmiddle);
- return;
- }
- pgtable = pte_offset(pgmiddle, addr);
- if (!pte_present(*pgtable)) {
- handle_mm_fault(tsk, vma, addr, 1);
- goto repeat;
- }
- page = pte_page(*pgtable);
- if (!pte_write(*pgtable)) {
- handle_mm_fault(tsk, vma, addr, 1);
- goto repeat;
- }
-/* this is a hack for non-kernel-mapped video buffers and similar */
- if (MAP_NR(page) < max_mapnr) {
- *(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
- flush_page_to_ram (page);
- }
-/* we're bypassing pagetables, so we have to set the dirty bit ourselves */
-/* this should also re-instate whatever read-only mode there was before */
- *pgtable = pte_mkdirty(mk_pte(page, vma->vm_page_prot));
- flush_tlb_all();
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls get_long() to read a long.
- */
-static int read_long(struct task_struct * tsk, unsigned long addr,
- unsigned long * result)
-{
- struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
- if (!vma)
- return -EIO;
- if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
- unsigned long low,high;
- struct vm_area_struct * vma_low = vma;
-
- if (addr + sizeof(long) >= vma->vm_end) {
- vma_low = vma->vm_next;
- if (!vma_low || vma_low->vm_start != vma->vm_end)
- return -EIO;
- }
- high = get_long(tsk, vma,addr & ~(sizeof(long)-1));
- low = get_long(tsk, vma_low,(addr+sizeof(long)) & ~(sizeof(long)-1));
- switch (addr & (sizeof(long)-1)) {
- case 3:
- low >>= 8;
- low |= high << 24;
- break;
- case 2:
- low >>= 16;
- low |= high << 16;
- break;
- case 1:
- low >>= 24;
- low |= high << 8;
- break;
- }
- *result = low;
- } else
- *result = get_long(tsk, vma,addr);
- return 0;
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls put_long() to write a long.
- */
-static int write_long(struct task_struct * tsk, unsigned long addr,
- unsigned long data)
-{
- struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
- if (!vma)
- return -EIO;
- if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
- unsigned long low,high;
- struct vm_area_struct * vma_low = vma;
-
- if (addr + sizeof(long) >= vma->vm_end) {
- vma_low = vma->vm_next;
- if (!vma_low || vma_low->vm_start != vma->vm_end)
- return -EIO;
- }
- high = get_long(tsk, vma,addr & ~(sizeof(long)-1));
- low = get_long(tsk, vma_low,(addr+sizeof(long)) & ~(sizeof(long)-1));
- switch (addr & (sizeof(long)-1)) {
- case 0: /* shouldn't happen, but safety first */
- high = data;
- break;
- case 3:
- low &= 0x000000ff;
- low |= data << 8;
- high &= ~0xff;
- high |= data >> 24;
- break;
- case 2:
- low &= 0x0000ffff;
- low |= data << 16;
- high &= ~0xffff;
- high |= data >> 16;
- break;
- case 1:
- low &= 0x00ffffff;
- low |= data << 24;
- high &= ~0xffffff;
- high |= data >> 8;
- break;
- }
- put_long(tsk, vma,addr & ~(sizeof(long)-1),high);
- put_long(tsk, vma_low,(addr+sizeof(long)) & ~(sizeof(long)-1),low);
- } else
- put_long(tsk, vma,addr,data);
- return 0;
-}
-
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
@@ -361,12 +157,13 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: {
unsigned long tmp;
+ int copied;
- down(&child->mm->mmap_sem);
- ret = read_long(child, addr, &tmp);
- up(&child->mm->mmap_sem);
- if (ret >= 0)
- ret = put_user(tmp, (unsigned long *) data);
+ copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+ ret = -EIO;
+ if (copied != sizeof(tmp))
+ goto out;
+ ret = put_user(tmp,(unsigned long *) data);
goto out;
}
@@ -404,9 +201,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
- down(&child->mm->mmap_sem);
- ret = write_long(child,addr,data);
- up(&child->mm->mmap_sem);
+ ret = 0;
+ if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+ goto out;
+ ret = -EIO;
goto out;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
@@ -416,8 +214,6 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
addr = addr >> 2; /* temporary hack. */
- if (addr == PT_ORIG_D0)
- goto out;
if (addr == PT_SR) {
data &= SR_MASK;
data <<= 16;
diff --git a/arch/m68k/kernel/semaphore.c b/arch/m68k/kernel/semaphore.c
index d62b355e1..b873ee9c7 100644
--- a/arch/m68k/kernel/semaphore.c
+++ b/arch/m68k/kernel/semaphore.c
@@ -60,15 +60,11 @@ void __up(struct semaphore *sem)
*
*/
-#define DOWN_VAR \
- struct task_struct *tsk = current; \
- wait_queue_t wait; \
- init_waitqueue_entry(&wait, tsk);
#define DOWN_HEAD(task_state) \
\
\
- tsk->state = (task_state); \
+ current->state = (task_state); \
add_wait_queue(&sem->wait, &wait); \
\
/* \
@@ -89,14 +85,15 @@ void __up(struct semaphore *sem)
for (;;) {
#define DOWN_TAIL(task_state) \
- tsk->state = (task_state); \
+ current->state = (task_state); \
} \
- tsk->state = TASK_RUNNING; \
+ current->state = TASK_RUNNING; \
remove_wait_queue(&sem->wait, &wait);
void __down(struct semaphore * sem)
{
- DOWN_VAR
+ DECLARE_WAITQUEUE(wait, current);
+
DOWN_HEAD(TASK_UNINTERRUPTIBLE)
if (waking_non_zero(sem))
break;
@@ -106,11 +103,12 @@ void __down(struct semaphore * sem)
int __down_interruptible(struct semaphore * sem)
{
+ DECLARE_WAITQUEUE(wait, current);
int ret = 0;
- DOWN_VAR
+
DOWN_HEAD(TASK_INTERRUPTIBLE)
- ret = waking_non_zero_interruptible(sem, tsk);
+ ret = waking_non_zero_interruptible(sem, current);
if (ret)
{
if (ret == 1)
@@ -127,3 +125,111 @@ int __down_trylock(struct semaphore * sem)
{
return waking_non_zero_trylock(sem);
}
+
+
+/* Wait for the lock to become unbiased. Readers
+ * are non-exclusive. =)
+ */
+void down_read_failed(struct rw_semaphore *sem)
+{
+ DECLARE_WAITQUEUE(wait, current);
+
+ __up_read(sem); /* this takes care of granting the lock */
+
+ add_wait_queue(&sem->wait, &wait);
+
+ while (atomic_read(&sem->count) < 0) {
+ set_task_state(current, TASK_UNINTERRUPTIBLE);
+ if (atomic_read(&sem->count) >= 0)
+ break;
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ current->state = TASK_RUNNING;
+}
+
+void down_read_failed_biased(struct rw_semaphore *sem)
+{
+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue(&sem->wait, &wait); /* put ourselves at the head of the list */
+
+ for (;;) {
+ if (sem->read_bias_granted && xchg(&sem->read_bias_granted, 0))
+ break;
+ set_task_state(current, TASK_UNINTERRUPTIBLE);
+ if (!sem->read_bias_granted)
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ current->state = TASK_RUNNING;
+}
+
+
+/* Wait for the lock to become unbiased. Since we're
+ * a writer, we'll make ourselves exclusive.
+ */
+void down_write_failed(struct rw_semaphore *sem)
+{
+ DECLARE_WAITQUEUE(wait, current);
+
+ __up_write(sem); /* this takes care of granting the lock */
+
+ add_wait_queue_exclusive(&sem->wait, &wait);
+
+ while (atomic_read(&sem->count) < 0) {
+ set_task_state(current, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE);
+ if (atomic_read(&sem->count) >= 0)
+ break; /* we must attempt to aquire or bias the lock */
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ current->state = TASK_RUNNING;
+}
+
+void down_write_failed_biased(struct rw_semaphore *sem)
+{
+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue_exclusive(&sem->write_bias_wait, &wait); /* put ourselves at the end of the list */
+
+ for (;;) {
+ if (sem->write_bias_granted && xchg(&sem->write_bias_granted, 0))
+ break;
+ set_task_state(current, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE);
+ if (!sem->write_bias_granted)
+ schedule();
+ }
+
+ remove_wait_queue(&sem->write_bias_wait, &wait);
+ current->state = TASK_RUNNING;
+
+ /* if the lock is currently unbiased, awaken the sleepers
+ * FIXME: this wakes up the readers early in a bit of a
+ * stampede -> bad!
+ */
+ if (atomic_read(&sem->count) >= 0)
+ wake_up(&sem->wait);
+}
+
+
+/* Called when someone has done an up that transitioned from
+ * negative to non-negative, meaning that the lock has been
+ * granted to whomever owned the bias.
+ */
+void rwsem_wake_readers(struct rw_semaphore *sem)
+{
+ if (xchg(&sem->read_bias_granted, 1))
+ BUG();
+ wake_up(&sem->wait);
+}
+
+void rwsem_wake_writer(struct rw_semaphore *sem)
+{
+ if (xchg(&sem->write_bias_granted, 1))
+ BUG();
+ wake_up(&sem->write_bias_wait);
+}
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c
index adafc9879..5f010dd76 100644
--- a/arch/m68k/kernel/setup.c
+++ b/arch/m68k/kernel/setup.c
@@ -10,6 +10,7 @@
#include <linux/config.h>
#include <linux/kernel.h>
+#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -19,6 +20,7 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/init.h>
+#include <linux/bootmem.h>
#include <linux/module.h>
#include <asm/bootinfo.h>
@@ -35,13 +37,19 @@
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h>
-#include <asm/pgtable.h>
+#endif
+
+#ifndef CONFIG_AMIGA
+#define dbprintf printk
#endif
unsigned long m68k_machtype;
unsigned long m68k_cputype;
unsigned long m68k_fputype;
unsigned long m68k_mmutype;
+#ifdef CONFIG_VME
+unsigned long vme_brdtype;
+#endif
int m68k_is040or060 = 0;
@@ -50,6 +58,7 @@ extern unsigned long availmem;
int m68k_num_memory = 0;
int m68k_realnum_memory = 0;
+unsigned long m68k_memoffset;
struct mem_info m68k_memory[NUM_MEMINFO];
static struct mem_info m68k_ramdisk = { 0, 0 };
@@ -91,14 +100,14 @@ int serial_register_serial(struct serial_struct *);
void serial_unregister_serial(int);
long ser_console_init(long, long );
#endif
-#if defined(CONFIG_USERIAL)||defined(CONFIG_BVME6000_SCC)||defined(CONFIG_MVME162_SCC)||defined(CONFIG_HPDCA)||defined(CONFIG_WHIPPET_SERIAL)||defined(CONFIG_MULTIFACE_III_TTY)||defined(CONFIG_GVPIOEXT)||defined(CONFIG_AMIGA_BUILTIN_SERIAL)||defined(CONFIG_MAC_SCC)||defined(CONFIG_ATARI_MIDI)||defined(CONFIG_ATARI_SCC)||defined(CONFIG_ATARI_MFPSER)
+#if defined(CONFIG_USERIAL)||defined(CONFIG_HPDCA)||defined(CONFIG_WHIPPET_SERIAL)||defined(CONFIG_MULTIFACE_III_TTY)||defined(CONFIG_GVPIOEXT)||defined(CONFIG_AMIGA_BUILTIN_SERIAL)||defined(CONFIG_MAC_SCC)||defined(CONFIG_ATARI_MIDI)||defined(CONFIG_ATARI_SCC)||defined(CONFIG_ATARI_MFPSER)
#define M68K_SERIAL
#endif
#ifdef M68K_SERIAL
long m68k_rs_init(void);
int m68k_register_serial(struct serial_struct *);
void m68k_unregister_serial(int);
-long m68k_serial_console_init(long, long );
+long m68k_serial_console_init(void);
#endif
#ifdef CONFIG_HEARTBEAT
void (*mach_heartbeat) (int) = NULL;
@@ -107,8 +116,6 @@ void (*mach_heartbeat) (int) = NULL;
void (*mach_l2_flush) (int) = NULL;
#endif
-extern void base_trap_init(void);
-
#ifdef CONFIG_MAGIC_SYSRQ
int mach_sysrq_key = -1;
int mach_sysrq_shift_state = 0;
@@ -120,6 +127,9 @@ extern int amiga_parse_bootinfo(const struct bi_record *);
extern int atari_parse_bootinfo(const struct bi_record *);
extern int mac_parse_bootinfo(const struct bi_record *);
extern int q40_parse_bootinfo(const struct bi_record *);
+extern int bvme6000_parse_bootinfo(const struct bi_record *);
+extern int mvme16x_parse_bootinfo(const struct bi_record *);
+extern int mvme147_parse_bootinfo(const struct bi_record *);
extern void config_amiga(void);
extern void config_atari(void);
@@ -179,6 +189,12 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
unknown = mac_parse_bootinfo(record);
else if (MACH_IS_Q40)
unknown = q40_parse_bootinfo(record);
+ else if (MACH_IS_BVME6000)
+ unknown = bvme6000_parse_bootinfo(record);
+ else if (MACH_IS_MVME16x)
+ unknown = mvme16x_parse_bootinfo(record);
+ else if (MACH_IS_MVME147)
+ unknown = mvme147_parse_bootinfo(record);
else
unknown = 1;
}
@@ -195,13 +211,14 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
(m68k_num_memory - 1));
m68k_num_memory = 1;
}
+ m68k_memoffset = m68k_memory[0].addr-PAGE_OFFSET;
#endif
}
-void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p,
- unsigned long * memory_end_p)
+void __init setup_arch(char **cmdline_p)
{
extern int _etext, _edata, _end;
+ unsigned long endmem, startmem;
int i;
char *p, *q;
@@ -213,10 +230,6 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p,
else if (CPU_IS_060)
m68k_is040or060 = 6;
-#ifndef CONFIG_SUN3
- base_trap_init();
-#endif
-
/* FIXME: m68k_fputype is passed in by Penguin booter, which can
* be confused by software FPU emulation. BEWARE.
* We should really do our own FPU check at startup.
@@ -339,10 +352,25 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p,
#endif
#ifndef CONFIG_SUN3
- *memory_start_p = availmem;
- *memory_end_p = 0;
+ startmem= m68k_memory[0].addr;
+ endmem = startmem + m68k_memory[0].size;
+ high_memory = PAGE_OFFSET;
+ for (i = 0; i < m68k_num_memory; i++) {
+ m68k_memory[i].size &= MASK_256K;
+ if (m68k_memory[i].addr < startmem)
+ startmem = m68k_memory[i].addr;
+ if (m68k_memory[i].addr+m68k_memory[i].size > endmem)
+ endmem = m68k_memory[i].addr+m68k_memory[i].size;
+ high_memory += m68k_memory[i].size;
+ }
+
+ availmem += init_bootmem_node(0, availmem >> PAGE_SHIFT,
+ startmem >> PAGE_SHIFT, endmem >> PAGE_SHIFT);
+
for (i = 0; i < m68k_num_memory; i++)
- *memory_end_p += m68k_memory[i].size & MASK_256K;
+ free_bootmem(m68k_memory[0].addr, m68k_memory[0].size);
+
+ reserve_bootmem(m68k_memory[0].addr, availmem - m68k_memory[0].addr);
#endif
}
@@ -479,16 +507,16 @@ EXPORT_SYMBOL(register_serial);
EXPORT_SYMBOL(unregister_serial);
#ifdef CONFIG_SERIAL_CONSOLE
-long serial_console_init(long kmem_start, long kmem_end)
+void serial_console_init(void)
{
-#ifdef CONFIG_SERIAL
- if (MACH_IS_Q40)
- return ser_console_init(kmem_start, kmem_end);
+#ifdef CONFIG_Q40_SERIAL
+ if (MACH_IS_Q40) {
+ ser_console_init();
+ return;
+ }
#endif
#if defined(M68K_SERIAL) && defined(CONFIG_SERIAL_CONSOLE)
- return m68k_serial_console_init(kmem_start, kmem_end);
-#else
- return kmem_start;
+ m68k_serial_console_init();
#endif
}
#endif
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index bbff5d590..555b39612 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -37,7 +37,6 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
-#include <linux/highuid.h>
#include <asm/setup.h>
#include <asm/uaccess.h>
@@ -1049,7 +1048,6 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
info.si_code = SI_USER;
info.si_pid = current->p_pptr->pid;
info.si_uid = current->p_pptr->uid;
- info.si_uid16 = high2lowuid(current->p_pptr->uid);
}
/* If the (new) signal is now blocked, requeue it. */
@@ -1076,7 +1074,8 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
continue;
switch (signr) {
- case SIGCONT: case SIGCHLD: case SIGWINCH:
+ case SIGCONT: case SIGCHLD:
+ case SIGWINCH: case SIGURG:
continue;
case SIGTSTP: case SIGTTIN: case SIGTTOU:
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index 1387f594b..46ddcc1a0 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -111,11 +111,12 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg)
a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- error = do_mmap2(file, a.addr, a.len, a.prot, a.flags, a.offset >> PAGE_SHIFT);
+ error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
out:
return error;
}
+#if 0
struct mmap_arg_struct64 {
__u32 addr;
__u32 len;
@@ -160,6 +161,7 @@ out:
up(&current->mm->mmap_sem);
return error;
}
+#endif
extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
index e3a9e560b..db298c997 100644
--- a/arch/m68k/kernel/traps.c
+++ b/arch/m68k/kernel/traps.c
@@ -68,18 +68,37 @@ asm(".text\n"
__ALIGN_STR "\n"
SYMBOL_NAME_STR(nmihandler) ": rte");
+/*
+ * this must be called very early as the kernel might
+ * use some instruction that are emulated on the 060
+ */
void __init base_trap_init(void)
{
-#ifdef CONFIG_SUN3
- /* Keep the keyboard interrupt working with PROM for debugging. --m */
- e_vector *old_vbr;
- __asm__ volatile ("movec %%vbr,%1\n\t"
- "movec %0,%%vbr"
- : "=&r" (old_vbr) : "r" ((void*)vectors));
- vectors[0x1E] = old_vbr[0x1E]; /* Copy int6 vector. */
-#else
/* setup the exception vector table */
__asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));
+
+ if (CPU_IS_060) {
+ /* set up ISP entry points */
+ asmlinkage void unimp_vec(void) asm ("_060_isp_unimp");
+
+ vectors[VEC_UNIMPII] = unimp_vec;
+ }
+}
+
+void __init trap_init (void)
+{
+ int i;
+
+ for (i = 48; i < 64; i++)
+ if (!vectors[i])
+ vectors[i] = trap;
+
+ for (i = 64; i < 256; i++)
+ vectors[i] = inthandler;
+
+#ifdef CONFIG_M68KFPU_EMU
+ if (FPU_IS_EMU)
+ vectors[VEC_LINE11] = fpu_emu;
#endif
if (CPU_IS_040 && !FPU_IS_EMU) {
@@ -104,12 +123,7 @@ void __init base_trap_init(void)
vectors[VEC_LINE11] = fline_vec;
vectors[VEC_FPUNSUP] = unsupp_vec;
}
- if (CPU_IS_060) {
- /* set up ISP entry points */
- asmlinkage void unimp_vec(void) asm ("_060_isp_unimp");
- vectors[VEC_UNIMPII] = unimp_vec;
- }
if (CPU_IS_060 && !FPU_IS_EMU) {
/* set up IFPSP entry points */
asmlinkage void snan_vec(void) asm ("_060_fpsp_snan");
@@ -132,32 +146,11 @@ void __init base_trap_init(void)
vectors[VEC_FPUNSUP] = unsupp_vec;
vectors[VEC_UNIMPEA] = effadd_vec;
}
-}
-
-void __init trap_init (void)
-{
- int i;
-
- for (i = 48; i < 64; i++)
- if (!vectors[i])
- vectors[i] = trap;
-
- for (i = 64; i < 256; i++)
- vectors[i] = inthandler;
-
-#ifdef CONFIG_M68KFPU_EMU
- if (FPU_IS_EMU)
- vectors[VEC_LINE11] = fpu_emu;
-#endif
/* if running on an amiga, make the NMI interrupt do nothing */
if (MACH_IS_AMIGA) {
vectors[VEC_INT7] = nmihandler;
}
-#ifdef CONFIG_SUN3
- /* Moved from setup_arch() */
- base_trap_init();
-#endif
}
diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile
index d1d6b1d7d..22fe6cb6d 100644
--- a/arch/m68k/lib/Makefile
+++ b/arch/m68k/lib/Makefile
@@ -6,6 +6,6 @@
$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $@
L_TARGET = lib.a
-L_OBJS = ashrdi3.o checksum.o memcpy.o memcmp.o memset.o semaphore.o
+L_OBJS = ashrdi3.o lshrdi3.o checksum.o memcpy.o memcmp.o memset.o semaphore.o
include $(TOPDIR)/Rules.make
diff --git a/arch/m68k/lib/lshrdi3.c b/arch/m68k/lib/lshrdi3.c
new file mode 100644
index 000000000..93b1cb6fd
--- /dev/null
+++ b/arch/m68k/lib/lshrdi3.c
@@ -0,0 +1,62 @@
+/* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute 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.
+
+GNU CC is distributed in the hope that 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#define BITS_PER_UNIT 8
+
+typedef int SItype __attribute__ ((mode (SI)));
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef int DItype __attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+ struct DIstruct s;
+ DItype ll;
+} DIunion;
+
+DItype
+__lshrdi3 (DItype u, word_type b)
+{
+ DIunion w;
+ word_type bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0)
+ {
+ w.s.high = 0;
+ w.s.low = (USItype)uu.s.high >> -bm;
+ }
+ else
+ {
+ USItype carries = (USItype)uu.s.high << bm;
+ w.s.high = (USItype)uu.s.high >> b;
+ w.s.low = ((USItype)uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
diff --git a/arch/m68k/lib/semaphore.S b/arch/m68k/lib/semaphore.S
index 842f83f64..c814a1487 100644
--- a/arch/m68k/lib/semaphore.S
+++ b/arch/m68k/lib/semaphore.S
@@ -7,6 +7,7 @@
*/
#include <linux/linkage.h>
+#include <asm/semaphore.h>
/*
* The semaphore operations have a special calling sequence that
@@ -49,3 +50,50 @@ ENTRY(__up_wakeup)
movel (%sp)+,%a1
moveml (%sp)+,%a0/%d0/%d1
rts
+
+ENTRY(__down_read_failed)
+ moveml %a0/%d0/%d1,-(%sp)
+ jcc 3f
+1: movel %a1,-(%sp)
+ jbsr SYMBOL_NAME(down_read_failed_biased)
+ movel (%sp)+,%a1
+2: moveml (%sp)+,%a0/%d0/%d1
+ rts
+
+3: movel %a1,-(%sp)
+ jbsr SYMBOL_NAME(down_read_failed)
+ movel (%sp)+,%a1
+ subql #1,%a1@
+ jpl 2b
+ jcc 3b
+ jra 1b
+
+ENTRY(__down_write_failed)
+ moveml %a0/%d0/%d1,-(%sp)
+ jcc 3f
+1: movel %a1,-(%sp)
+ jbsr SYMBOL_NAME(down_write_failed_biased)
+ movel (%sp)+,%a1
+2: moveml (%sp)+,%a0/%d0/%d1
+ rts
+
+3: movel %a1,-(%sp)
+ jbsr SYMBOL_NAME(down_write_failed)
+ movel (%sp)+,%a1
+ subl #RW_LOCK_BIAS,%a1@
+ jpl 2b
+ jcc 3b
+ jra 1b
+
+ENTRY(__rwsem_wake)
+ moveml %a0/%d0/%d1,-(%sp)
+ jeq 1f
+ movel %a1,-(%sp)
+ jbsr SYMBOL_NAME(rwsem_wake_readers)
+ jra 2f
+1: movel %a1,-(%sp)
+ jbsr rwsem_wake_writer
+2: movel (%sp)+,%a1
+ moveml (%sp)+,%a0/%d0/%d1
+ rts
+
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index c66db0652..c88c4c167 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -14,7 +14,7 @@
#include <asm/traps.h>
#include <asm/system.h>
#include <asm/uaccess.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
extern void die_if_kernel(char *, struct pt_regs *, long);
extern const int frame_extra_sizes[]; /* in m68k/kernel/signal.c */
diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c
index 3442c1cfa..5e7741ee1 100644
--- a/arch/m68k/mm/init.c
+++ b/arch/m68k/mm/init.c
@@ -16,6 +16,7 @@
#include <linux/string.h>
#include <linux/types.h>
#include <linux/init.h>
+#include <linux/bootmem.h>
#ifdef CONFIG_BLK_DEV_RAM
#include <linux/blk.h>
#endif
@@ -23,7 +24,7 @@
#include <asm/setup.h>
#include <asm/uaccess.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/system.h>
#include <asm/machdep.h>
#include <asm/io.h>
@@ -31,6 +32,8 @@
#include <asm/atari_stram.h>
#endif
+static unsigned long totalram_pages = 0;
+
#ifdef CONFIG_SUN3
void mmu_emu_reserve_pages(unsigned long max_page);
#endif
@@ -77,7 +80,7 @@ unsigned long empty_bad_page;
pte_t __bad_page(void)
{
memset ((void *)empty_bad_page, 0, PAGE_SIZE);
- return pte_mkdirty(mk_pte(empty_bad_page, PAGE_SHARED));
+ return pte_mkdirty(__mk_pte(empty_bad_page, PAGE_SHARED));
}
unsigned long empty_zero_page;
@@ -127,7 +130,7 @@ extern char __init_begin, __init_end;
extern pmd_t *zero_pgtable;
-void __init mem_init(unsigned long start_mem, unsigned long end_mem)
+void __init mem_init(void)
{
int codepages = 0;
int datapages = 0;
@@ -135,15 +138,7 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem)
unsigned long tmp;
int i;
- end_mem &= PAGE_MASK;
- high_memory = (void *) end_mem;
- max_mapnr = num_physpages = MAP_NR(end_mem);
-
- tmp = start_mem = PAGE_ALIGN(start_mem);
- while (tmp < end_mem) {
- clear_bit(PG_reserved, &mem_map[MAP_NR(tmp)].flags);
- tmp += PAGE_SIZE;
- }
+ max_mapnr = num_physpages = MAP_NR(high_memory);
#ifdef CONFIG_ATARI
if (MACH_IS_ATARI)
@@ -155,11 +150,17 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem)
mmu_emu_reserve_pages(max_mapnr);
#endif
- for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
+ /* this will put all memory onto the freelists */
+ totalram_pages = free_all_bootmem();
+ printk("tp:%ld\n", totalram_pages);
+
+ for (tmp = PAGE_OFFSET ; tmp < (unsigned long)high_memory; tmp += PAGE_SIZE) {
+#if 0
#ifndef CONFIG_SUN3
if (virt_to_phys ((void *)tmp) >= mach_max_dma_address)
clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
#endif
+#endif
if (PageReserved(mem_map+MAP_NR(tmp))) {
if (tmp >= (unsigned long)&_text
&& tmp < (unsigned long)&_etext)
@@ -171,12 +172,14 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem)
datapages++;
continue;
}
+#if 0
set_page_count(mem_map+MAP_NR(tmp), 1);
#ifdef CONFIG_BLK_DEV_INITRD
if (!initrd_start ||
(tmp < (initrd_start & PAGE_MASK) || tmp >= initrd_end))
#endif
free_page(tmp);
+#endif
}
#ifndef CONFIG_SUN3
@@ -184,7 +187,7 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem)
init_pointer_table((unsigned long)kernel_pg_dir);
for (i = 0; i < PTRS_PER_PGD; i++) {
if (pgd_present(kernel_pg_dir[i]))
- init_pointer_table(pgd_page(kernel_pg_dir[i]));
+ init_pointer_table(__pgd_page(kernel_pg_dir[i]));
}
/* insert also pointer table that we used to unmap the zero page */
@@ -193,22 +196,35 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem)
#endif
printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n",
- (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
+ (unsigned long)nr_free_pages() << (PAGE_SHIFT-10),
max_mapnr << (PAGE_SHIFT-10),
codepages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10),
initpages << (PAGE_SHIFT-10));
}
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(mem_map + MAP_NR(start));
+ set_page_count(mem_map+MAP_NR(start), 1);
+ free_page(start);
+ totalram_pages++;
+ }
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
+
void si_meminfo(struct sysinfo *val)
{
unsigned long i;
i = max_mapnr;
- val->totalram = 0;
+ val->totalram = totalram_pages;
val->sharedram = 0;
- val->freeram = nr_free_pages << PAGE_SHIFT;
- val->bufferram = atomic_read(&buffermem);
+ val->freeram = nr_free_pages();
+ val->bufferram = atomic_read(&buffermem_pages);
while (i-- > 0) {
if (PageReserved(mem_map+i))
continue;
@@ -217,7 +233,7 @@ void si_meminfo(struct sysinfo *val)
continue;
val->sharedram += page_count(mem_map+i) - 1;
}
- val->totalram <<= PAGE_SHIFT;
- val->sharedram <<= PAGE_SHIFT;
+ val->totalhigh = 0;
+ val->freehigh = 0;
return;
}
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
index 86041c373..55a455423 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -18,7 +18,7 @@
#include <asm/setup.h>
#include <asm/segment.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/io.h>
#include <asm/system.h>
diff --git a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c
index 0bf9691dd..a0a5336ed 100644
--- a/arch/m68k/mm/memory.c
+++ b/arch/m68k/mm/memory.c
@@ -16,7 +16,7 @@
#include <asm/setup.h>
#include <asm/segment.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/system.h>
#include <asm/traps.h>
#include <asm/io.h>
@@ -46,8 +46,8 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
pte = (pte_t *) __get_free_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (pte) {
- clear_page((unsigned long)pte);
- flush_page_to_ram((unsigned long)pte);
+ clear_page(pte);
+ __flush_page_to_ram((unsigned long)pte);
flush_tlb_kernel_page((unsigned long)pte);
nocache_page((unsigned long)pte);
pmd_set(pmd, pte);
@@ -61,7 +61,7 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
__bad_pte(pmd);
return NULL;
}
- return (pte_t *) pmd_page(*pmd) + offset;
+ return (pte_t *)__pmd_page(*pmd) + offset;
}
pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset)
@@ -82,7 +82,7 @@ pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset)
__bad_pmd(pgd);
return NULL;
}
- return (pmd_t *) pgd_page(*pgd) + offset;
+ return (pmd_t *)__pgd_page(*pgd) + offset;
}
@@ -90,11 +90,12 @@ pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset)
struct page instead of separately kmalloced struct. Stolen from
arch/sparc/mm/srmmu.c ... */
-typedef struct page ptable_desc;
-static ptable_desc ptable_list = { &ptable_list, &ptable_list };
+typedef struct list_head ptable_desc;
+static LIST_HEAD(ptable_list);
-#define PD_MARKBITS(dp) (*(unsigned char *)&(dp)->offset)
-#define PAGE_PD(page) ((ptable_desc *)&mem_map[MAP_NR(page)])
+#define PD_PTABLE(page) ((ptable_desc *)&mem_map[MAP_NR(page)])
+#define PD_PAGE(ptable) (list_entry(ptable, struct page, list))
+#define PD_MARKBITS(dp) (*(unsigned char *)&PD_PAGE(dp)->index)
#define PTABLE_SIZE (PTRS_PER_PMD * sizeof(pmd_t))
@@ -104,11 +105,10 @@ void __init init_pointer_table(unsigned long ptable)
unsigned long page = ptable & PAGE_MASK;
unsigned char mask = 1 << ((ptable - page)/PTABLE_SIZE);
- dp = PAGE_PD(page);
+ dp = PD_PTABLE(page);
if (!(PD_MARKBITS(dp) & mask)) {
PD_MARKBITS(dp) = 0xff;
- (dp->prev = ptable_list.prev)->next = dp;
- (dp->next = &ptable_list)->prev = dp;
+ list_add(dp, &ptable_list);
}
PD_MARKBITS(dp) &= ~mask;
@@ -117,8 +117,8 @@ void __init init_pointer_table(unsigned long ptable)
#endif
/* unreserve the page so it's possible to free that page */
- dp->flags &= ~(1 << PG_reserved);
- atomic_set(&dp->count, 1);
+ PD_PAGE(dp)->flags &= ~(1 << PG_reserved);
+ atomic_set(&PD_PAGE(dp)->count, 1);
return;
}
@@ -146,36 +146,31 @@ pmd_t *get_pointer_table (void)
flush_tlb_kernel_page(page);
nocache_page (page);
- new = PAGE_PD(page);
+ new = PD_PTABLE(page);
PD_MARKBITS(new) = 0xfe;
- (new->prev = dp->prev)->next = new;
- (new->next = dp)->prev = new;
+ list_add_tail(new, dp);
+
return (pmd_t *)page;
}
- for (tmp = 1, off = 0; (mask & tmp) == 0; tmp <<= 1, off += PTABLE_SIZE);
+ for (tmp = 1, off = 0; (mask & tmp) == 0; tmp <<= 1, off += PTABLE_SIZE)
+ ;
PD_MARKBITS(dp) = mask & ~tmp;
if (!PD_MARKBITS(dp)) {
- ptable_desc *last, *next;
-
/* move to end of list */
- next = dp->next;
- (next->prev = dp->prev)->next = next;
-
- last = ptable_list.prev;
- (dp->next = last->next)->prev = dp;
- (dp->prev = last)->next = dp;
+ list_del(dp);
+ list_add_tail(dp, &ptable_list);
}
- return (pmd_t *) (page_address(dp) + off);
+ return (pmd_t *) (page_address(PD_PAGE(dp)) + off);
}
int free_pointer_table (pmd_t *ptable)
{
- ptable_desc *dp, *first;
+ ptable_desc *dp;
unsigned long page = (unsigned long)ptable & PAGE_MASK;
unsigned char mask = 1 << (((unsigned long)ptable - page)/PTABLE_SIZE);
- dp = PAGE_PD(page);
+ dp = PD_PTABLE(page);
if (PD_MARKBITS (dp) & mask)
panic ("table already free!");
@@ -183,21 +178,17 @@ int free_pointer_table (pmd_t *ptable)
if (PD_MARKBITS(dp) == 0xff) {
/* all tables in page are free, free page */
- ptable_desc *next = dp->next;
- (next->prev = dp->prev)->next = next;
+ list_del(dp);
cache_page (page);
free_page (page);
return 1;
- } else if ((first = ptable_list.next) != dp) {
+ } else if (ptable_list.next != dp) {
/*
* move this descriptor to the front of the list, since
* it has one or more free tables.
*/
- ptable_desc *next = dp->next;
- (next->prev = dp->prev)->next = next;
-
- (dp->prev = first->prev)->next = dp;
- (dp->next = first)->prev = dp;
+ list_del(dp);
+ list_add(dp, &ptable_list);
}
return 0;
}
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c
index 7b463b895..456520a64 100644
--- a/arch/m68k/mm/motorola.c
+++ b/arch/m68k/mm/motorola.c
@@ -17,6 +17,7 @@
#include <linux/string.h>
#include <linux/types.h>
#include <linux/init.h>
+#include <linux/bootmem.h>
#ifdef CONFIG_BLK_DEV_RAM
#include <linux/blk.h>
#endif
@@ -24,10 +25,11 @@
#include <asm/setup.h>
#include <asm/uaccess.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/system.h>
#include <asm/machdep.h>
#include <asm/io.h>
+#include <asm/dma.h>
#ifdef CONFIG_ATARI
#include <asm/atari_stram.h>
#endif
@@ -43,15 +45,14 @@
unsigned long mm_cachebits = 0;
#endif
-static pte_t * __init kernel_page_table(unsigned long *memavailp)
+static pte_t * __init kernel_page_table(void)
{
pte_t *ptablep;
- ptablep = (pte_t *)*memavailp;
- *memavailp += PAGE_SIZE;
+ ptablep = (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
- clear_page((unsigned long)ptablep);
- flush_page_to_ram((unsigned long) ptablep);
+ clear_page(ptablep);
+ __flush_page_to_ram((unsigned long) ptablep);
flush_tlb_kernel_page((unsigned long) ptablep);
nocache_page ((unsigned long)ptablep);
@@ -61,7 +62,7 @@ static pte_t * __init kernel_page_table(unsigned long *memavailp)
static pmd_t *last_pgtable __initdata = NULL;
pmd_t *zero_pgtable __initdata = NULL;
-static pmd_t * __init kernel_ptr_table(unsigned long *memavailp)
+static pmd_t * __init kernel_ptr_table(void)
{
if (!last_pgtable) {
unsigned long pmd, last;
@@ -75,7 +76,7 @@ static pmd_t * __init kernel_ptr_table(unsigned long *memavailp)
for (i = 0; i < PTRS_PER_PGD; i++) {
if (!pgd_present(kernel_pg_dir[i]))
continue;
- pmd = pgd_page(kernel_pg_dir[i]);
+ pmd = __pgd_page(kernel_pg_dir[i]);
if (pmd > last)
last = pmd;
}
@@ -87,11 +88,10 @@ static pmd_t * __init kernel_ptr_table(unsigned long *memavailp)
}
if (((unsigned long)(last_pgtable + PTRS_PER_PMD) & ~PAGE_MASK) == 0) {
- last_pgtable = (pmd_t *)*memavailp;
- *memavailp += PAGE_SIZE;
+ last_pgtable = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
- clear_page((unsigned long)last_pgtable);
- flush_page_to_ram((unsigned long)last_pgtable);
+ clear_page(last_pgtable);
+ __flush_page_to_ram((unsigned long)last_pgtable);
flush_tlb_kernel_page((unsigned long)last_pgtable);
nocache_page((unsigned long)last_pgtable);
} else
@@ -101,7 +101,7 @@ static pmd_t * __init kernel_ptr_table(unsigned long *memavailp)
}
static unsigned long __init
-map_chunk (unsigned long addr, long size, unsigned long *memavailp)
+map_chunk (unsigned long addr, long size)
{
#define PTRTREESIZE (256*1024)
#define ROOTTREESIZE (32*1024*1024)
@@ -137,7 +137,7 @@ map_chunk (unsigned long addr, long size, unsigned long *memavailp)
}
}
if (!pgd_present(*pgd_dir)) {
- pmd_dir = kernel_ptr_table(memavailp);
+ pmd_dir = kernel_ptr_table();
#ifdef DEBUG
printk ("[new pointer %p]", pmd_dir);
#endif
@@ -157,7 +157,7 @@ map_chunk (unsigned long addr, long size, unsigned long *memavailp)
#ifdef DEBUG
printk ("[zero map]");
#endif
- zero_pgtable = kernel_ptr_table(memavailp);
+ zero_pgtable = kernel_ptr_table();
pte_dir = (pte_t *)zero_pgtable;
pmd_dir->pmd[0] = virt_to_phys(pte_dir) |
_PAGE_TABLE | _PAGE_ACCESSED;
@@ -173,7 +173,7 @@ map_chunk (unsigned long addr, long size, unsigned long *memavailp)
#ifdef DEBUG
printk ("[new table]");
#endif
- pte_dir = kernel_page_table(memavailp);
+ pte_dir = kernel_page_table();
pmd_set(pmd_dir, pte_dir);
}
pte_dir = pte_offset(pmd_dir, virtaddr);
@@ -196,7 +196,6 @@ map_chunk (unsigned long addr, long size, unsigned long *memavailp)
return virtaddr;
}
-extern unsigned long free_area_init(unsigned long, unsigned long);
extern unsigned long empty_bad_page_table;
extern unsigned long empty_bad_page;
@@ -204,11 +203,11 @@ extern unsigned long empty_bad_page;
* paging_init() continues the virtual memory environment setup which
* was begun by the code in arch/head.S.
*/
-unsigned long __init paging_init(unsigned long start_mem,
- unsigned long end_mem)
+void __init paging_init(void)
{
int chunk;
unsigned long mem_avail = 0;
+ unsigned int zones_size[3] = { 0, };
#ifdef DEBUG
{
@@ -248,7 +247,7 @@ unsigned long __init paging_init(unsigned long start_mem,
for (chunk = 0; chunk < m68k_num_memory; chunk++) {
mem_avail = map_chunk (m68k_memory[chunk].addr,
- m68k_memory[chunk].size, &start_mem);
+ m68k_memory[chunk].size);
}
@@ -263,12 +262,9 @@ unsigned long __init paging_init(unsigned long start_mem,
* initialize the bad page table and bad page to point
* to a couple of allocated pages
*/
- empty_bad_page_table = start_mem;
- start_mem += PAGE_SIZE;
- empty_bad_page = start_mem;
- start_mem += PAGE_SIZE;
- empty_zero_page = start_mem;
- start_mem += PAGE_SIZE;
+ empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+ empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+ empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
memset((void *)empty_zero_page, 0, PAGE_SIZE);
/*
@@ -279,7 +275,14 @@ unsigned long __init paging_init(unsigned long start_mem,
#ifdef DEBUG
printk ("before free_area_init\n");
#endif
- return PAGE_ALIGN(free_area_init(start_mem, end_mem));
+ zones_size[0] = (mach_max_dma_address < (unsigned long)high_memory ?
+ mach_max_dma_address : (unsigned long)high_memory);
+ zones_size[1] = (unsigned long)high_memory - zones_size[0];
+
+ zones_size[0] = (zones_size[0] - PAGE_OFFSET) >> PAGE_SHIFT;
+ zones_size[1] >>= PAGE_SHIFT;
+
+ free_area_init(zones_size);
}
extern char __init_begin, __init_end;
diff --git a/arch/m68k/mm/sun3mmu.c b/arch/m68k/mm/sun3mmu.c
index 0d3277de0..bd59fecba 100644
--- a/arch/m68k/mm/sun3mmu.c
+++ b/arch/m68k/mm/sun3mmu.c
@@ -80,7 +80,7 @@ unsigned long __init paging_init(unsigned long start_mem,
/* now change pg_table to kernel virtual addresses */
pg_table = (pte_t *) __va ((unsigned long) pg_table);
for (i=0; i<PTRS_PER_PTE; ++i, ++pg_table) {
- pte_t pte = mk_pte (address, PAGE_INIT);
+ pte_t pte = __mk_pte(address, PAGE_INIT);
if (address >= end_mem)
pte_val (pte) = 0;
set_pte (pg_table, pte);
diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c
index 774690012..c27a18279 100644
--- a/arch/m68k/mvme147/config.c
+++ b/arch/m68k/mvme147/config.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/major.h>
+#include <asm/bootinfo.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/setup.h>
@@ -62,6 +63,14 @@ static int bcd2int (unsigned char b);
void (*tick_handler)(int, void *, struct pt_regs *);
+int mvme147_parse_bootinfo(const struct bi_record *bi)
+{
+ if (bi->tag == BI_VME_TYPE || bi->tag == BI_VME_BRDINFO)
+ return 0;
+ else
+ return 1;
+}
+
int mvme147_kbdrate (struct kbd_repeat *k)
{
return 0;
@@ -109,6 +118,10 @@ void __init config_mvme147(void)
disable_irq = mvme147_disable_irq;
mach_get_model = mvme147_get_model;
mach_get_hardware_list = mvme147_get_hardware_list;
+
+ /* Board type is only set by newer versions of vmelilo/tftplilo */
+ if (!vme_brdtype)
+ vme_brdtype = VME_TYPE_MVME147;
}
diff --git a/arch/m68k/mvme16x/Makefile b/arch/m68k/mvme16x/Makefile
index bb7485ab8..1c6bfd3ca 100644
--- a/arch/m68k/mvme16x/Makefile
+++ b/arch/m68k/mvme16x/Makefile
@@ -9,6 +9,6 @@
O_TARGET := mvme16x.o
O_OBJS := config.o 16xints.o rtc.o
-#OX_OBJS = ksyms.o
+OX_OBJS := mvme16x_ksyms.o
include $(TOPDIR)/Rules.make
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
index 2f5d5689a..3c93562f9 100644
--- a/arch/m68k/mvme16x/config.c
+++ b/arch/m68k/mvme16x/config.c
@@ -14,7 +14,6 @@
* for more details.
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/mm.h>
@@ -25,6 +24,7 @@
#include <linux/init.h>
#include <linux/major.h>
+#include <asm/bootinfo.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/setup.h>
@@ -35,6 +35,7 @@
int atari_SCC_reset_done = 1; /* So SCC doesn't get reset */
u_long atari_mch_cookie = 0;
+extern t_bdid mvme_bdid;
static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE;
@@ -71,6 +72,14 @@ static void (*tick_handler)(int, void *, struct pt_regs *);
unsigned short mvme16x_config;
+int mvme16x_parse_bootinfo(const struct bi_record *bi)
+{
+ if (bi->tag == BI_VME_TYPE || bi->tag == BI_VME_BRDINFO)
+ return 0;
+ else
+ return 1;
+}
+
int mvme16x_kbdrate (struct kbd_repeat *k)
{
return 0;
@@ -91,7 +100,7 @@ void mvme16x_reset()
static void mvme16x_get_model(char *model)
{
- p_bdid p = (p_bdid)mvme_bdid_ptr;
+ p_bdid p = &mvme_bdid;
char suf[4];
suf[1] = p->brdsuffix[0];
@@ -105,7 +114,7 @@ static void mvme16x_get_model(char *model)
static int mvme16x_get_hardware_list(char *buffer)
{
- p_bdid p = (p_bdid)mvme_bdid_ptr;
+ p_bdid p = &mvme_bdid;
int len = 0;
if (p->brdno == 0x0162 || p->brdno == 0x0172)
@@ -133,7 +142,7 @@ static int mvme16x_get_hardware_list(char *buffer)
void __init config_mvme16x(void)
{
- p_bdid p = (p_bdid)mvme_bdid_ptr;
+ p_bdid p = &mvme_bdid;
char id[40];
mach_sched_init = mvme16x_sched_init;
@@ -163,6 +172,10 @@ void __init config_mvme16x(void)
while (1)
;
}
+ /* Board type is only set by newer versions of vmelilo/tftplilo */
+ if (vme_brdtype == 0)
+ vme_brdtype = p->brdno;
+
mvme16x_get_model(id);
printk ("\nBRD_ID: %s BUG %x.%x %02x/%02x/%02x\n", id, p->rev>>4,
p->rev&0xf, p->yr, p->mth, p->day);
@@ -199,7 +212,7 @@ void __init config_mvme16x(void)
static void mvme16x_abort_int (int irq, void *dev_id, struct pt_regs *fp)
{
- p_bdid p = (p_bdid)mvme_bdid_ptr;
+ p_bdid p = &mvme_bdid;
unsigned long *new = (unsigned long *)vectors;
unsigned long *old = (unsigned long *)0xffe00000;
volatile unsigned char uc, *ucp;
@@ -232,7 +245,7 @@ static void mvme16x_timer_int (int irq, void *dev_id, struct pt_regs *fp)
void mvme16x_sched_init (void (*timer_routine)(int, void *, struct pt_regs *))
{
- p_bdid p = (p_bdid)mvme_bdid_ptr;
+ p_bdid p = &mvme_bdid;
int irq;
tick_handler = timer_routine;
@@ -294,80 +307,3 @@ int mvme16x_keyb_init (void)
return 0;
}
-/*------------------- Serial console stuff ------------------------*/
-
-extern void mvme167_serial_console_setup(int cflag);
-extern void serial167_write(struct console *co, const char *str, unsigned cnt);
-extern void vme_scc_write(struct console *co, const char *str, unsigned cnt);
-
-
-void mvme16x_init_console_port (struct console *co, int cflag)
-{
- p_bdid p = (p_bdid)mvme_bdid_ptr;
-
- switch (p->brdno)
- {
-#ifdef CONFIG_MVME162_SCC
- case 0x0162:
- case 0x0172:
- co->write = vme_scc_write;
- return;
-#endif
-#ifdef CONFIG_SERIAL167
- case 0x0166:
- case 0x0167:
- case 0x0176:
- case 0x0177:
- co->write = serial167_write;
- mvme167_serial_console_setup (cflag);
- return;
-#endif
- default:
- panic ("No console support for MVME%x\n", p->brdno);
- }
- return;
-}
-
-
-#ifdef CONFIG_MVME162_SCC
-
-static void scc_delay (void)
-{
- int n;
- volatile int trash;
-
- for (n = 0; n < 20; n++)
- trash = n;
-}
-
-static void scc_write (char ch)
-{
- volatile char *p = (volatile char *)MVME_SCC_A_ADDR;
-
- do {
- scc_delay();
- }
- while (!(*p & 4));
- scc_delay();
- *p = 8;
- scc_delay();
- *p = ch;
-}
-
-
-void vme_scc_write (struct console *co, const char *str, unsigned count)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
-
- while (count--)
- {
- if (*str == '\n')
- scc_write ('\r');
- scc_write (*str++);
- }
- restore_flags(flags);
-}
-#endif
diff --git a/arch/m68k/mvme16x/mvme16x_ksyms.c b/arch/m68k/mvme16x/mvme16x_ksyms.c
new file mode 100644
index 000000000..7185bb0f0
--- /dev/null
+++ b/arch/m68k/mvme16x/mvme16x_ksyms.c
@@ -0,0 +1,6 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <asm/ptrace.h>
+#include <asm/mvme16xhw.h>
+
+EXPORT_SYMBOL(mvme16x_config);
diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c
index 75efb8bd6..f5f472132 100644
--- a/arch/m68k/mvme16x/rtc.c
+++ b/arch/m68k/mvme16x/rtc.c
@@ -67,8 +67,9 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
}
case RTC_SET_TIME: /* Set the RTC */
{
- unsigned char leap_yr;
struct rtc_time rtc_tm;
+ unsigned char mon, day, hrs, min, sec, leap_yr;
+ unsigned int yrs;
if (!suser())
return -EACCES;
@@ -77,31 +78,41 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
sizeof(struct rtc_time)))
return -EFAULT;
- leap_yr = ((!(rtc_tm.tm_year % 4) && (rtc_tm.tm_year % 100)) || !(rtc_tm.tm_year % 400));
+ yrs = rtc_tm.tm_year;
+ if (yrs < 1900)
+ yrs += 1900;
+ mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */
+ day = rtc_tm.tm_mday;
+ hrs = rtc_tm.tm_hour;
+ min = rtc_tm.tm_min;
+ sec = rtc_tm.tm_sec;
- if ((rtc_tm.tm_mon > 12) || (rtc_tm.tm_mday == 0))
+ leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
+
+ if ((mon > 12) || (day == 0))
return -EINVAL;
- if (rtc_tm.tm_mday > (days_in_mo[rtc_tm.tm_mon] + ((rtc_tm.tm_mon == 2) && leap_yr)))
+ if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
return -EINVAL;
-
- if ((rtc_tm.tm_hour >= 24) || (rtc_tm.tm_min >= 60) || (rtc_tm.tm_sec >= 60))
+
+ if ((hrs >= 24) || (min >= 60) || (sec >= 60))
return -EINVAL;
+ if (yrs >= 2070)
+ return -EINVAL;
+
save_flags(flags);
cli();
- rtc->ctrl = RTC_WRITE;
+ rtc->ctrl = RTC_WRITE;
- rtc->bcd_sec = BIN2BCD(rtc_tm.tm_sec);
- rtc->bcd_min = BIN2BCD(rtc_tm.tm_min);
- rtc->bcd_hr = BIN2BCD(rtc_tm.tm_hour);
- rtc->bcd_dom = BIN2BCD(rtc_tm.tm_mday);
- rtc->bcd_mth = BIN2BCD(rtc_tm.tm_mon + 1);
- rtc->bcd_year = BIN2BCD(rtc_tm.tm_year%100);
- if (rtc_tm.tm_wday >= 0)
- rtc->bcd_dow = BIN2BCD(rtc_tm.tm_wday+1);
+ rtc->bcd_sec = BIN2BCD(sec);
+ rtc->bcd_min = BIN2BCD(min);
+ rtc->bcd_hr = BIN2BCD(hrs);
+ rtc->bcd_dom = BIN2BCD(day);
+ rtc->bcd_mth = BIN2BCD(mon);
+ rtc->bcd_year = BIN2BCD(yrs%100);
- rtc->ctrl = 0;
+ rtc->ctrl = 0;
restore_flags(flags);
return 0;
}
diff --git a/arch/m68k/sun3/Makefile b/arch/m68k/sun3/Makefile
index 998a4eee1..9a34b3034 100644
--- a/arch/m68k/sun3/Makefile
+++ b/arch/m68k/sun3/Makefile
@@ -11,6 +11,7 @@
$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -Wa,-m68020 -c $< -o $*.o
O_TARGET := sun3.o
-O_OBJS := config.o idprom.o mmu_emu.o sun3ints.o leds.o dvma.o sbus.o
+O_OBJS := config.o idprom.o mmu_emu.o sun3ints.o leds.o dvma.o sbus.o intersil.o
+OX_OBJS := sun3_ksyms.o
include $(TOPDIR)/Rules.make
diff --git a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c
index 05fbdea8d..87bae8a51 100644
--- a/arch/m68k/sun3/config.c
+++ b/arch/m68k/sun3/config.c
@@ -36,7 +36,7 @@ extern char _text, _end;
static int kernel_start, kernel_end;
char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
-static unsigned long sun3_gettimeoffset(void);
+extern unsigned long sun3_gettimeoffset(void);
extern int sun3_get_irq_list (char *);
extern void sun3_sched_init(void (*handler)(int, void *, struct pt_regs *));
extern void sun3_init_IRQ (void);
@@ -50,8 +50,9 @@ extern void sun3_enable_interrupts (void);
extern void sun3_disable_interrupts (void);
extern void sun3_get_model (unsigned char* model);
extern void idprom_init (void);
-void sun3_gettod (int *yearp, int *monp, int *dayp,
+extern void sun3_gettod (int *yearp, int *monp, int *dayp,
int *hourp, int *minp, int *secp);
+extern int sun3_hwclk(int set, struct hwclk_time *t);
extern unsigned long sun_serial_setup(unsigned long memory_start);
volatile char* clock_va;
@@ -106,6 +107,11 @@ static void sun3_reboot (void)
prom_reboot ("vmlinux");
}
+static void sun3_halt (void)
+{
+ prom_halt ();
+}
+
void __init config_sun3(unsigned long *start_mem_p, unsigned long *end_mem_p)
{
printk("ARCH: SUN3\n");
@@ -126,6 +132,8 @@ void __init config_sun3(unsigned long *start_mem_p, unsigned long *end_mem_p)
mach_reset = sun3_reboot;
mach_gettimeoffset = sun3_gettimeoffset;
mach_get_model = sun3_get_model;
+ mach_hwclk = sun3_hwclk;
+ mach_halt = sun3_halt;
#ifndef CONFIG_SERIAL_CONSOLE
conswitchp = &dummy_con;
#endif
@@ -153,21 +161,3 @@ void __init sun3_sched_init(void (*timer_routine)(int, void *, struct pt_regs *)
intersil_clear();
}
-static unsigned long sun3_gettimeoffset(void)
-{
- return 1;
-}
-
-void sun3_gettod (int *yearp, int *monp, int *dayp,
- int *hourp, int *minp, int *secp)
-{
- struct intersil_dt* todintersil;
- todintersil = (struct intersil_dt *) &intersil_clock->counter;
- *secp = todintersil->second;
- *minp = todintersil->minute;
- *hourp = todintersil->hour;
- *dayp = todintersil->day;
- *monp = todintersil->month;
- *yearp = todintersil->year+68; /* The base year for sun3 is 1968 */
-}
-
diff --git a/arch/m68k/sun3/intersil.c b/arch/m68k/sun3/intersil.c
new file mode 100644
index 000000000..a39336d8c
--- /dev/null
+++ b/arch/m68k/sun3/intersil.c
@@ -0,0 +1,100 @@
+/*
+ * arch/m68k/sun3/intersil.c
+ *
+ * basic routines for accessing the intersil clock within the sun3 machines
+ *
+ * started 11/12/1999 Sam Creasey
+ *
+ * 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/kernel.h>
+#include <linux/kd.h>
+
+#include <asm/system.h>
+#include <asm/intersil.h>
+
+
+/* bits to set for start/run of the intersil */
+#define STOP_VAL (INTERSIL_STOP | INTERSIL_INT_ENABLE | INTERSIL_24H_MODE)
+#define START_VAL (INTERSIL_RUN | INTERSIL_INT_ENABLE | INTERSIL_24H_MODE)
+
+/* does this need to be implemented? */
+unsigned long sun3_gettimeoffset(void)
+{
+ return 1;
+}
+
+void sun3_gettod (int *yearp, int *monp, int *dayp,
+ int *hourp, int *minp, int *secp)
+{
+ u_char wday;
+ volatile struct intersil_dt* todintersil;
+ unsigned long flags;
+
+ todintersil = (struct intersil_dt *) &intersil_clock->counter;
+
+ save_and_cli(flags);
+
+ intersil_clock->cmd_reg = STOP_VAL;
+
+ *secp = todintersil->csec;
+ *hourp = todintersil->hour;
+ *minp = todintersil->minute;
+ *secp = todintersil->second;
+ *monp = todintersil->month;
+ *dayp = todintersil->day;
+ *yearp = todintersil->year+68; /* The base year for sun3 is 1968 */
+ wday = todintersil->weekday;
+
+ intersil_clock->cmd_reg = START_VAL;
+
+ restore_flags(flags);
+}
+
+
+/* get/set hwclock */
+
+int sun3_hwclk(int set, struct hwclk_time *t)
+{
+ volatile struct intersil_dt *todintersil;
+ unsigned long flags;
+
+ todintersil = (struct intersil_dt *) &intersil_clock->counter;
+
+ save_and_cli(flags);
+
+ intersil_clock->cmd_reg = STOP_VAL;
+
+ /* set or read the clock */
+ if(set) {
+ todintersil->csec = 0;
+ todintersil->hour = t->hour;
+ todintersil->minute = t->min;
+ todintersil->second = t->sec;
+ todintersil->month = t->mon;
+ todintersil->day = t->day;
+ todintersil->year = t->year - 68;
+ todintersil->weekday = t->wday;
+ } else {
+ /* read clock */
+ t->sec = todintersil->csec;
+ t->hour = todintersil->hour;
+ t->min = todintersil->minute;
+ t->sec = todintersil->second;
+ t->mon = todintersil->month;
+ t->day = todintersil->day;
+ t->year = todintersil->year + 68;
+ t->wday = todintersil->weekday;
+ }
+
+ intersil_clock->cmd_reg = START_VAL;
+
+ restore_flags(flags);
+
+ return 0;
+
+}
+
diff --git a/arch/m68k/sun3/mmu_emu.c b/arch/m68k/sun3/mmu_emu.c
index 857aba4f1..e7464f2ad 100644
--- a/arch/m68k/sun3/mmu_emu.c
+++ b/arch/m68k/sun3/mmu_emu.c
@@ -51,9 +51,7 @@ unsigned char pmeg_ctx[PMEGS_NUM];
context. 0xffffffff is a marker for kernel context */
struct mm_struct *ctx_alloc[CONTEXTS_NUM] = {0xffffffff, 0, 0, 0, 0, 0, 0, 0};
/* has this context been mmdrop'd? */
-unsigned char ctx_live[CONTEXTS_NUM] = {1, 0, 0, 0, 0, 0, 0, 0};
static unsigned char ctx_avail = CONTEXTS_NUM-1;
-unsigned char ctx_next_to_die = 1;
/* array of pages to be marked off for the rom when we do mem_init later */
/* 256 pages lets the rom take up to 2mb of physical ram.. I really
@@ -213,45 +211,29 @@ void clear_context(unsigned long context)
unsigned char oldctx;
unsigned long i;
- if(!ctx_alloc[context])
- panic("clear_context: context not allocated\n");
+ if(context) {
+ if(!ctx_alloc[context])
+ panic("clear_context: context not allocated\n");
+
+ ctx_alloc[context]->context = SUN3_INVALID_CONTEXT;
+ ctx_alloc[context] = (struct mm_struct *)0;
+ ctx_avail++;
+ }
oldctx = sun3_get_context();
sun3_put_context(context);
- /* ctx_live denotes if we're clearing a context with an active
- mm, in which case we can use the pgd for clues and also should
- mark that mm as lacking a context. if the context has been
- mmdrop'd, then flush outright. */
-
- if(!ctx_live[context]) {
- for(i = 0; i < TASK_SIZE ; i += SUN3_PMEG_SIZE)
- sun3_put_segmap(i, SUN3_INVALID_PMEG);
- } else {
- pgd_t *pgd;
-
- pgd = ctx_alloc[context]->pgd;
- ctx_alloc[context]->context = SUN3_INVALID_CONTEXT;
- for(i = 0; i < (TASK_SIZE>>PGDIR_SHIFT); i++, pgd++)
- {
- if(pgd_val(*pgd)) {
- sun3_put_segmap(i<<PGDIR_SHIFT,
- SUN3_INVALID_PMEG);
- }
- }
- }
-
for(i = 0; i < SUN3_INVALID_PMEG; i++) {
- if((pmeg_ctx[i] == context) && (pmeg_alloc[i] != 2)) {
+ if((pmeg_ctx[i] == context) && (pmeg_alloc[i] == 1)) {
+ sun3_put_segmap(pmeg_vaddr[i], SUN3_INVALID_PMEG);
pmeg_ctx[i] = 0;
pmeg_alloc[i] = 0;
pmeg_vaddr[i] = 0;
}
}
- ctx_alloc[context] = (struct mm_struct *)0;
- ctx_avail++;
+ sun3_put_context(oldctx);
}
/* gets an empty context. if full, kills the next context listed to
@@ -263,14 +245,15 @@ void clear_context(unsigned long context)
unsigned long get_free_context(struct mm_struct *mm)
{
unsigned long new = 1;
+ static unsigned char next_to_die = 1;
if(!ctx_avail) {
/* kill someone to get our context */
- new = ctx_next_to_die;
+ new = next_to_die;
clear_context(new);
- ctx_next_to_die = (ctx_next_to_die + 1) & 0x7;
- if(!ctx_next_to_die)
- ctx_next_to_die++;
+ next_to_die = (next_to_die + 1) & 0x7;
+ if(!next_to_die)
+ next_to_die++;
} else {
while(new < CONTEXTS_NUM) {
if(ctx_alloc[new])
@@ -284,7 +267,6 @@ unsigned long get_free_context(struct mm_struct *mm)
}
ctx_alloc[new] = mm;
- ctx_live[new] = 1;
ctx_avail--;
return new;
diff --git a/arch/m68k/sun3/sun3_ksyms.c b/arch/m68k/sun3/sun3_ksyms.c
new file mode 100644
index 000000000..e2de77bfd
--- /dev/null
+++ b/arch/m68k/sun3/sun3_ksyms.c
@@ -0,0 +1,10 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <asm/dvma.h>
+#include <asm/idprom.h>
+
+/*
+ * Add things here when you find the need for it.
+ */
+EXPORT_SYMBOL(sun3_dvma_malloc);
+EXPORT_SYMBOL(idprom);
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index 1154cd149..57872bd51 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -88,7 +88,6 @@ CONFIG_KMOD=y
# CONFIG_BLK_DEV_MD is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=m
# CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
# CONFIG_BLK_DEV_HD is not set
@@ -260,10 +259,12 @@ CONFIG_PSMOUSE=y
#
# CONFIG_QUOTA is not set
CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_BFS_FS is not set
+# CONFIG_BFS_FS_WRITE is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
@@ -274,14 +275,20 @@ CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
# CONFIG_MINIX_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_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_SYSV_FS_WRITE 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
@@ -300,10 +307,7 @@ CONFIG_LOCKD=y
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
CONFIG_SGI_PARTITION=y
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
#
diff --git a/arch/mips/defconfig-ip22 b/arch/mips/defconfig-ip22
index 1154cd149..57872bd51 100644
--- a/arch/mips/defconfig-ip22
+++ b/arch/mips/defconfig-ip22
@@ -88,7 +88,6 @@ CONFIG_KMOD=y
# CONFIG_BLK_DEV_MD is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=m
# CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
# CONFIG_BLK_DEV_HD is not set
@@ -260,10 +259,12 @@ CONFIG_PSMOUSE=y
#
# CONFIG_QUOTA is not set
CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_BFS_FS is not set
+# CONFIG_BFS_FS_WRITE is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
@@ -274,14 +275,20 @@ CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
# CONFIG_MINIX_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_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_SYSV_FS_WRITE 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
@@ -300,10 +307,7 @@ CONFIG_LOCKD=y
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
CONFIG_SGI_PARTITION=y
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
#
diff --git a/arch/mips/kernel/semaphore.c b/arch/mips/kernel/semaphore.c
index d62b355e1..1f47bd929 100644
--- a/arch/mips/kernel/semaphore.c
+++ b/arch/mips/kernel/semaphore.c
@@ -127,3 +127,114 @@ int __down_trylock(struct semaphore * sem)
{
return waking_non_zero_trylock(sem);
}
+
+/*
+ * RW Semaphores
+ */
+void
+__down_read(struct rw_semaphore *sem, int count)
+{
+ DOWN_VAR;
+
+ retry_down:
+ if (count < 0) {
+ /* Wait for the lock to become unbiased. Readers
+ are non-exclusive. */
+
+ /* This takes care of granting the lock. */
+ up_read(sem);
+
+ add_wait_queue(&sem->wait, &wait);
+ while (atomic_read(&sem->count) < 0) {
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ if (atomic_read(&sem->count) >= 0)
+ break;
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ tsk->state = TASK_RUNNING;
+
+ mb();
+ count = atomic_dec_return(&sem->count);
+ if (count <= 0)
+ goto retry_down;
+ } else {
+ add_wait_queue(&sem->wait, &wait);
+
+ while (1) {
+ if (test_and_clear_bit(0, &sem->granted))
+ break;
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ if ((sem->granted & 1) == 0)
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ tsk->state = TASK_RUNNING;
+ }
+}
+
+void
+__down_write(struct rw_semaphore *sem, int count)
+{
+ DOWN_VAR;
+
+ retry_down:
+ if (count + RW_LOCK_BIAS < 0) {
+ up_write(sem);
+
+ add_wait_queue_exclusive(&sem->wait, &wait);
+
+ while (atomic_read(&sem->count) < 0) {
+ set_task_state(tsk, (TASK_UNINTERRUPTIBLE
+ | TASK_EXCLUSIVE));
+ if (atomic_read(&sem->count) >= RW_LOCK_BIAS)
+ break;
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ tsk->state = TASK_RUNNING;
+
+ mb();
+ count = atomic_sub_return(RW_LOCK_BIAS, &sem->count);
+ if (count != 0)
+ goto retry_down;
+ } else {
+ /* Put ourselves at the end of the list. */
+ add_wait_queue_exclusive(&sem->write_bias_wait, &wait);
+
+ while (1) {
+ if (test_and_clear_bit(1, &sem->granted))
+ break;
+ set_task_state(tsk, (TASK_UNINTERRUPTIBLE
+ | TASK_EXCLUSIVE));
+ if ((sem->granted & 2) == 0)
+ schedule();
+ }
+
+ remove_wait_queue(&sem->write_bias_wait, &wait);
+ tsk->state = TASK_RUNNING;
+
+ /* If the lock is currently unbiased, awaken the sleepers.
+ FIXME: This wakes up the readers early in a bit of a
+ stampede -> bad! */
+ if (atomic_read(&sem->count) >= 0)
+ wake_up(&sem->wait);
+ }
+}
+
+void
+__rwsem_wake(struct rw_semaphore *sem, unsigned long readers)
+{
+ if (readers) {
+ if (test_and_set_bit(0, &sem->granted))
+ BUG();
+ wake_up(&sem->wait);
+ } else {
+ if (test_and_set_bit(1, &sem->granted))
+ BUG();
+ wake_up(&sem->write_bias_wait);
+ }
+}
diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h
index 66aa9ff50..84ab41425 100644
--- a/arch/mips/kernel/syscalls.h
+++ b/arch/mips/kernel/syscalls.h
@@ -1,4 +1,4 @@
-/* $Id: syscalls.h,v 1.20 2000/02/04 07:40:23 ralf Exp $
+/* $Id: syscalls.h,v 1.21 2000/02/05 06:47:08 ralf Exp $
*
* 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
@@ -231,3 +231,4 @@ SYS(sys_ftruncate64, 2)
SYS(sys_stat64, 3)
SYS(sys_lstat64, 3)
SYS(sys_fstat64, 3) /* 4215 */
+SYS(sys_pivot_root, 2)
diff --git a/arch/mips/kernel/sysmips.c b/arch/mips/kernel/sysmips.c
index 870cdac2d..a854c915f 100644
--- a/arch/mips/kernel/sysmips.c
+++ b/arch/mips/kernel/sysmips.c
@@ -7,7 +7,7 @@
*
* Copyright (C) 1995, 1996, 1997 by Ralf Baechle
*
- * $Id: sysmips.c,v 1.7 1999/10/09 00:00:58 ralf Exp $
+ * $Id: sysmips.c,v 1.8 2000/02/05 06:47:08 ralf Exp $
*/
#include <linux/errno.h>
#include <linux/linkage.h>
@@ -72,6 +72,7 @@ sys_sysmips(int cmd, int arg1, int arg2, int arg3)
if (len == 0 || len > __NEW_UTS_LEN)
goto out;
+ /* Fiiiixmeeee... */
copy_from_user(system_utsname.nodename, name, len);
system_utsname.nodename[len] = '\0';
retval = 0;
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index cfcfc9c8b..263f2c919 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.14 1999/12/04 03:59:00 ralf Exp $
+/* $Id: fault.c,v 1.15 2000/02/04 07:40:23 ralf Exp $
*
* 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
@@ -47,6 +47,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
struct vm_area_struct * vma;
struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
+ int si_code = SEGV_MAPERR;
unsigned long fixup;
/*
@@ -74,6 +75,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
* we can handle it..
*/
good_area:
+ si_code = SEGV_ACCERR;
+
if (write) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
@@ -106,6 +109,7 @@ bad_area:
up(&mm->mmap_sem);
if (user_mode(regs)) {
+ struct siginfo si;
tsk->thread.cp0_badvaddr = address;
tsk->thread.error_code = write;
#if 0
@@ -117,7 +121,10 @@ bad_area:
(unsigned long) regs->cp0_epc,
(unsigned long) regs->regs[31]);
#endif
- force_sig(SIGSEGV, tsk);
+ si.si_signo = SIGSEGV;
+ si.si_code = si_code;
+ si.si_addr = (void *) address;
+ force_sig_info(SIGSEGV, &si, tsk);
return;
}
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile
index f3bb81704..b5091e159 100644
--- a/arch/mips/sni/Makefile
+++ b/arch/mips/sni/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.3 1998/10/28 12:38:16 ralf Exp $
+# $Id: Makefile,v 1.3 1999/01/04 16:03:57 ralf Exp $
#
# Makefile for the SNI specific part of the kernel
#
@@ -14,7 +14,7 @@
all: sni.o
O_TARGET := sni.o
-O_OBJS := int-handler.o io.o pci.o pcimt_scache.o reset.o setup.o
+O_OBJS := dma.o int-handler.o io.o pci.o pcimt_scache.o reset.o setup.o
int-handler.o: int-handler.S
diff --git a/arch/mips/sni/dma.c b/arch/mips/sni/dma.c
new file mode 100644
index 000000000..26a7c0f0b
--- /dev/null
+++ b/arch/mips/sni/dma.c
@@ -0,0 +1,56 @@
+/* $Id: dma.c,v 1.1 2000/02/16 21:21:58 ralf Exp $
+ *
+ * Dynamic DMA mapping support.
+ *
+ * On RM200 there is no hardware dynamic DMA address translation,
+ * so consistent alloc/free are merely page allocation/freeing.
+ * The rest of the dynamic DMA mapping interface is implemented
+ * in <asm/pci.h>.
+ *
+ * These routines assume that the RM has all it's memory at physical
+ * addresses of < 512mb.
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+/* Pure 2^n version of get_order */
+extern __inline__ int __get_order(unsigned long size)
+{
+ int order;
+
+ size = (size-1) >> (PAGE_SHIFT-1);
+ order = -1;
+ do {
+ size >>= 1;
+ order++;
+ } while (size);
+ return order;
+}
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+ dma_addr_t *dma_handle)
+{
+ void *ret;
+ int gfp = GFP_ATOMIC;
+ int order = __get_order(size);
+
+ if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
+ gfp |= GFP_DMA;
+ ret = (void *)__get_free_pages(gfp, order);
+
+ if (ret != NULL) {
+ memset(ret, 0, size);
+ *dma_handle = virt_to_bus(ret);
+ }
+ dma_cache_wback_inv(ret, PAGE_SIZE << order);
+ return KSEG1ADDR(ret);
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ free_pages((unsigned long)vaddr, __get_order(size));
+}
diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig
index a07c83b0c..971b6aae6 100644
--- a/arch/mips64/defconfig
+++ b/arch/mips64/defconfig
@@ -77,7 +77,7 @@ CONFIG_PCI_NAMES=y
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_XD is not set
# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_PARIDE_PARPORT=m
+# CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
# CONFIG_BLK_DEV_HD is not set
@@ -328,23 +328,36 @@ CONFIG_SERIAL_CONSOLE=y
#
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_BFS_FS_WRITE 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_CRAMFS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
# CONFIG_MINIX_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_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_SYSV_FS_WRITE 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
@@ -353,6 +366,7 @@ CONFIG_EXT2_FS=y
CONFIG_NFS_FS=y
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
@@ -362,10 +376,7 @@ CONFIG_LOCKD=y
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_ULTRIX_PARTITION is not set
CONFIG_SGI_PARTITION=y
-# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
CONFIG_KCORE_ELF=y
diff --git a/arch/mips64/defconfig-ip22 b/arch/mips64/defconfig-ip22
index 88f4eecd1..43206114d 100644
--- a/arch/mips64/defconfig-ip22
+++ b/arch/mips64/defconfig-ip22
@@ -68,7 +68,7 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BLK_DEV_MD is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=m
+# CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
# CONFIG_BLK_DEV_HD is not set
@@ -250,23 +250,36 @@ CONFIG_VT_CONSOLE=y
#
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_BFS_FS_WRITE 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_CRAMFS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
# CONFIG_MINIX_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_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_SYSV_FS_WRITE 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
@@ -275,6 +288,7 @@ CONFIG_EXT2_FS=y
CONFIG_NFS_FS=y
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
@@ -284,10 +298,7 @@ CONFIG_LOCKD=y
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
CONFIG_SGI_PARTITION=y
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
#
diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27
index a07c83b0c..971b6aae6 100644
--- a/arch/mips64/defconfig-ip27
+++ b/arch/mips64/defconfig-ip27
@@ -77,7 +77,7 @@ CONFIG_PCI_NAMES=y
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_XD is not set
# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_PARIDE_PARPORT=m
+# CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
# CONFIG_BLK_DEV_HD is not set
@@ -328,23 +328,36 @@ CONFIG_SERIAL_CONSOLE=y
#
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_BFS_FS_WRITE 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_CRAMFS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
# CONFIG_MINIX_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_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_SYSV_FS_WRITE 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
@@ -353,6 +366,7 @@ CONFIG_EXT2_FS=y
CONFIG_NFS_FS=y
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
@@ -362,10 +376,7 @@ CONFIG_LOCKD=y
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_ULTRIX_PARTITION is not set
CONFIG_SGI_PARTITION=y
-# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
CONFIG_KCORE_ELF=y
diff --git a/arch/mips64/kernel/scall_64.S b/arch/mips64/kernel/scall_64.S
index 0e9d40e17..34ff47b4d 100644
--- a/arch/mips64/kernel/scall_64.S
+++ b/arch/mips64/kernel/scall_64.S
@@ -1,4 +1,4 @@
-/* $Id: scall_64.S,v 1.2 1999/12/21 12:35:22 ralf Exp $
+/* $Id: scall_64.S,v 1.5 2000/01/24 01:34:16 ralf Exp $
*
* 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
@@ -344,3 +344,4 @@ sys_call_table:
PTR sys_sendfile
PTR sys_ni_syscall
PTR sys_ni_syscall
+ PTR sys_pivot_root /* 4210 */
diff --git a/arch/mips64/kernel/scall_o32.S b/arch/mips64/kernel/scall_o32.S
index 7906258d2..57ec8bd53 100644
--- a/arch/mips64/kernel/scall_o32.S
+++ b/arch/mips64/kernel/scall_o32.S
@@ -1,4 +1,4 @@
-/* $Id: scall_o32.S,v 1.5 2000/02/04 07:40:24 ralf Exp $
+/* $Id: scall_o32.S,v 1.6 2000/02/05 06:47:09 ralf Exp $
*
* 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
@@ -407,6 +407,7 @@ illegal_syscall:
sys sys_stat64 3
sys sys_lstat64 3
sys sys_fstat64 3 /* 4210 */
+ sys sys_pivot_root 2
.endm
.macro sys function, nargs
diff --git a/arch/mips64/kernel/semaphore.c b/arch/mips64/kernel/semaphore.c
index d62b355e1..1f47bd929 100644
--- a/arch/mips64/kernel/semaphore.c
+++ b/arch/mips64/kernel/semaphore.c
@@ -127,3 +127,114 @@ int __down_trylock(struct semaphore * sem)
{
return waking_non_zero_trylock(sem);
}
+
+/*
+ * RW Semaphores
+ */
+void
+__down_read(struct rw_semaphore *sem, int count)
+{
+ DOWN_VAR;
+
+ retry_down:
+ if (count < 0) {
+ /* Wait for the lock to become unbiased. Readers
+ are non-exclusive. */
+
+ /* This takes care of granting the lock. */
+ up_read(sem);
+
+ add_wait_queue(&sem->wait, &wait);
+ while (atomic_read(&sem->count) < 0) {
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ if (atomic_read(&sem->count) >= 0)
+ break;
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ tsk->state = TASK_RUNNING;
+
+ mb();
+ count = atomic_dec_return(&sem->count);
+ if (count <= 0)
+ goto retry_down;
+ } else {
+ add_wait_queue(&sem->wait, &wait);
+
+ while (1) {
+ if (test_and_clear_bit(0, &sem->granted))
+ break;
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ if ((sem->granted & 1) == 0)
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ tsk->state = TASK_RUNNING;
+ }
+}
+
+void
+__down_write(struct rw_semaphore *sem, int count)
+{
+ DOWN_VAR;
+
+ retry_down:
+ if (count + RW_LOCK_BIAS < 0) {
+ up_write(sem);
+
+ add_wait_queue_exclusive(&sem->wait, &wait);
+
+ while (atomic_read(&sem->count) < 0) {
+ set_task_state(tsk, (TASK_UNINTERRUPTIBLE
+ | TASK_EXCLUSIVE));
+ if (atomic_read(&sem->count) >= RW_LOCK_BIAS)
+ break;
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ tsk->state = TASK_RUNNING;
+
+ mb();
+ count = atomic_sub_return(RW_LOCK_BIAS, &sem->count);
+ if (count != 0)
+ goto retry_down;
+ } else {
+ /* Put ourselves at the end of the list. */
+ add_wait_queue_exclusive(&sem->write_bias_wait, &wait);
+
+ while (1) {
+ if (test_and_clear_bit(1, &sem->granted))
+ break;
+ set_task_state(tsk, (TASK_UNINTERRUPTIBLE
+ | TASK_EXCLUSIVE));
+ if ((sem->granted & 2) == 0)
+ schedule();
+ }
+
+ remove_wait_queue(&sem->write_bias_wait, &wait);
+ tsk->state = TASK_RUNNING;
+
+ /* If the lock is currently unbiased, awaken the sleepers.
+ FIXME: This wakes up the readers early in a bit of a
+ stampede -> bad! */
+ if (atomic_read(&sem->count) >= 0)
+ wake_up(&sem->wait);
+ }
+}
+
+void
+__rwsem_wake(struct rw_semaphore *sem, unsigned long readers)
+{
+ if (readers) {
+ if (test_and_set_bit(0, &sem->granted))
+ BUG();
+ wake_up(&sem->wait);
+ } else {
+ if (test_and_set_bit(1, &sem->granted))
+ BUG();
+ wake_up(&sem->write_bias_wait);
+ }
+}
diff --git a/arch/mips64/mm/fault.c b/arch/mips64/mm/fault.c
index 772aa0475..b7a9e2b8f 100644
--- a/arch/mips64/mm/fault.c
+++ b/arch/mips64/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.4 1999/12/04 03:59:00 ralf Exp $
+/* $Id: fault.c,v 1.5 2000/02/04 07:40:24 ralf Exp $
*
* 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
@@ -50,6 +50,7 @@ do_page_fault(struct pt_regs *regs, unsigned long write, unsigned long address)
struct vm_area_struct * vma;
struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
+ int si_code = SEGV_MAPERR;
unsigned long fixup;
/*
@@ -77,6 +78,8 @@ do_page_fault(struct pt_regs *regs, unsigned long write, unsigned long address)
* we can handle it..
*/
good_area:
+ si_code = SEGV_ACCERR;
+
if (write) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
@@ -109,6 +112,7 @@ bad_area:
up(&mm->mmap_sem);
if (user_mode(regs)) {
+ struct siginfo si;
tsk->thread.cp0_badvaddr = address;
tsk->thread.error_code = write;
#if 0
@@ -120,7 +124,10 @@ bad_area:
(unsigned long) regs->cp0_epc,
(unsigned long) regs->regs[31]);
#endif
- force_sig(SIGSEGV, tsk);
+ si.si_signo = SIGSEGV;
+ si.si_code = si_code;
+ si.si_addr = (void *) address;
+ force_sig_info(SIGSEGV, &si, tsk);
return;
}
diff --git a/arch/mips64/sgi-ip27/Makefile b/arch/mips64/sgi-ip27/Makefile
index 996bfb1e8..514beaa81 100644
--- a/arch/mips64/sgi-ip27/Makefile
+++ b/arch/mips64/sgi-ip27/Makefile
@@ -1,4 +1,4 @@
-# $Id$
+# $Id: Makefile,v 1.3 2000/02/04 08:41:40 kanoj Exp $
#
# Makefile for the IP27 specific kernel interface routines under Linux.
#
@@ -10,7 +10,7 @@
L_TARGET = ip27.a
L_OBJS = ip27-berr.o ip27-irq.o ip27-irq-glue.o ip27-klconfig.o \
- ip27-memory.o ip27-pci.o ip27-reset.o ip27-setup.o ip27-timer.o \
- ip27-init.o
+ ip27-memory.o ip27-pci.o ip27-pci-dma.o ip27-reset.o ip27-setup.o \
+ ip27-timer.o ip27-init.o
include $(TOPDIR)/Rules.make
diff --git a/arch/mips64/sgi-ip27/ip27-pci-dma.c b/arch/mips64/sgi-ip27/ip27-pci-dma.c
new file mode 100644
index 000000000..81e3e5c6f
--- /dev/null
+++ b/arch/mips64/sgi-ip27/ip27-pci-dma.c
@@ -0,0 +1,55 @@
+/* $Id: ip27-pci-dma.c,v 1.1 2000/02/16 21:22:00 ralf Exp $
+ *
+ * Dynamic DMA mapping support.
+ *
+ * On the Origin there is dynamic DMA address translation for all PCI DMA.
+ * However we don't use this facility yet but rely on the 2gb direct
+ * mapped DMA window for PCI64. So consistent alloc/free are merely page
+ * allocation/freeing. The rest of the dynamic DMA mapping interface is
+ * implemented in <asm/pci.h>. So this code will fail with more than
+ * 2gb of memory.
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+/* Pure 2^n version of get_order */
+extern __inline__ int __get_order(unsigned long size)
+{
+ int order;
+
+ size = (size-1) >> (PAGE_SHIFT-1);
+ order = -1;
+ do {
+ size >>= 1;
+ order++;
+ } while (size);
+ return order;
+}
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+ dma_addr_t *dma_handle)
+{
+ void *ret;
+ int gfp = GFP_ATOMIC;
+ int order = __get_order(size);
+
+ if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
+ gfp |= GFP_DMA;
+ ret = (void *)__get_free_pages(gfp, order);
+
+ if (ret != NULL) {
+ memset(ret, 0, size);
+ *dma_handle = virt_to_bus(ret);
+ }
+
+ return ret;
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ free_pages((unsigned long)vaddr, __get_order(size));
+}
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index cb92163d6..2c4ff5554 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -271,6 +271,7 @@ ret_from_smpfork:
bl schedule_tail
b ret_from_except
#endif
+
.globl ret_from_intercept
ret_from_intercept:
/*
@@ -278,7 +279,16 @@ ret_from_intercept:
* -- Cort
*/
cmpi 0,r3,0
- beq 10f
+ bne ret_from_except
+ /*
+ * If we're returning from user mode we do things differently
+ * -- Cort
+ */
+ lwz r3,_MSR(r1)
+ andi. r3,r3,MSR_PR
+ beq+ 10f
+ b 8f
+
.globl ret_from_except
ret_from_except:
0: /* disable interrupts */
@@ -315,7 +325,6 @@ do_bottom_half_ret:
lwz r30,0(r30)
mtlr r30
blrl
-
lwz r3,_MSR(r1) /* Returning to user mode? */
andi. r3,r3,MSR_PR
beq+ 10f /* if so, check need_resched and signals */
@@ -337,7 +346,13 @@ do_signal_ret:
stw r4,THREAD+KSP(r2) /* save kernel stack pointer */
tophys(r3,r1)
mtspr SPRG2,r3 /* phys exception stack pointer */
-10: lwz r2,_CTR(r1)
+10: /* make sure we hard disable here, even if rtl is active -- Cort */
+ mfmsr r0 /* Get current interrupt state */
+ rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */
+ sync /* Some chip revs have problems here... */
+ mtmsr r0 /* Update machine state */
+
+ lwz r2,_CTR(r1)
lwz r0,_LINK(r1)
mtctr r2
mtlr r0
diff --git a/arch/ppc/kernel/i8259.c b/arch/ppc/kernel/i8259.c
index 3a3a16d9e..5dfe902df 100644
--- a/arch/ppc/kernel/i8259.c
+++ b/arch/ppc/kernel/i8259.c
@@ -10,6 +10,8 @@ unsigned char cached_8259[2] = { 0xff, 0xff };
#define cached_A1 (cached_8259[0])
#define cached_21 (cached_8259[1])
+int i8259_pic_irq_offset;
+
int i8259_irq(int cpu)
{
int irq;
@@ -46,8 +48,8 @@ int i8259_irq(int cpu)
static void i8259_mask_and_ack_irq(unsigned int irq_nr)
{
- if ( irq_nr >= i8259_pic.irq_offset )
- irq_nr -= i8259_pic.irq_offset;
+ if ( irq_nr >= i8259_pic_irq_offset )
+ irq_nr -= i8259_pic_irq_offset;
if (irq_nr > 7) {
cached_A1 |= 1 << (irq_nr-8);
@@ -71,8 +73,8 @@ static void i8259_set_irq_mask(int irq_nr)
static void i8259_mask_irq(unsigned int irq_nr)
{
- if ( irq_nr >= i8259_pic.irq_offset )
- irq_nr -= i8259_pic.irq_offset;
+ if ( irq_nr >= i8259_pic_irq_offset )
+ irq_nr -= i8259_pic_irq_offset;
if ( irq_nr < 8 )
cached_21 |= 1 << irq_nr;
else
@@ -83,8 +85,8 @@ static void i8259_mask_irq(unsigned int irq_nr)
static void i8259_unmask_irq(unsigned int irq_nr)
{
- if ( irq_nr >= i8259_pic.irq_offset )
- irq_nr -= i8259_pic.irq_offset;
+ if ( irq_nr >= i8259_pic_irq_offset )
+ irq_nr -= i8259_pic_irq_offset;
if ( irq_nr < 8 )
cached_21 &= ~(1 << irq_nr);
else
@@ -123,7 +125,7 @@ void __init i8259_init(void)
outb(0xFF, 0xA1); /* Mask all */
outb(cached_A1, 0xA1);
outb(cached_21, 0x21);
- request_irq( i8259_pic.irq_offset + 2, no_action, SA_INTERRUPT,
+ request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT,
"82c59 secondary cascade", NULL );
- enable_irq(i8259_pic.irq_offset + 2); /* Enable cascade interrupt */
+ enable_irq(i8259_pic_irq_offset + 2); /* Enable cascade interrupt */
}
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 444654ec6..aa9f5ac83 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -1068,4 +1068,6 @@ _GLOBAL(sys_call_table)
.long sys_ni_syscall /* streams2 */
.long sys_vfork
.long sys_getrlimit /* 190 */
- .space (NR_syscalls-190)*4
+ .rept NR_syscalls-190
+ .long sys_ni_syscall
+ .endr
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index 426f80ff3..9ed5f3805 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -70,7 +70,7 @@ xmon_map_scc(void)
sccd = sccc + (0xf3013030 - 0xf3013020);
#endif
}
- else
+ else if ( _machine & _MACH_chrp )
{
/* should already be mapped by the kernel boot */
sccc = (volatile unsigned char *) (isa_io_base + 0x3fd);
@@ -78,6 +78,15 @@ xmon_map_scc(void)
TXRDY = 0x20;
RXRDY = 1;
}
+ else if ( _machine & _MACH_gemini )
+ {
+ /* should already be mapped by the kernel boot */
+ sccc = (volatile unsigned char *) 0xffeffb0d;
+ sccd = (volatile unsigned char *) 0xffeffb08;
+ TXRDY = 0x20;
+ RXRDY = 1;
+ console = 1;
+ }
}
static int scc_initialized = 0;
@@ -226,7 +235,7 @@ static unsigned char scc_inittab[] = {
void
xmon_init_scc()
{
- if ( _machine == _MACH_chrp )
+ if ( _machine & (_MACH_chrp|_MACH_gemini) )
{
sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */
sccd[0] = 3; eieio(); /* DLL = 38400 baud */
@@ -235,7 +244,7 @@ xmon_init_scc()
sccd[3] = 3; eieio(); /* LCR = 8N1 */
sccd[1] = 0; eieio(); /* IER = 0 */
}
- else
+ else if ( _machine == _MACH_Pmac )
{
int i, x;
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 8f480f764..1b708e5a9 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -170,9 +170,9 @@ asmlinkage int sys_uname(struct old_utsname * name)
int err;
if (!name)
return -EFAULT;
- down(&uts_sem);
+ down_read(&uts_sem);
err=copy_to_user(name, &system_utsname, sizeof (*name));
- up(&uts_sem);
+ up_read(&uts_sem);
return err?-EFAULT:0;
}
diff --git a/arch/sparc/config.in b/arch/sparc/config.in
index 31e126f33..8d3562e37 100644
--- a/arch/sparc/config.in
+++ b/arch/sparc/config.in
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.80 2000/01/14 07:12:30 davem Exp $
+# $Id: config.in,v 1.81 2000/01/22 05:14:44 zaitcev Exp $
# For a description of the syntax of this configuration file,
# see the Configure script.
#
@@ -37,7 +37,6 @@ else
mainmenu_option next_comment
comment 'Console drivers'
bool 'PROM console' CONFIG_PROM_CONSOLE
- bool 'Support Frame buffer devices' CONFIG_FB
source drivers/video/Config.in
endmenu
diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c
index c1ef01be3..c9972ab16 100644
--- a/arch/sparc/kernel/ebus.c
+++ b/arch/sparc/kernel/ebus.c
@@ -1,4 +1,4 @@
-/* $Id: ebus.c,v 1.8 1999/11/27 22:40:38 zaitcev Exp $
+/* $Id: ebus.c,v 1.9 2000/01/22 07:35:25 zaitcev Exp $
* ebus.c: PCI to EBus bridge device.
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -22,14 +22,6 @@
#include <asm/oplib.h>
#include <asm/bpp.h>
-#undef PROM_DEBUG
-
-#if 0 /* separate from PROM_DEBUG for the sake of PROLL */
-#define dprintk prom_printf
-#else
-#define dprintk printk
-#endif
-
struct linux_ebus *ebus_chain = 0;
#ifdef CONFIG_SUN_OPENPROMIO
@@ -51,11 +43,62 @@ extern int envctrl_init(void);
/* We are together with pcic.c under CONFIG_PCI. */
extern unsigned int pcic_pin_to_irq(unsigned int, char *name);
+/*
+ * IRQ Blacklist
+ * Here we list PROMs and systems that are known to supply crap as IRQ numbers.
+ */
+struct ebus_device_irq {
+ char *name;
+ unsigned int pin;
+};
+
+struct ebus_system_entry {
+ char *esname;
+ struct ebus_device_irq *ipt;
+};
+
+static struct ebus_device_irq je1_1[] = {
+ { "8042", 3 },
+ { "SUNW,CS4231", 0 },
+ { "parallel", 0 },
+ { "se", 2 },
+ { 0, 0 }
+};
+
+/*
+ * Gleb's JE1 supplied reasonable pin numbers, but mine did not (OBP 2.32).
+ * Blacklist the sucker... Note that Gleb's system will work.
+ */
+static struct ebus_system_entry ebus_blacklist[] = {
+ { "SUNW,JavaEngine1", je1_1 },
+ { 0, 0 }
+};
+
+static struct ebus_device_irq *ebus_blackp = NULL;
+
+/*
+ */
static inline unsigned long ebus_alloc(size_t size)
{
return (unsigned long)kmalloc(size, GFP_ATOMIC);
}
+/*
+ */
+int __init ebus_blacklist_irq(char *name)
+{
+ struct ebus_device_irq *dp;
+
+ if ((dp = ebus_blackp) != NULL) {
+ for (; dp->name != NULL; dp++) {
+ if (strcmp(name, dp->name) == 0) {
+ return pcic_pin_to_irq(dp->pin, name);
+ }
+ }
+ }
+ return 0;
+}
+
void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
struct linux_ebus_child *dev)
{
@@ -81,14 +124,10 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
dev->resource[i].start = dev->parent->resource[regs[i]].start; /* XXX resource */
}
- /*
- * Houston, we have a problem...
- * Sometimes PROM supplies absolutely meaningless properties.
- * Still, we take what it gives since we have nothing better.
- * Children of ebus may be wired on any input pin of PCIC.
- */
- len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
- if ((len == -1) || (len == 0)) {
+ if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_name)) != 0) {
+ dev->num_irqs = 1;
+ } else if ((len = prom_getproperty(node, "interrupts",
+ (char *)&irqs, sizeof(irqs)) == -1) || (len == 0)) {
dev->num_irqs = 0;
dev->irqs[0] = 0;
if (dev->parent->num_irqs != 0) {
@@ -177,8 +216,10 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
dev->resource[i].start = baseaddr; /* XXX Unaligned */
}
- len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
- if ((len == -1) || (len == 0)) {
+ if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_name)) != 0) {
+ dev->num_irqs = 1;
+ } else if ((len = prom_getproperty(node, "interrupts",
+ (char *)&irqs, sizeof(irqs)) == -1) || (len == 0)) {
dev->num_irqs = 0;
if ((dev->irqs[0] = dev->bus->self->irq) != 0) {
dev->num_irqs = 1;
@@ -226,6 +267,7 @@ void __init ebus_init(void)
struct linux_pbm_info *pbm;
struct linux_ebus_device *dev;
struct linux_ebus *ebus;
+ struct ebus_system_entry *sp;
struct pci_dev *pdev;
struct pcidev_cookie *cookie;
char lbuf[128];
@@ -238,11 +280,16 @@ void __init ebus_init(void)
if (!pci_present())
return;
+ prom_getstring(prom_root_node, "name", lbuf, sizeof(lbuf));
+ for (sp = ebus_blacklist; sp->esname != NULL; sp++) {
+ if (strcmp(lbuf, sp->esname) == 0) {
+ ebus_blackp = sp->ipt;
+ break;
+ }
+ }
+
pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0);
if (!pdev) {
-#ifdef PROM_DEBUG
- dprintk("ebus: No EBus's found.\n");
-#endif
return;
}
cookie = pdev->sysdata;
@@ -253,9 +300,6 @@ void __init ebus_init(void)
ebus->next = 0;
while (ebusnd) {
-#ifdef PROM_DEBUG
- dprintk("ebus%d:", num_ebus);
-#endif
prom_getstring(ebusnd, "name", lbuf, sizeof(lbuf));
ebus->prom_node = ebusnd;
@@ -284,13 +328,7 @@ void __init ebus_init(void)
addr = regs[reg].phys_lo;
*base++ = addr;
-#ifdef PROM_DEBUG
- dprintk(" %lx[%x]", addr, regs[reg].size_lo);
-#endif
}
-#ifdef PROM_DEBUG
- dprintk("\n");
-#endif
nd = prom_getchild(ebusnd);
if (!nd)
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index e2b6b1ae4..c0ffb2675 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -1,4 +1,4 @@
-/* $Id: ioport.c,v 1.28 1999/12/27 06:08:28 anton Exp $
+/* $Id: ioport.c,v 1.29 2000/01/22 07:35:25 zaitcev Exp $
* ioport.c: Simple io mapping allocator.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -203,6 +203,7 @@ static void *_sparc_alloc_io(unsigned int busno, unsigned long phys,
tlen = strlen(name);
tack = kmalloc(sizeof (struct resource) + tlen + 1, GFP_KERNEL);
if (tack == NULL) return NULL;
+ memset(tack, 0, sizeof(struct resource));
res = (struct resource *) tack;
tack += sizeof (struct resource);
}
@@ -285,8 +286,10 @@ void sbus_set_sbus64(struct sbus_dev *sdev, int x) {
* Allocate a chunk of memory suitable for DMA.
* Typically devices use them for control blocks.
* CPU may access them without any explicit flushing.
+ *
+ * XXX Some clever people know that sdev is not used and supply NULL. Watch.
*/
-void *sbus_alloc_consistant(struct sbus_dev *sdev, long len, u32 *dma_addrp)
+void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp)
{
unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK;
unsigned long va;
@@ -310,26 +313,27 @@ void *sbus_alloc_consistant(struct sbus_dev *sdev, long len, u32 *dma_addrp)
/*
* printk here may be flooding... Consider removal XXX.
*/
- printk("sbus_alloc_consistant: no %ld pages\n", len_total>>PAGE_SHIFT);
+ printk("sbus_alloc_consistent: no %ld pages\n", len_total>>PAGE_SHIFT);
return NULL;
}
if ((res = kmalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) {
free_pages(va, order);
- printk("sbus_alloc_consistant: no core\n");
+ printk("sbus_alloc_consistent: no core\n");
return NULL;
}
+ memset((char*)res, 0, sizeof(struct resource));
if (allocate_resource(&sparc_dvma, res, len_total,
sparc_dvma.start, sparc_dvma.end, PAGE_SIZE, NULL, NULL) != 0) {
- printk("sbus_alloc_consistant: cannot occupy 0x%lx", len);
+ printk("sbus_alloc_consistent: cannot occupy 0x%lx", len_total);
free_pages(va, order);
kfree(res);
return NULL;
}
*dma_addrp = res->start;
- mmu_map_dma_area(va, res->start, len);
+ mmu_map_dma_area(va, res->start, len_total);
/*
* "Official" or "natural" address of pages we got is va.
@@ -342,7 +346,7 @@ void *sbus_alloc_consistant(struct sbus_dev *sdev, long len, u32 *dma_addrp)
return (void *)res->start;
}
-void sbus_free_consistant(struct sbus_dev *sdev, long n, void *p, u32 ba)
+void sbus_free_consistent(struct sbus_dev *sdev, long n, void *p, u32 ba)
{
struct resource *res;
unsigned long pgp;
@@ -350,18 +354,18 @@ void sbus_free_consistant(struct sbus_dev *sdev, long n, void *p, u32 ba)
if ((res = sparc_find_resource_bystart(&sparc_dvma,
(unsigned long)p)) == NULL) {
- printk("sbus_free_consistant: cannot free %p\n", p);
+ printk("sbus_free_consistent: cannot free %p\n", p);
return;
}
if (((unsigned long)p & (PAGE_MASK-1)) != 0) {
- printk("sbus_free_consistant: unaligned va %p\n", p);
+ printk("sbus_free_consistent: unaligned va %p\n", p);
return;
}
n = (n + PAGE_SIZE-1) & PAGE_MASK;
if ((res->end-res->start)+1 != n) {
- printk("sbus_free_consistant: region 0x%lx asked 0x%lx\n",
+ printk("sbus_free_consistent: region 0x%lx asked 0x%lx\n",
(long)((res->end-res->start)+1), n);
return;
}
@@ -386,7 +390,7 @@ void sbus_free_consistant(struct sbus_dev *sdev, long n, void *p, u32 ba)
*/
u32 sbus_map_single(struct sbus_dev *sdev, void *va, long len)
{
-#if 0 /* This is the version that abuses consistant space */
+#if 0 /* This is the version that abuses consistent space */
unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK;
struct resource *res;
@@ -403,6 +407,7 @@ u32 sbus_map_single(struct sbus_dev *sdev, void *va, long len)
printk("sbus_map_single: no core\n");
return 0;
}
+ memset((char*)res, 0, sizeof(struct resource));
res->name = va;
if (allocate_resource(&sparc_dvma, res, len_total,
@@ -433,7 +438,7 @@ u32 sbus_map_single(struct sbus_dev *sdev, void *va, long len)
void sbus_unmap_single(struct sbus_dev *sdev, u32 ba, long n)
{
-#if 0 /* This is the version that abuses consistant space */
+#if 0 /* This is the version that abuses consistent space */
struct resource *res;
unsigned long va;
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 94847460b..b504e2412 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -1,4 +1,4 @@
-/* $Id: pcic.c,v 1.11 1999/11/25 05:22:05 zaitcev Exp $
+/* $Id: pcic.c,v 1.12 2000/01/22 07:35:25 zaitcev Exp $
* pcic.c: Sparc/PCI controller support
*
* Copyright (C) 1998 V. Roganov and G. Raiko
@@ -84,8 +84,6 @@ unsigned int pcic_pin_to_irq(unsigned int pin, char *name);
* Once we know the map we take device configuration address and
* find PCIC pin number where INT line goes. Then we may either program
* preferred irq into the PCIC or supply the preexisting irq to the device.
- *
- * XXX Entries for JE-1 are completely bogus. Gleb, Vladimir, please fill them.
*/
struct pcic_ca2irq {
unsigned char busno; /* PCI bus number */
@@ -102,14 +100,28 @@ struct pcic_sn2list {
};
/*
- * XXX JE-1 is a little known beast.
- * One rumor has the map this way: pin 0 - parallel, audio;
- * pin 1 - Ethernet; pin 2 - su; pin 3 - PS/2 kbd and mouse.
- * All other comparable systems tie serial and keyboard together,
- * so we do not code this rumor just yet.
+ * JavaEngine-1 apparently has different versions.
+ *
+ * According to communications with Sun folks, for P2 build 501-4628-03:
+ * pin 0 - parallel, audio;
+ * pin 1 - Ethernet;
+ * pin 2 - su;
+ * pin 3 - PS/2 kbd and mouse.
+ *
+ * OEM manual (805-1486):
+ * pin 0: Ethernet
+ * pin 1: All EBus
+ * pin 2: IGA (unused)
+ * pin 3: Not connected
+ * OEM manual says that 501-4628 & 501-4811 are the same thing,
+ * only the latter has NAND flash in place.
+ *
+ * So far unofficial Sun wins over the OEM manual. Poor OEMs...
*/
-static struct pcic_ca2irq pcic_i_je1[] = {
+static struct pcic_ca2irq pcic_i_je1a[] = { /* 501-4811-03 */
+ { 0, 0x00, 2, 12, 0 }, /* EBus: hogs all */
{ 0, 0x01, 1, 6, 1 }, /* Happy Meal */
+ { 0, 0x80, 0, 7, 0 }, /* IGA (unused) */
};
/* XXX JS-E entry is incomplete - PCI Slot 2 address (pin 7)? */
@@ -159,7 +171,7 @@ static struct pcic_ca2irq pcic_i_jk[] = {
{ name, map, sizeof(map)/sizeof(struct pcic_ca2irq) }
static struct pcic_sn2list pcic_known_sysnames[] = {
- SN2L_INIT("JE-1-name", pcic_i_je1), /* XXX Gleb, put name here, pls */
+ SN2L_INIT("SUNW,JavaEngine1", pcic_i_je1a), /* JE1, PROM 2.32 */
SN2L_INIT("SUNW,JS-E", pcic_i_jse), /* PROLL JavaStation-E */
SN2L_INIT("SUNW,SPARCengine-6", pcic_i_se6), /* SPARCengine-6/CP-1200 */
SN2L_INIT("SUNW,JS-NC", pcic_i_jk), /* PROLL JavaStation-NC */
@@ -602,11 +614,19 @@ pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node)
p->irq, dev->device, dev->vendor);
dev->irq = p->irq;
- ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_HI);
- ivec &= ~(0xF << ((p->pin - 4) << 2));
- ivec |= p->irq << ((p->pin - 4) << 2);
- writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_HI);
- }
+ i = p->pin;
+ if (i >= 4) {
+ ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_HI);
+ ivec &= ~(0xF << ((i - 4) << 2));
+ ivec |= p->irq << ((i - 4) << 2);
+ writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_HI);
+ } else {
+ ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_LO);
+ ivec &= ~(0xF << (i << 2));
+ ivec |= p->irq << (i << 2);
+ writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_LO);
+ }
+ }
return;
}
@@ -616,7 +636,7 @@ pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node)
*/
void __init pcibios_fixup_bus(struct pci_bus *bus)
{
- struct pci_dev *dev;
+ struct list_head *walk;
int i, has_io, has_mem;
unsigned short cmd;
struct linux_pcic *pcic;
@@ -638,7 +658,10 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
return;
}
- for (dev = bus->devices; dev; dev = dev->sibling) {
+ walk = &bus->devices;
+ for (walk = walk->next; walk != &bus->devices; walk = walk->next) {
+ struct pci_dev *dev = pci_dev_b(walk);
+
/*
* Comment from i386 branch:
* There are buggy BIOSes that forget to enable I/O and memory
@@ -832,6 +855,46 @@ char * __init pcibios_setup(char *str)
}
/*
+ */
+void pcibios_update_resource(struct pci_dev *pdev, struct resource *res1,
+ struct resource *res2, int index)
+{
+}
+
+#if 0
+void pcibios_update_irq(struct pci_dev *pdev, int irq)
+{
+}
+
+unsigned long resource_fixup(struct pci_dev *pdev, struct resource *res,
+ unsigned long start, unsigned long size)
+{
+ return start;
+}
+
+void pcibios_fixup_pbus_ranges(struct pci_bus *pbus,
+ struct pbus_set_ranges_data *pranges)
+{
+}
+#endif
+
+void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+}
+
+#if 0
+int pci_assign_resource(struct pci_dev *dev, int i)
+{
+ return -ENOSYS; /* :-)... actually implement this soon */
+}
+#endif
+
+int pcibios_enable_device(struct pci_dev *pdev)
+{
+ return 0;
+}
+
+/*
* NMI
*/
void pcic_nmi(unsigned int pend, struct pt_regs *regs)
@@ -1017,4 +1080,70 @@ int pcibios_assign_resource(struct pci_dev *pdev, int resource)
return -ENXIO;
}
+/*
+ * This probably belongs here rather than ioport.c because
+ * we do not want this crud linked into SBus kernels.
+ * Also, think for a moment about likes of floppy.c that
+ * include architecture specific parts. They may want to redefine ins/outs.
+ *
+ * We do not use horroble macroses here because we want to
+ * advance pointer by sizeof(size).
+ */
+void outsb(unsigned long addr, const void *src, unsigned long count) {
+ while (count) {
+ count -= 1;
+ writeb(*(const char *)src, addr);
+ src += 1;
+ addr += 1;
+ }
+}
+
+void outsw(unsigned long addr, const void *src, unsigned long count) {
+ while (count) {
+ count -= 2;
+ writew(*(const short *)src, addr);
+ src += 2;
+ addr += 2;
+ }
+}
+
+void outsl(unsigned long addr, const void *src, unsigned long count) {
+ while (count) {
+ count -= 4;
+ writel(*(const long *)src, addr);
+ src += 4;
+ addr += 4;
+ }
+}
+
+void insb(unsigned long addr, void *dst, unsigned long count) {
+ while (count) {
+ count -= 1;
+ *(unsigned char *)dst = readb(addr);
+ dst += 1;
+ addr += 1;
+ }
+}
+
+void insw(unsigned long addr, void *dst, unsigned long count) {
+ while (count) {
+ count -= 2;
+ *(unsigned short *)dst = readw(addr);
+ dst += 2;
+ addr += 2;
+ }
+}
+
+void insl(unsigned long addr, void *dst, unsigned long count) {
+ while (count) {
+ count -= 4;
+ /*
+ * XXX I am sure we are in for an unaligned trap here.
+ */
+ *(unsigned long *)dst = readl(addr);
+ dst += 4;
+ addr += 4;
+ }
+}
+
#endif
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 1be5a02e3..420efe1e1 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.143 2000/01/09 09:13:28 anton Exp $
+/* $Id: process.c,v 1.144 2000/01/21 11:38:39 jj Exp $
* linux/arch/sparc/kernel/process.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -293,7 +293,6 @@ void show_thread(struct thread_struct *thread)
printk("uwinmask: 0x%08lx kregs: 0x%08lx\n", thread->uwinmask, (unsigned long)thread->kregs);
show_regs(thread->kregs);
- printk("sig_address: 0x%08lx sig_desc: 0x%08lx\n", thread->sig_address, thread->sig_desc);
printk("ksp: 0x%08lx kpc: 0x%08lx\n", thread->ksp, thread->kpc);
printk("kpsr: 0x%08lx kwim: 0x%08lx\n", thread->kpsr, thread->kwim);
printk("fork_kpsr: 0x%08lx fork_kwim: 0x%08lx\n", thread->fork_kpsr, thread->fork_kwim);
@@ -595,7 +594,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
dump->fpu.fpstatus.fpq_count = current->thread.fpqdepth;
memcpy(&dump->fpu.fpstatus.fpq[0], &current->thread.fpqueue[0],
((sizeof(unsigned long) * 2) * 16));
- dump->sigcode = current->thread.sig_desc;
+ dump->sigcode = 0;
}
/*
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index ea0c7e1ff..98b542402 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.99 1999/12/27 06:08:32 anton Exp $
+/* $Id: signal.c,v 1.101 2000/01/21 11:38:38 jj Exp $
* linux/arch/sparc/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -424,12 +424,15 @@ static inline void *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
}
static inline void
-setup_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
- struct pt_regs *regs, int signr, sigset_t *oldset)
+setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info)
{
struct signal_sframe *sframep;
struct sigcontext *sc;
int window = 0, err;
+ unsigned long pc = regs->pc;
+ unsigned long npc = regs->npc;
+ void *sig_address;
+ int sig_code;
synchronize_user_stack();
sframep = (struct signal_sframe *)get_sigframe(sa, regs, SF_ALIGNEDSZ);
@@ -474,18 +477,63 @@ setup_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
sizeof(struct reg_window));
current->thread.w_saved = 0; /* So process is allowed to execute. */
+
err |= __put_user(signr, &sframep->sig_num);
- if(signr == SIGSEGV ||
- signr == SIGILL ||
- signr == SIGFPE ||
- signr == SIGBUS ||
- signr == SIGEMT) {
- err |= __put_user(current->thread.sig_desc, &sframep->sig_code);
- err |= __put_user(current->thread.sig_address, &sframep->sig_address);
- } else {
- err |= __put_user(0, &sframep->sig_code);
- err |= __put_user(0, &sframep->sig_address);
+ sig_address = NULL;
+ sig_code = 0;
+ if (SI_FROMKERNEL (info) && (info->si_code & __SI_MASK) == __SI_FAULT) {
+ sig_address = info->si_addr;
+ switch (signr) {
+ case SIGSEGV:
+ switch (info->si_code) {
+ case SEGV_MAPERR: sig_code = SUBSIG_NOMAPPING; break;
+ default: sig_code = SUBSIG_PROTECTION; break;
+ }
+ break;
+ case SIGILL:
+ switch (info->si_code) {
+ case ILL_ILLOPC: sig_code = SUBSIG_ILLINST; break;
+ case ILL_PRVOPC: sig_code = SUBSIG_PRIVINST; break;
+ case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP (info->si_trapno); break;
+ default: sig_code = SUBSIG_STACK; break;
+ }
+ break;
+ case SIGFPE:
+ switch (info->si_code) {
+ case FPE_INTDIV: sig_code = SUBSIG_IDIVZERO; break;
+ case FPE_INTOVF: sig_code = SUBSIG_FPINTOVFL; break;
+ case FPE_FLTDIV: sig_code = SUBSIG_FPDIVZERO; break;
+ case FPE_FLTOVF: sig_code = SUBSIG_FPOVFLOW; break;
+ case FPE_FLTUND: sig_code = SUBSIG_FPUNFLOW; break;
+ case FPE_FLTRES: sig_code = SUBSIG_FPINEXACT; break;
+ case FPE_FLTINV: sig_code = SUBSIG_FPOPERROR; break;
+ default: sig_code = SUBSIG_FPERROR; break;
+ }
+ break;
+ case SIGBUS:
+ switch (info->si_code) {
+ case BUS_ADRALN: sig_code = SUBSIG_ALIGNMENT; break;
+ case BUS_ADRERR: sig_code = SUBSIG_MISCERROR; break;
+ default: sig_code = SUBSIG_BUSTIMEOUT; break;
+ }
+ break;
+ case SIGEMT:
+ switch (info->si_code) {
+ case EMT_TAGOVF: sig_code = SUBSIG_TAG; break;
+ }
+ break;
+ case SIGSYS:
+ if (info->si_code == (__SI_FAULT|0x100)) {
+ /* See sys_sunos.c */
+ sig_code = info->si_trapno;
+ break;
+ }
+ default:
+ sig_address = NULL;
+ }
}
+ err |= __put_user((long)sig_address, &sframep->sig_address);
+ err |= __put_user(sig_code, &sframep->sig_code);
err |= __put_user(sc, &sframep->sig_scptr);
if (err)
goto sigsegv;
@@ -791,8 +839,7 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
/* Setup the signal information. Solaris expects a bunch of
* information to be passed to the signal handler, we don't provide
- * that much currently, should use those that David already
- * is providing with thread.sig_desc
+ * that much currently, should use siginfo.
*/
err |= __put_user(signr, &si->siginfo.signo);
err |= __put_user(SVR4_SINOINFO, &si->siginfo.code);
@@ -977,7 +1024,7 @@ handle_signal(unsigned long signr, struct k_sigaction *ka,
else if (current->thread.new_signal)
new_setup_frame (ka, regs, signr, oldset);
else
- setup_frame(&ka->sa, regs->pc, regs->npc, regs, signr, oldset);
+ setup_frame(&ka->sa, regs, signr, oldset, info);
}
if(ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
@@ -1074,7 +1121,16 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
struct k_sigaction *ka;
siginfo_t info;
+ /*
+ * XXX Disable svr4 signal handling until solaris emulation works.
+ * It is buggy - Anton
+ */
+#define SVR4_SIGNAL_BROKEN 1
+#ifdef SVR4_SIGNAL_BROKEN
+ int svr4_signal = 0;
+#else
int svr4_signal = current->personality == PER_SVR4;
+#endif
if (!oldset)
oldset = &current->blocked;
diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c
index 58f1be4e8..6153eb99e 100644
--- a/arch/sparc/kernel/smp.c
+++ b/arch/sparc/kernel/smp.c
@@ -15,6 +15,7 @@
#include <linux/kernel_stat.h>
#include <linux/init.h>
#include <linux/spinlock.h>
+#include <linux/mm.h>
#include <asm/ptrace.h>
#include <asm/atomic.h>
@@ -51,7 +52,7 @@ unsigned long cpu_offset[NR_CPUS];
unsigned char boot_cpu_id = 0;
unsigned char boot_cpu_id4 = 0; /* boot_cpu_id << 2 */
int smp_activated = 0;
-volatile int cpu_number_map[NR_CPUS];
+volatile int __cpu_number_map[NR_CPUS];
volatile int __cpu_logical_map[NR_CPUS];
cycles_t cacheflush_time = 0; /* XXX */
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 6943aa4e6..b8cdd3749 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -1,4 +1,4 @@
-/* $Id: sparc_ksyms.c,v 1.86 2000/01/09 10:46:49 anton Exp $
+/* $Id: sparc_ksyms.c,v 1.87 2000/01/21 17:41:14 anton Exp $
* arch/sparc/kernel/ksyms.c: Sparc specific ksyms support.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -16,6 +16,7 @@
#include <linux/interrupt.h>
#include <linux/in6.h>
#include <linux/spinlock.h>
+#include <linux/mm.h>
#include <asm/oplib.h>
#include <asm/delay.h>
@@ -182,8 +183,8 @@ EXPORT_SYMBOL_NOVERS(BTFIXUP_CALL(mmu_release_scsi_one));
EXPORT_SYMBOL(sbus_root);
EXPORT_SYMBOL(dma_chain);
EXPORT_SYMBOL(sbus_set_sbus64);
-EXPORT_SYMBOL(sbus_alloc_consistant);
-EXPORT_SYMBOL(sbus_free_consistant);
+EXPORT_SYMBOL(sbus_alloc_consistent);
+EXPORT_SYMBOL(sbus_free_consistent);
EXPORT_SYMBOL(sbus_map_single);
EXPORT_SYMBOL(sbus_unmap_single);
EXPORT_SYMBOL(sbus_map_sg);
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index ec105ec18..b589712aa 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -18,6 +18,7 @@
#include <linux/kernel_stat.h>
#include <linux/init.h>
#include <linux/spinlock.h>
+#include <linux/mm.h>
#include <asm/ptrace.h>
#include <asm/atomic.h>
@@ -57,13 +58,15 @@ extern struct cpuinfo_sparc cpu_data[NR_CPUS];
extern unsigned long cpu_offset[NR_CPUS];
extern unsigned char boot_cpu_id;
extern int smp_activated;
-extern volatile int cpu_number_map[NR_CPUS];
+extern volatile int __cpu_number_map[NR_CPUS];
extern volatile int __cpu_logical_map[NR_CPUS];
extern volatile unsigned long ipi_count;
extern volatile int smp_process_available;
extern volatile int smp_commenced;
extern int __smp4d_processor_id(void);
+extern unsigned long totalram_pages;
+
/* #define SMP_DEBUG */
#ifdef SMP_DEBUG
@@ -138,10 +141,10 @@ void __init smp4d_callin(void)
cpu_leds[cpuid] = 0x9;
show_leds(cpuid);
- current->mm->mmap->vm_page_prot = PAGE_SHARED;
- current->mm->mmap->vm_start = PAGE_OFFSET;
- current->mm->mmap->vm_end = init_mm.mmap->vm_end;
-
+ /* Attach to the address space of init_task. */
+ atomic_inc(&init_mm.mm_count);
+ current->active_mm = &init_mm;
+
local_flush_cache_all();
local_flush_tlb_all();
@@ -189,12 +192,12 @@ void __init smp4d_boot_cpus(void)
cpu_present_map |= (1<<linux_cpus[i].mid);
SMP_PRINTK(("cpu_present_map %08lx\n", cpu_present_map));
for(i=0; i < NR_CPUS; i++)
- cpu_number_map[i] = -1;
+ __cpu_number_map[i] = -1;
for(i=0; i < NR_CPUS; i++)
__cpu_logical_map[i] = -1;
for(i=0; i < NR_CPUS; i++)
mid_xlate[i] = i;
- cpu_number_map[boot_cpu_id] = 0;
+ __cpu_number_map[boot_cpu_id] = 0;
__cpu_logical_map[0] = boot_cpu_id;
current->processor = boot_cpu_id;
smp_store_cpu_info(boot_cpu_id);
@@ -218,12 +221,19 @@ void __init smp4d_boot_cpus(void)
/* Cook up an idler for this guy. */
kernel_thread(start_secondary, NULL, CLONE_PID);
- p = task[++cpucount];
+ cpucount++;
+
+ p = init_task.prev_task;
+ init_tasks[i] = p;
p->processor = i;
p->has_cpu = 1; /* we schedule the first task manually */
+
current_set[i] = p;
-
+
+ del_from_runqueue(p);
+ unhash_process(p);
+
for (no = 0; no < linux_num_cpus; no++)
if (linux_cpus[no].mid == i)
break;
@@ -254,7 +264,7 @@ void __init smp4d_boot_cpus(void)
if(cpu_callin_map[i]) {
/* Another "Red Snapper". */
- cpu_number_map[i] = cpucount;
+ __cpu_number_map[i] = cpucount;
__cpu_logical_map[cpucount] = i;
} else {
cpucount--;
@@ -263,7 +273,7 @@ void __init smp4d_boot_cpus(void)
}
if(!(cpu_callin_map[i])) {
cpu_present_map &= ~(1 << i);
- cpu_number_map[i] = -1;
+ __cpu_number_map[i] = -1;
}
}
local_flush_cache_all();
@@ -289,13 +299,23 @@ void __init smp4d_boot_cpus(void)
}
/* Free unneeded trap tables */
-
- mem_map[MAP_NR((unsigned long)trapbase_cpu1)].flags &= ~(1 << PG_reserved);
+ ClearPageReserved(mem_map + MAP_NR(trapbase_cpu1));
+ set_page_count(mem_map + MAP_NR(trapbase_cpu1), 1);
free_page((unsigned long)trapbase_cpu1);
- mem_map[MAP_NR((unsigned long)trapbase_cpu2)].flags &= ~(1 << PG_reserved);
+ totalram_pages++;
+ num_physpages++;
+
+ ClearPageReserved(mem_map + MAP_NR(trapbase_cpu2));
+ set_page_count(mem_map + MAP_NR(trapbase_cpu2), 1);
free_page((unsigned long)trapbase_cpu2);
- mem_map[MAP_NR((unsigned long)trapbase_cpu3)].flags &= ~(1 << PG_reserved);
+ totalram_pages++;
+ num_physpages++;
+
+ ClearPageReserved(mem_map + MAP_NR(trapbase_cpu3));
+ set_page_count(mem_map + MAP_NR(trapbase_cpu3), 1);
free_page((unsigned long)trapbase_cpu3);
+ totalram_pages++;
+ num_physpages++;
/* Ok, they are spinning and ready to go. */
smp_processors_ready = 1;
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index 2d2d97810..36c3d3c25 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -14,6 +14,7 @@
#include <linux/kernel_stat.h>
#include <linux/init.h>
#include <linux/spinlock.h>
+#include <linux/mm.h>
#include <asm/ptrace.h>
#include <asm/atomic.h>
@@ -52,13 +53,15 @@ extern struct cpuinfo_sparc cpu_data[NR_CPUS];
extern unsigned long cpu_offset[NR_CPUS];
extern unsigned char boot_cpu_id;
extern int smp_activated;
-extern volatile int cpu_number_map[NR_CPUS];
+extern volatile int __cpu_number_map[NR_CPUS];
extern volatile int __cpu_logical_map[NR_CPUS];
extern volatile unsigned long ipi_count;
extern volatile int smp_process_available;
extern volatile int smp_commenced;
extern int __smp4m_processor_id(void);
+extern unsigned long totalram_pages;
+
/*#define SMP_DEBUG*/
#ifdef SMP_DEBUG
@@ -84,6 +87,7 @@ void __init smp4m_callin(void)
local_flush_cache_all();
local_flush_tlb_all();
+
set_irq_udt(mid_xlate[boot_cpu_id]);
/* Get our local ticker going. */
@@ -91,6 +95,7 @@ void __init smp4m_callin(void)
calibrate_delay();
smp_store_cpu_info(cpuid);
+
local_flush_cache_all();
local_flush_tlb_all();
@@ -104,22 +109,21 @@ void __init smp4m_callin(void)
/* Allow master to continue. */
swap((unsigned long *)&cpu_callin_map[cpuid], 1);
+
local_flush_cache_all();
local_flush_tlb_all();
cpu_probe();
- while(!task[cpuid] || current_set[cpuid] != task[cpuid])
- barrier();
-
/* Fix idle thread fields. */
__asm__ __volatile__("ld [%0], %%g6\n\t"
: : "r" (&current_set[cpuid])
: "memory" /* paranoid */);
- current->mm->mmap->vm_page_prot = PAGE_SHARED;
- current->mm->mmap->vm_start = PAGE_OFFSET;
- current->mm->mmap->vm_end = init_mm.mmap->vm_end;
-
+
+ /* Attach to the address space of init_task. */
+ atomic_inc(&init_mm.mm_count);
+ current->active_mm = &init_mm;
+
while(!smp_commenced)
barrier();
@@ -152,21 +156,23 @@ void __init smp4m_boot_cpus(void)
printk("Entering SMP Mode...\n");
- for (i = 0; i < NR_CPUS; i++)
- cpu_offset[i] = (char *)&cpu_data[i] - (char *)&cpu_data;
-
__sti();
cpu_present_map = 0;
+
for(i=0; i < linux_num_cpus; i++)
cpu_present_map |= (1<<i);
- for(i=0; i < NR_CPUS; i++)
- cpu_number_map[i] = -1;
- for(i=0; i < NR_CPUS; i++)
+
+ for(i=0; i < NR_CPUS; i++) {
+ cpu_offset[i] = (char *)&cpu_data[i] - (char *)&cpu_data;
+ __cpu_number_map[i] = -1;
__cpu_logical_map[i] = -1;
+ }
+
mid_xlate[boot_cpu_id] = (linux_cpus[boot_cpu_id].mid & ~8);
- cpu_number_map[boot_cpu_id] = 0;
+ __cpu_number_map[boot_cpu_id] = 0;
__cpu_logical_map[0] = boot_cpu_id;
current->processor = boot_cpu_id;
+
smp_store_cpu_info(boot_cpu_id);
set_irq_udt(mid_xlate[boot_cpu_id]);
smp_setup_percpu_timer();
@@ -187,12 +193,19 @@ void __init smp4m_boot_cpus(void)
/* Cook up an idler for this guy. */
kernel_thread(start_secondary, NULL, CLONE_PID);
- p = task[++cpucount];
+ cpucount++;
+
+ p = init_task.prev_task;
+ init_tasks[i] = p;
p->processor = i;
p->has_cpu = 1; /* we schedule the first task manually */
+
current_set[i] = p;
+ del_from_runqueue(p);
+ unhash_process(p);
+
/* See trampoline.S for details... */
entry += ((i-1) * 3);
@@ -220,7 +233,7 @@ void __init smp4m_boot_cpus(void)
}
if(cpu_callin_map[i]) {
/* Another "Red Snapper". */
- cpu_number_map[i] = i;
+ __cpu_number_map[i] = i;
__cpu_logical_map[i] = i;
} else {
cpucount--;
@@ -229,7 +242,7 @@ void __init smp4m_boot_cpus(void)
}
if(!(cpu_callin_map[i])) {
cpu_present_map &= ~(1 << i);
- cpu_number_map[i] = -1;
+ __cpu_number_map[i] = -1;
}
}
local_flush_cache_all();
@@ -265,18 +278,26 @@ void __init smp4m_boot_cpus(void)
cpu_data[prev].next = first;
/* Free unneeded trap tables */
-
if (!(cpu_present_map & (1 << 1))) {
- mem_map[MAP_NR((unsigned long)trapbase_cpu1)].flags &= ~(1 << PG_reserved);
+ ClearPageReserved(mem_map + MAP_NR(trapbase_cpu1));
+ set_page_count(mem_map + MAP_NR(trapbase_cpu1), 1);
free_page((unsigned long)trapbase_cpu1);
+ totalram_pages++;
+ num_physpages++;
}
if (!(cpu_present_map & (1 << 2))) {
- mem_map[MAP_NR((unsigned long)trapbase_cpu2)].flags &= ~(1 << PG_reserved);
+ ClearPageReserved(mem_map + MAP_NR(trapbase_cpu2));
+ set_page_count(mem_map + MAP_NR(trapbase_cpu2), 1);
free_page((unsigned long)trapbase_cpu2);
+ totalram_pages++;
+ num_physpages++;
}
if (!(cpu_present_map & (1 << 3))) {
- mem_map[MAP_NR((unsigned long)trapbase_cpu3)].flags &= ~(1 << PG_reserved);
+ ClearPageReserved(mem_map + MAP_NR(trapbase_cpu3));
+ set_page_count(mem_map + MAP_NR(trapbase_cpu3), 1);
free_page((unsigned long)trapbase_cpu3);
+ totalram_pages++;
+ num_physpages++;
}
/* Ok, they are spinning and ready to go. */
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
index 69379de4a..4dcb7866a 100644
--- a/arch/sparc/kernel/sys_sparc.c
+++ b/arch/sparc/kernel/sys_sparc.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.56 2000/01/04 11:01:26 jj Exp $
+/* $Id: sys_sparc.c,v 1.57 2000/01/21 11:38:42 jj Exp $
* linux/arch/sparc/kernel/sys_sparc.c
*
* This file contains various random system calls that
@@ -260,11 +260,19 @@ c_sys_nis_syscall (struct pt_regs *regs)
asmlinkage void
sparc_breakpoint (struct pt_regs *regs)
{
+ siginfo_t info;
+
lock_kernel();
#ifdef DEBUG_SPARC_BREAKPOINT
printk ("TRAP: Entering kernel PC=%x, nPC=%x\n", regs->pc, regs->npc);
#endif
- force_sig(SIGTRAP, current);
+ info.si_signo = SIGTRAP;
+ info.si_errno = 0;
+ info.si_code = TRAP_BRKPT;
+ info.si_addr = (void *)regs->pc;
+ info.si_trapno = 0;
+ force_sig_info(SIGTRAP, &info, current);
+
#ifdef DEBUG_SPARC_BREAKPOINT
printk ("TRAP: Returning to space: PC=%x nPC=%x\n", regs->pc, regs->npc);
#endif
@@ -360,7 +368,7 @@ asmlinkage int sys_getdomainname(char *name, int len)
int nlen;
int err = -EFAULT;
- down(&uts_sem);
+ down_read(&uts_sem);
nlen = strlen(system_utsname.domainname) + 1;
@@ -372,7 +380,7 @@ asmlinkage int sys_getdomainname(char *name, int len)
goto done;
err = 0;
done:
- up(&uts_sem);
+ up_read(&uts_sem);
return err;
}
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
index ddac348fe..15f38bd5e 100644
--- a/arch/sparc/kernel/sys_sunos.c
+++ b/arch/sparc/kernel/sys_sunos.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos.c,v 1.108 2000/01/06 23:51:46 davem Exp $
+/* $Id: sys_sunos.c,v 1.111 2000/01/22 05:17:55 anton Exp $
* sys_sunos.c: SunOS specific syscall compatibility support.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -366,6 +366,7 @@ asmlinkage unsigned long sunos_sigblock(unsigned long blk_mask)
spin_lock_irq(&current->sigmask_lock);
old = current->blocked.sig[0];
current->blocked.sig[0] |= (blk_mask & _BLOCKABLE);
+ recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
return old;
}
@@ -377,6 +378,7 @@ asmlinkage unsigned long sunos_sigsetmask(unsigned long newmask)
spin_lock_irq(&current->sigmask_lock);
retval = current->blocked.sig[0];
current->blocked.sig[0] = (newmask & _BLOCKABLE);
+ recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
return retval;
}
@@ -579,7 +581,7 @@ struct sunos_utsname {
asmlinkage int sunos_uname(struct sunos_utsname *name)
{
int ret;
- down(&uts_sem);
+ down_read(&uts_sem);
ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1);
if (!ret) {
ret |= __copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1);
@@ -588,22 +590,29 @@ asmlinkage int sunos_uname(struct sunos_utsname *name)
ret |= __copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1);
ret |= __copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1);
}
- up(&uts_sem);
+ up_read(&uts_sem);
return ret;
}
asmlinkage int sunos_nosys(void)
{
struct pt_regs *regs;
+ siginfo_t info;
+ static int cnt;
lock_kernel();
regs = current->thread.kregs;
- current->thread.sig_address = regs->pc;
- current->thread.sig_desc = regs->u_regs[UREG_G1];
- send_sig(SIGSYS, current, 1);
- printk("Process makes ni_syscall number %d, register dump:\n",
- (int) regs->u_regs[UREG_G1]);
- show_regs(regs);
+ info.si_signo = SIGSYS;
+ info.si_errno = 0;
+ info.si_code = __SI_FAULT|0x100;
+ info.si_addr = (void *)regs->pc;
+ info.si_trapno = regs->u_regs[UREG_G1];
+ send_sig_info(SIGSYS, &info, current);
+ if (cnt++ < 4) {
+ printk("Process makes ni_syscall number %d, register dump:\n",
+ (int) regs->u_regs[UREG_G1]);
+ show_regs(regs);
+ }
unlock_kernel();
return -ENOSYS;
}
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index 6da3c3f21..47aea979b 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.90 2000/01/11 17:33:20 jj Exp $
+/* $Id: systbls.S,v 1.91 2000/01/16 06:20:44 davem Exp $
* systbls.S: System call entry point tables for OS compatibility.
* The native Linux system call table lives here also.
*
@@ -33,15 +33,15 @@ sys_call_table:
/*60*/ .long sys_umask, sys_chroot, sys_newfstat, sys_fstat64, sys_getpagesize
/*65*/ .long sys_msync, sys_vfork, sys_pread, sys_pwrite, sys_geteuid
/*70*/ .long sys_getegid, sys_mmap, sys_setreuid, sys_munmap, sys_mprotect
-/*75*/ .long sys_setregid, sys_vhangup, sys_truncate64, sys_getgroups, sys_getgroups16
+/*75*/ .long sys_nis_syscall, sys_vhangup, sys_truncate64, sys_nis_syscall, sys_getgroups16
/*80*/ .long sys_setgroups16, sys_getpgrp, sys_setgroups, sys_setitimer, sys_ftruncate64
/*85*/ .long sys_swapon, sys_getitimer, sys_setuid, sys_sethostname, sys_setgid
/*90*/ .long sys_dup2, sys_setfsuid, sys_fcntl, sys_select, sys_setfsgid
/*95*/ .long sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
/*100*/ .long sys_getpriority, sys_rt_sigreturn, sys_rt_sigaction, sys_rt_sigprocmask, sys_rt_sigpending
/*105*/ .long sys_rt_sigtimedwait, sys_rt_sigqueueinfo, sys_rt_sigsuspend, sys_setresuid, sys_getresuid
-/*110*/ .long sys_setresgid, sys_getresgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
-/*115*/ .long sys_nis_syscall, sys_gettimeofday, sys_getrusage, sys_nis_syscall, sys_getcwd
+/*110*/ .long sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
+/*115*/ .long sys_getgroups, sys_gettimeofday, sys_getrusage, sys_nis_syscall, sys_getcwd
/*120*/ .long sys_readv, sys_writev, sys_settimeofday, sys_fchown16, sys_fchmod
/*125*/ .long sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate
/*130*/ .long sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 008567aba..295988f58 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.49 1999/11/17 07:34:07 zaitcev Exp $
+/* $Id: time.c,v 1.50 2000/01/21 04:35:53 anton Exp $
* linux/arch/sparc/kernel/time.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -229,7 +229,7 @@ static __inline__ void sun4_clock_probe(void)
sp_clock_typ = INTERSIL;
r.start = sun4_clock_physaddr;
intersil_clock = (struct intersil *)
- sparc_ioremap(&r, 0, sizeof(*intersil_clock), "intersil");
+ sbus_ioremap(&r, 0, sizeof(*intersil_clock), "intersil");
mstk48t02_regs = 0; /* just be sure */
mstk48t08_regs = 0; /* ditto */
/* initialise the clock */
diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c
index 31b64b0cd..d7159f9ff 100644
--- a/arch/sparc/kernel/traps.c
+++ b/arch/sparc/kernel/traps.c
@@ -1,7 +1,8 @@
-/* $Id: traps.c,v 1.60 1999/08/14 03:51:31 anton Exp $
+/* $Id: traps.c,v 1.61 2000/01/21 11:38:41 jj Exp $
* arch/sparc/kernel/traps.c
*
* Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright 2000 Jakub Jelinek (jakub@redhat.com)
*/
/*
@@ -128,6 +129,8 @@ void die_if_kernel(char *str, struct pt_regs *regs)
void do_hw_interrupt(unsigned long type, unsigned long psr, unsigned long pc)
{
+ siginfo_t info;
+
lock_kernel();
if(type < 0x80) {
/* Sun OS's puke from bad traps, Linux survives! */
@@ -135,22 +138,23 @@ void do_hw_interrupt(unsigned long type, unsigned long psr, unsigned long pc)
die_if_kernel("Whee... Hello Mr. Penguin", current->thread.kregs);
}
- if(type == SP_TRAP_SBPT) {
- send_sig(SIGTRAP, current, 1);
- } else {
- if(psr & PSR_PS)
- die_if_kernel("Kernel bad trap", current->thread.kregs);
-
- current->thread.sig_desc = SUBSIG_BADTRAP(type - 0x80);
- current->thread.sig_address = pc;
- send_sig(SIGILL, current, 1);
- }
+ if(psr & PSR_PS)
+ die_if_kernel("Kernel bad trap", current->thread.kregs);
+
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = ILL_ILLTRP;
+ info.si_addr = (void *)pc;
+ info.si_trapno = type - 0x80;
+ force_sig_info(SIGILL, &info, current);
unlock_kernel();
}
void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc,
unsigned long psr)
{
+ siginfo_t info;
+
lock_kernel();
if(psr & PSR_PS)
die_if_kernel("Kernel illegal instruction", regs);
@@ -163,9 +167,12 @@ void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned lon
if (!do_user_muldiv (regs, pc))
goto out;
}
- current->thread.sig_address = pc;
- current->thread.sig_desc = SUBSIG_ILLINST;
- send_sig(SIGILL, current, 1);
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = ILL_ILLOPC;
+ info.si_addr = (void *)pc;
+ info.si_trapno = 0;
+ send_sig_info(SIGILL, &info, current);
out:
unlock_kernel();
}
@@ -173,12 +180,17 @@ out:
void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc,
unsigned long psr)
{
+ siginfo_t info;
+
lock_kernel();
if(psr & PSR_PS)
die_if_kernel("Penguin instruction from Penguin mode??!?!", regs);
- current->thread.sig_address = pc;
- current->thread.sig_desc = SUBSIG_PRIVINST;
- send_sig(SIGILL, current, 1);
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = ILL_PRVOPC;
+ info.si_addr = (void *)pc;
+ info.si_trapno = 0;
+ send_sig_info(SIGILL, &info, current);
unlock_kernel();
}
@@ -187,6 +199,8 @@ void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long n
void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, unsigned long npc,
unsigned long psr)
{
+ siginfo_t info;
+
lock_kernel();
if(regs->psr & PSR_PS) {
printk("KERNEL MNA at pc %08lx npc %08lx called by %08lx\n", pc, npc,
@@ -194,14 +208,17 @@ void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, unsigned lon
die_if_kernel("BOGUS", regs);
/* die_if_kernel("Kernel MNA access", regs); */
}
- current->thread.sig_address = pc;
- current->thread.sig_desc = SUBSIG_PRIVINST;
#if 0
show_regs (regs);
instruction_dump ((unsigned long *) regs->pc);
printk ("do_MNA!\n");
#endif
- send_sig(SIGBUS, current, 1);
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = BUS_ADRALN;
+ info.si_addr = /* FIXME: Should dig out mna address */ (void *)0;
+ info.si_trapno = 0;
+ send_sig_info(SIGBUS, &info, current);
unlock_kernel();
}
@@ -269,6 +286,8 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
unsigned long psr)
{
static int calls = 0;
+ siginfo_t info;
+ unsigned long fsr;
int ret = 0;
#ifndef __SMP__
struct task_struct *fpt = last_task_used_math;
@@ -326,8 +345,6 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
}
/* nope, better SIGFPE the offending process... */
- fpt->thread.sig_address = pc;
- fpt->thread.sig_desc = SUBSIG_FPERROR; /* as good as any */
#ifdef __SMP__
fpt->flags &= ~PF_USEDFPU;
#endif
@@ -345,7 +362,26 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
regs);
goto out;
}
- send_sig(SIGFPE, fpt, 1);
+
+ fsr = fpt->thread.fsr;
+ info.si_signo = SIGFPE;
+ info.si_errno = 0;
+ info.si_addr = (void *)pc;
+ info.si_trapno = 0;
+ info.si_code = __SI_FAULT;
+ if ((fsr & 0x1c000) == (1 << 14)) {
+ if (fsr & 0x10)
+ info.si_code = FPE_FLTINV;
+ else if (fsr & 0x08)
+ info.si_code = FPE_FLTOVF;
+ else if (fsr & 0x04)
+ info.si_code = FPE_FLTUND;
+ else if (fsr & 0x02)
+ info.si_code = FPE_FLTDIV;
+ else if (fsr & 0x01)
+ info.si_code = FPE_FLTRES;
+ }
+ send_sig_info(SIGFPE, &info, fpt);
#ifndef __SMP__
last_task_used_math = NULL;
#endif
@@ -359,12 +395,17 @@ out:
void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, unsigned long npc,
unsigned long psr)
{
+ siginfo_t info;
+
lock_kernel();
if(psr & PSR_PS)
die_if_kernel("Penguin overflow trap from kernel mode", regs);
- current->thread.sig_address = pc;
- current->thread.sig_desc = SUBSIG_TAG; /* as good as any */
- send_sig(SIGEMT, current, 1);
+ info.si_signo = SIGEMT;
+ info.si_errno = 0;
+ info.si_code = EMT_TAGOVF;
+ info.si_addr = (void *)pc;
+ info.si_trapno = 0;
+ send_sig_info(SIGEMT, &info, current);
unlock_kernel();
}
@@ -385,40 +426,69 @@ void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long npc
void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc,
unsigned long psr)
{
+ siginfo_t info;
+
lock_kernel();
#ifdef TRAP_DEBUG
printk("Register Access Exception at PC %08lx NPC %08lx PSR %08lx\n",
pc, npc, psr);
#endif
- send_sig(SIGILL, current, 1);
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = BUS_OBJERR;
+ info.si_addr = (void *)pc;
+ info.si_trapno = 0;
+ force_sig_info(SIGBUS, &info, current);
unlock_kernel();
}
void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long npc,
unsigned long psr)
{
+ siginfo_t info;
+
lock_kernel();
- send_sig(SIGILL, current, 1);
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = ILL_COPROC;
+ info.si_addr = (void *)pc;
+ info.si_trapno = 0;
+ send_sig_info(SIGILL, &info, current);
unlock_kernel();
}
void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long npc,
unsigned long psr)
{
+ siginfo_t info;
+
lock_kernel();
#ifdef TRAP_DEBUG
printk("Co-Processor Exception at PC %08lx NPC %08lx PSR %08lx\n",
pc, npc, psr);
#endif
- send_sig(SIGILL, current, 1);
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = ILL_COPROC;
+ info.si_addr = (void *)pc;
+ info.si_trapno = 0;
+ send_sig_info(SIGILL, &info, current);
unlock_kernel();
}
void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, unsigned long npc,
unsigned long psr)
{
+ siginfo_t info;
+
lock_kernel();
- send_sig(SIGILL, current, 1);
+ info.si_signo = SIGFPE;
+ info.si_errno = 0;
+ info.si_code = FPE_INTDIV;
+ info.si_addr = (void *)pc;
+ info.si_trapno = 0;
+ send_sig_info(SIGFPE, &info, current);
+
unlock_kernel();
}
diff --git a/arch/sparc/kernel/unaligned.c b/arch/sparc/kernel/unaligned.c
index ff9295e9d..592a2a4c0 100644
--- a/arch/sparc/kernel/unaligned.c
+++ b/arch/sparc/kernel/unaligned.c
@@ -1,4 +1,4 @@
-/* $Id: unaligned.c,v 1.19 1999/08/14 03:51:33 anton Exp $
+/* $Id: unaligned.c,v 1.20 2000/01/21 11:38:42 jj Exp $
* unaligned.c: Unaligned load/store trap handling with special
* cases for the kernel to do them more quickly.
*
@@ -422,9 +422,14 @@ void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("user
void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
{
- current->thread.sig_address = regs->pc;
- current->thread.sig_desc = SUBSIG_PRIVINST;
- send_sig(SIGBUS, current, 1);
+ siginfo_t info;
+
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = BUS_ADRALN;
+ info.si_addr = (void *)compute_effective_address(regs, insn);
+ info.si_trapno = 0;
+ send_sig_info(SIGBUS, &info, current);
}
asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
@@ -487,9 +492,7 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
}
kill_user:
- current->thread.sig_address = regs->pc;
- current->thread.sig_desc = SUBSIG_PRIVINST;
- send_sig(SIGBUS, current, 1);
+ user_mna_trap_fault(regs, insn);
out:
unlock_kernel();
}
diff --git a/arch/sparc/mm/asyncd.c b/arch/sparc/mm/asyncd.c
index 569940417..0034cb60b 100644
--- a/arch/sparc/mm/asyncd.c
+++ b/arch/sparc/mm/asyncd.c
@@ -1,4 +1,4 @@
-/* $Id: asyncd.c,v 1.19 2000/01/08 20:22:16 davem Exp $
+/* $Id: asyncd.c,v 1.20 2000/01/21 11:38:47 jj Exp $
* The asyncd kernel daemon. This handles paging on behalf of
* processes that receive page faults due to remote (async) memory
* accesses.
@@ -116,6 +116,7 @@ static int fault_in_page(int taskid,
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte;
+ siginfo_t info;
if (!tsk || !tsk->mm)
return 1;
@@ -179,9 +180,12 @@ no_memory:
bad_area:
stats.failure++;
- tsk->thread.sig_address = address;
- tsk->thread.sig_desc = SUBSIG_NOMAPPING;
- send_sig(SIGSEGV, tsk, 1);
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ info.si_code = SEGV_MAPERR;
+ info.si_addr = (void *)address;
+ info.si_trapno = 0;
+ send_sig_info(SIGSEGV, &info, tsk);
return 1;
}
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index ba75681b1..d9981e68b 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.111 1999/10/24 13:45:59 anton Exp $
+/* $Id: fault.c,v 1.113 2000/01/21 11:38:47 jj Exp $
* fault.c: Page fault handlers for the Sparc.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -197,8 +197,10 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
struct mm_struct *mm = tsk->mm;
unsigned int fixup;
unsigned long g2;
+ siginfo_t info;
int from_user = !(regs->psr & PSR_PS);
+ info.si_code = SEGV_MAPERR;
if(text_fault)
address = regs->pc;
@@ -207,10 +209,12 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
* context, we must not take the fault..
*/
if (in_interrupt() || !mm)
- goto do_kernel_fault;
+ goto no_context;
down(&mm->mmap_sem);
- /* The kernel referencing a bad kernel pointer can lock up
+
+ /*
+ * The kernel referencing a bad kernel pointer can lock up
* a sun4c machine completely, so we must attempt recovery.
*/
if(!from_user && address >= PAGE_OFFSET)
@@ -230,6 +234,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
* we can handle it..
*/
good_area:
+ info.si_code = SEGV_ACCERR;
if(write) {
if(!(vma->vm_flags & VM_WRITE))
goto bad_area;
@@ -238,18 +243,47 @@ good_area:
if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
- if (!handle_mm_fault(current, vma, address, write))
- goto do_sigbus;
+
+ /*
+ * If for any reason at all we couldn't handle the fault,
+ * make sure we exit gracefully rather than endlessly redo
+ * the fault.
+ */
+ {
+ int fault = handle_mm_fault(tsk, vma, address, write);
+ if (fault < 0)
+ goto out_of_memory;
+ if (!fault)
+ goto do_sigbus;
+ }
up(&mm->mmap_sem);
return;
+
/*
* Something tried to access memory that isn't in our memory map..
* Fix it, but check if it's kernel or user first..
*/
bad_area:
up(&mm->mmap_sem);
+
+ /* User mode accesses just cause a SIGSEGV */
+ if(from_user) {
+#if 0
+ printk("Fault whee %s [%d]: segfaults at %08lx pc=%08lx\n",
+ tsk->comm, tsk->pid, address, regs->pc);
+#endif
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ /* info.si_code set above to make clear whether
+ this was a SEGV_MAPERR or SEGV_ACCERR fault. */
+ info.si_addr = (void *)address;
+ info.si_trapno = 0;
+ force_sig_info (SIGSEGV, &info, tsk);
+ return;
+ }
+
/* Is this in ex_table? */
-do_kernel_fault:
+no_context:
g2 = regs->u_regs[UREG_G2];
if (!from_user && (fixup = search_exception_table (regs->pc, &g2))) {
if (fixup > 10) { /* Values below are reserved for other things */
@@ -276,26 +310,31 @@ do_kernel_fault:
return;
}
}
- if(from_user) {
-#if 0
- printk("Fault whee %s [%d]: segfaults at %08lx pc=%08lx\n",
- tsk->comm, tsk->pid, address, regs->pc);
-#endif
- tsk->thread.sig_address = address;
- tsk->thread.sig_desc = SUBSIG_NOMAPPING;
- force_sig(SIGSEGV, tsk);
- return;
- }
+
unhandled_fault (address, tsk, regs);
- return;
+ do_exit(SIGKILL);
+
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+out_of_memory:
+ up(&mm->mmap_sem);
+ printk("VM: killing process %s\n", tsk->comm);
+ if (from_user)
+ do_exit(SIGKILL);
+ goto no_context;
do_sigbus:
up(&mm->mmap_sem);
- tsk->thread.sig_address = address;
- tsk->thread.sig_desc = SUBSIG_MISCERROR;
- force_sig(SIGBUS, tsk);
- if (! from_user)
- goto do_kernel_fault;
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = BUS_ADRERR;
+ info.si_addr = (void *)address;
+ info.si_trapno = 0;
+ force_sig_info (SIGBUS, &info, tsk);
+ if (!from_user)
+ goto no_context;
}
asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
@@ -385,6 +424,9 @@ inline void force_user_fault(unsigned long address, int write)
struct vm_area_struct *vma;
struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
+ siginfo_t info;
+
+ info.si_code = SEGV_MAPERR;
#if 0
printk("wf<pid=%d,wr=%d,addr=%08lx>\n",
@@ -401,6 +443,7 @@ inline void force_user_fault(unsigned long address, int write)
if(expand_stack(vma, address))
goto bad_area;
good_area:
+ info.si_code = SEGV_ACCERR;
if(write) {
if(!(vma->vm_flags & VM_WRITE))
goto bad_area;
@@ -418,16 +461,23 @@ bad_area:
printk("Window whee %s [%d]: segfaults at %08lx\n",
tsk->comm, tsk->pid, address);
#endif
- tsk->thread.sig_address = address;
- tsk->thread.sig_desc = SUBSIG_NOMAPPING;
- send_sig(SIGSEGV, tsk, 1);
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ /* info.si_code set above to make clear whether
+ this was a SEGV_MAPERR or SEGV_ACCERR fault. */
+ info.si_addr = (void *)address;
+ info.si_trapno = 0;
+ force_sig_info (SIGSEGV, &info, tsk);
return;
do_sigbus:
up(&mm->mmap_sem);
- tsk->thread.sig_address = address;
- tsk->thread.sig_desc = SUBSIG_MISCERROR;
- force_sig(SIGBUS, tsk);
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = BUS_ADRERR;
+ info.si_addr = (void *)address;
+ info.si_trapno = 0;
+ force_sig_info (SIGBUS, &info, tsk);
}
void window_overflow_fault(void)
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
index 817861a19..3fc96ef14 100644
--- a/arch/sparc/mm/init.c
+++ b/arch/sparc/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.73 2000/01/15 00:51:26 anton Exp $
+/* $Id: init.c,v 1.78 2000/01/24 03:22:38 anton Exp $
* linux/arch/sparc/mm/init.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -45,9 +45,9 @@ unsigned long sparc_unmapped_base;
struct pgtable_cache_struct pgt_quicklists;
/* References to section boundaries */
-extern char __init_begin, __init_end, _start, _end, etext , edata;
+extern char __init_begin, __init_end, _start, end, etext , edata;
-static unsigned long totalram_pages = 0;
+unsigned long totalram_pages = 0;
/*
* BAD_PAGE is the page that is used for page faults when linux
@@ -165,7 +165,7 @@ unsigned long __init bootmem_init(void)
/* Start with page aligned address of last symbol in kernel
* image.
*/
- start_pfn = (unsigned long)__pa(PAGE_ALIGN((unsigned long) &_end));
+ start_pfn = (unsigned long)__pa(PAGE_ALIGN((unsigned long) &end));
/* Adjust up to the physical address where the kernel begins. */
start_pfn += phys_base;
@@ -199,11 +199,11 @@ unsigned long __init bootmem_init(void)
#ifdef DEBUG_BOOTMEM
prom_printf("reserve_bootmem: base[%lx] size[%lx]\n",
phys_base,
- (((start_pfn << PAGE_SHIFT) +
- bootmap_size) - phys_base));
+ (start_pfn << PAGE_SHIFT) +
+ bootmap_size + PAGE_SIZE-1 - phys_base);
#endif
- reserve_bootmem(phys_base, (((start_pfn << PAGE_SHIFT) +
- bootmap_size) - phys_base));
+ reserve_bootmem(phys_base, (start_pfn << PAGE_SHIFT) +
+ bootmap_size + PAGE_SIZE-1 - phys_base);
#ifdef DEBUG_BOOTMEM
prom_printf("init_bootmem: return end_pfn[%lx]\n", end_pfn);
@@ -366,10 +366,12 @@ void __init mem_init(void)
int datapages = 0;
int initpages = 0;
int i;
+#ifdef CONFIG_BLK_DEV_INITRD
unsigned long addr, last;
+#endif
/* Saves us work later. */
- memset((void *) ZERO_PAGE(0), 0, PAGE_SIZE);
+ memset((void *)&empty_zero_page, 0, PAGE_SIZE);
i = last_valid_pfn >> (8 + 5);
i += 1;
@@ -386,7 +388,7 @@ void __init mem_init(void)
/* fix this */
#ifdef CONFIG_BLK_DEV_INITRD
addr = __va(phys_base);
- last = PAGE_ALIGN((unsigned long)&_end) + phys_base;
+ last = PAGE_ALIGN((unsigned long)&end) + phys_base;
while(addr < last) {
if (initrd_below_start_ok && addr >= initrd_start && addr < initrd_end)
mem_map[MAP_NR(addr)].flags &= ~(1<<PG_reserved);
@@ -455,6 +457,7 @@ void free_initmem (void)
totalram_pages++;
num_physpages++;
}
+ printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
}
void si_meminfo(struct sysinfo *val)
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 77e9aa841..10990f3ea 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -1,4 +1,4 @@
-/* $Id: srmmu.c,v 1.203 2000/01/15 00:51:28 anton Exp $
+/* $Id: srmmu.c,v 1.205 2000/01/21 17:59:46 anton Exp $
* srmmu.c: SRMMU specific routines for memory management.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1204,8 +1204,12 @@ static inline void map_kernel(void)
{
int i;
+ if (phys_base > 0) {
+ do_large_mapping(PAGE_OFFSET, phys_base);
+ }
+
for (i = 0; sp_banks[i].num_bytes != 0; i++) {
- map_spbank(__va(sp_banks[i].base_addr), i);
+ map_spbank((unsigned long)__va(sp_banks[i].base_addr), i);
}
init_mm.mmap->vm_start = PAGE_OFFSET;
@@ -1255,7 +1259,7 @@ void __init srmmu_paging_init(void)
last_valid_pfn = end_pfn = bootmem_init();
- srmmu_allocate_ptable_skeleton(KERNBASE, __va(end_of_phys_memory));
+ srmmu_allocate_ptable_skeleton(KERNBASE, (unsigned long)__va(end_of_phys_memory));
#if CONFIG_SUN_IO
srmmu_allocate_ptable_skeleton(sparc_iomap.start, IOBASE_END);
srmmu_allocate_ptable_skeleton(DVMA_VADDR, DVMA_END);
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in
index 448dad773..ace1366ba 100644
--- a/arch/sparc64/config.in
+++ b/arch/sparc64/config.in
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.86 1999/12/23 01:46:09 davem Exp $
+# $Id: config.in,v 1.87 2000/01/16 06:18:53 davem Exp $
# For a description of the syntax of this configuration file,
# see the Configure script.
#
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
index cbbb3557b..009c506a0 100644
--- a/arch/sparc64/kernel/binfmt_aout32.c
+++ b/arch/sparc64/kernel/binfmt_aout32.c
@@ -30,16 +30,16 @@
#include <asm/system.h>
#include <asm/uaccess.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
static int load_aout32_binary(struct linux_binprm *, struct pt_regs * regs);
static int load_aout32_library(int fd);
-static int aout32_core_dump(long signr, struct pt_regs * regs);
+static int aout32_core_dump(long signr, struct pt_regs * regs, struct file *file);
extern void dump_thread(struct pt_regs *, struct user *);
static struct linux_binfmt aout32_format = {
- NULL, NULL, load_aout32_binary, load_aout32_library, aout32_core_dump,
+ NULL, THIS_MODULE, load_aout32_binary, load_aout32_library, aout32_core_dump,
PAGE_SIZE
};
@@ -214,7 +214,6 @@ static inline int do_load_aout32_binary(struct linux_binprm * bprm,
struct file * file;
int fd;
unsigned long error;
- unsigned long p = bprm->p;
unsigned long fd_offset;
unsigned long rlim;
int retval;
@@ -275,9 +274,13 @@ static inline int do_load_aout32_binary(struct linux_binprm * bprm,
read_exec(bprm->dentry, fd_offset, (char *) N_TXTADDR(ex),
ex.a_text+ex.a_data, 0);
} else {
+ static unsigned long error_time;
if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
- (N_MAGIC(ex) != NMAGIC))
+ (N_MAGIC(ex) != NMAGIC) && (jiffies-error_time) > 5*HZ)
+ {
printk(KERN_NOTICE "executable not page aligned\n");
+ error_time = jiffies;
+ }
fd = open_dentry(bprm->dentry, O_RDONLY);
if (fd < 0)
@@ -285,7 +288,7 @@ static inline int do_load_aout32_binary(struct linux_binprm * bprm,
file = fget(fd);
if (!file->f_op || !file->f_op->mmap) {
- fput(fd);
+ fput(file);
sys_close(fd);
do_brk(0, ex.a_text+ex.a_data);
read_exec(bprm->dentry, fd_offset,
@@ -452,8 +455,17 @@ load_aout32_library(int fd)
return retval;
}
-
-int __init init_aout32_binfmt(void)
+static int __init init_aout32_binfmt(void)
{
return register_binfmt(&aout32_format);
}
+
+static void __exit exit_aout32_binfmt(void)
+{
+ unregister_binfmt(&aout32_format);
+}
+
+EXPORT_NO_SYMBOLS;
+
+module_init(init_aout32_binfmt);
+module_exit(exit_aout32_binfmt);
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
index cba5cfac3..7a7315003 100644
--- a/arch/sparc64/kernel/ioctl32.c
+++ b/arch/sparc64/kernel/ioctl32.c
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.73 2000/01/11 01:06:47 davem Exp $
+/* $Id: ioctl32.c,v 1.74 2000/01/15 04:47:48 davem Exp $
* ioctl32.c: Conversion between 32bit and 64bit native ioctls.
*
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -39,6 +39,7 @@
#include <linux/videodev.h>
#include <linux/netdevice.h>
#include <linux/raw.h>
+#include <linux/smb_fs.h>
#include <scsi/scsi.h>
/* Ugly hack. */
@@ -1734,6 +1735,24 @@ static int do_unimap_ioctl(struct file *file, int cmd, struct unimapdesc32 *user
return 0;
}
+static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ mm_segment_t old_fs = get_fs();
+ __kernel_uid_t kuid;
+ int err;
+
+ cmd = SMB_IOC_GETMOUNTUID;
+
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
+ set_fs(old_fs);
+
+ if (err >= 0)
+ err = put_user(kuid, (__kernel_uid_t32 *)arg);
+
+ return err;
+}
+
asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct file * filp;
@@ -1921,6 +1940,11 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
error = do_video_ioctl(fd, cmd, arg);
goto out;
+ /* One SMB ioctl needs translations. */
+ case _IOR('u', 1, __kernel_uid_t32): /* SMB_IOC_GETMOUNTUID */
+ error = do_smb_getmountuid(fd, cmd, arg);
+ goto out;
+
/* List here exlicitly which ioctl's are known to have
* compatable types passed or none at all...
*/
@@ -2427,6 +2451,9 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
case RAW_SETBIND:
case RAW_GETBIND:
+ /* SMB ioctls which do not need any translations */
+ case SMB_IOC_NEWCONN:
+
error = sys_ioctl (fd, cmd, arg);
goto out;
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index c537353e0..d1041b85f 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -59,7 +59,6 @@ int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg, int ne
{
struct scatterlist *sg = *__sg;
iopte_t *iopte = *__iopte;
- int retval = 0;
u32 dlen = dma_sg->dvma_length;
u32 daddr = dma_sg->dvma_address;
unsigned int sglen;
@@ -75,7 +74,7 @@ int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg, int ne
printk("verify_one_map: Wrong start offset "
"sg[%08lx] dma[%08x]\n",
sgaddr, daddr);
- retval = -nents;
+ nents = -1;
goto out;
}
@@ -85,7 +84,7 @@ int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg, int ne
printk("verify_one_map: IOPTE[%08lx] maps the "
"wrong page, should be [%08lx]\n",
iopte_val(*iopte), (sgaddr & PAGE_MASK) - PAGE_OFFSET);
- retval = -nents;
+ nents = -1;
goto out;
}
@@ -114,6 +113,8 @@ int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg, int ne
iopte++;
sg++;
+ if (--nents <= 0)
+ break;
sgaddr = (unsigned long) sg->address;
sglen = sg->length;
}
@@ -121,7 +122,7 @@ int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg, int ne
/* Transfer overrun, big problems. */
printk("verify_one_map: Transfer overrun by %d bytes.\n",
-dlen);
- retval = -nents;
+ nents = -1;
} else {
/* Advance to next dma_sg implies that the next iopte will
* begin it.
@@ -132,7 +133,7 @@ int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg, int ne
out:
*__sg = sg;
*__iopte = iopte;
- return retval;
+ return nents;
}
int verify_maps(struct scatterlist *sg, int nents, iopte_t *iopte)
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index b70d936c3..820b93bb4 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.80 1999/12/06 03:14:48 davem Exp $
+/* $Id: irq.c,v 1.81 2000/01/21 06:33:59 davem Exp $
* irq.c: UltraSparc IRQ handling/init/registry.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -756,7 +756,7 @@ void handler_irq(int irq, struct pt_regs *regs)
* of our buddy.
*/
if(should_forward != 0) {
- buddy = cpu_number_map[cpu] + 1;
+ buddy = cpu_number_map(cpu) + 1;
if (buddy >= NR_CPUS ||
(buddy = cpu_logical_map(buddy)) == -1)
buddy = cpu_logical_map(0);
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index 12f7211d1..e72671428 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -2,7 +2,7 @@
* pci_iommu.c: UltraSparc PCI controller IOM/STC support.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
- * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com)
+ * Copyright (C) 1999, 2000 Jakub Jelinek (jakub@redhat.com)
*/
#include <linux/kernel.h>
@@ -63,7 +63,7 @@ static iopte_t *alloc_streaming_cluster(struct pci_iommu *iommu, unsigned long n
return iopte;
}
-static inline void free_streaming_cluster(struct pci_iommu *iommu, u32 base, unsigned long npages)
+static inline void free_streaming_cluster(struct pci_iommu *iommu, dma_addr_t base, unsigned long npages)
{
unsigned long cnum, ent;
@@ -76,8 +76,8 @@ static inline void free_streaming_cluster(struct pci_iommu *iommu, u32 base, uns
iommu->lowest_free[cnum] = ent;
}
-/* We allocate consistant mappings from the end of cluster zero. */
-static iopte_t *alloc_consistant_cluster(struct pci_iommu *iommu, unsigned long npages)
+/* We allocate consistent mappings from the end of cluster zero. */
+static iopte_t *alloc_consistent_cluster(struct pci_iommu *iommu, unsigned long npages)
{
iopte_t *iopte;
@@ -109,11 +109,11 @@ static iopte_t *alloc_consistant_cluster(struct pci_iommu *iommu, unsigned long
#define IOPTE_INVALID 0UL
-/* Allocate and map kernel buffer of size SIZE using consistant mode
+/* Allocate and map kernel buffer of size SIZE using consistent mode
* DMA for PCI device PDEV. Return non-NULL cpu-side address if
* successful and set *DMA_ADDRP to the PCI side dma address.
*/
-void *pci_alloc_consistant(struct pci_dev *pdev, long size, u32 *dma_addrp)
+void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
{
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
@@ -122,10 +122,6 @@ void *pci_alloc_consistant(struct pci_dev *pdev, long size, u32 *dma_addrp)
void *ret;
int npages;
- if (size <= 0 || pdev == NULL ||
- pdev->sysdata == NULL || dma_addrp == NULL)
- return NULL;
-
size = PAGE_ALIGN(size);
for (order = 0; order < 10; order++) {
if ((PAGE_SIZE << order) >= size)
@@ -134,6 +130,11 @@ void *pci_alloc_consistant(struct pci_dev *pdev, long size, u32 *dma_addrp)
if (order == 10)
return NULL;
+ /* We still don't support devices which don't recognize at least 30 bits
+ of bus address. Bug me to code it (is pretty easy actually). -jj */
+ if ((pdev->dma_mask & 0x3fffffff) != 0x3fffffff)
+ BUG();
+
first_page = __get_free_pages(GFP_ATOMIC, order);
if (first_page == 0UL)
return NULL;
@@ -143,7 +144,7 @@ void *pci_alloc_consistant(struct pci_dev *pdev, long size, u32 *dma_addrp)
iommu = &pcp->pbm->parent->iommu;
spin_lock_irqsave(&iommu->lock, flags);
- iopte = alloc_consistant_cluster(iommu, size >> PAGE_SHIFT);
+ iopte = alloc_consistent_cluster(iommu, size >> PAGE_SHIFT);
if (iopte == NULL) {
spin_unlock_irqrestore(&iommu->lock, flags);
free_pages(first_page, order);
@@ -182,18 +183,14 @@ void *pci_alloc_consistant(struct pci_dev *pdev, long size, u32 *dma_addrp)
return ret;
}
-/* Free and unmap a consistant DMA translation. */
-void pci_free_consistant(struct pci_dev *pdev, long size, void *cpu, u32 dvma)
+/* Free and unmap a consistent DMA translation. */
+void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_t dvma)
{
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
iopte_t *iopte;
unsigned long flags, order, npages, i;
- if (size <= 0 || pdev == NULL ||
- pdev->sysdata == NULL || cpu == NULL)
- return;
-
npages = PAGE_ALIGN(size) >> PAGE_SHIFT;
pcp = pdev->sysdata;
iommu = &pcp->pbm->parent->iommu;
@@ -202,7 +199,7 @@ void pci_free_consistant(struct pci_dev *pdev, long size, void *cpu, u32 dvma)
spin_lock_irqsave(&iommu->lock, flags);
- /* Data for consistant mappings cannot enter the streaming
+ /* Data for consistent mappings cannot enter the streaming
* buffers, so we only need to update the TSB. Flush of the
* IOTLB is done later when these ioptes are used for a new
* allocation.
@@ -224,16 +221,25 @@ void pci_free_consistant(struct pci_dev *pdev, long size, void *cpu, u32 dvma)
/* Map a single buffer at PTR of SZ bytes for PCI DMA
* in streaming mode.
*/
-u32 pci_map_single(struct pci_dev *pdev, void *ptr, long sz)
+dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz)
{
- struct pcidev_cookie *pcp = pdev->sysdata;
- struct pci_iommu *iommu = &pcp->pbm->parent->iommu;
- struct pci_strbuf *strbuf = &pcp->pbm->stc;
+ struct pcidev_cookie *pcp;
+ struct pci_iommu *iommu;
+ struct pci_strbuf *strbuf;
iopte_t *base;
unsigned long flags, npages, oaddr;
unsigned long i, base_paddr, ctx;
u32 bus_addr, ret;
+ pcp = pdev->sysdata;
+ iommu = &pcp->pbm->parent->iommu;
+ strbuf = &pcp->pbm->stc;
+
+ /* We still don't support devices which don't recognize at least 30 bits
+ of bus address. Bug me to code it (is pretty easy actually). -jj */
+ if ((pdev->dma_mask & 0x3fffffff) != 0x3fffffff)
+ BUG();
+
oaddr = (unsigned long)ptr;
npages = PAGE_ALIGN(oaddr + sz) - (oaddr & PAGE_MASK);
npages >>= PAGE_SHIFT;
@@ -270,18 +276,26 @@ u32 pci_map_single(struct pci_dev *pdev, void *ptr, long sz)
}
/* Unmap a single streaming mode DMA translation. */
-void pci_unmap_single(struct pci_dev *pdev, u32 bus_addr, long sz)
+void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz)
{
- struct pcidev_cookie *pcp = pdev->sysdata;
- struct pci_iommu *iommu = &pcp->pbm->parent->iommu;
- struct pci_strbuf *strbuf = &pcp->pbm->stc;
+ struct pcidev_cookie *pcp;
+ struct pci_iommu *iommu;
+ struct pci_strbuf *strbuf;
iopte_t *base;
unsigned long flags, npages, i, ctx;
+ pcp = pdev->sysdata;
+ iommu = &pcp->pbm->parent->iommu;
+ strbuf = &pcp->pbm->stc;
+
npages = PAGE_ALIGN(bus_addr + sz) - (bus_addr & PAGE_MASK);
npages >>= PAGE_SHIFT;
base = iommu->page_table +
((bus_addr - iommu->page_table_map_base) >> PAGE_SHIFT);
+#ifdef DEBUG_PCI_IOMMU
+ if (iopte_val(*base) == IOPTE_INVALID)
+ printk("pci_unmap_single called on non-mapped region %08x,%08x from %016lx\n", bus_addr, sz, __builtin_return_address(0));
+#endif
bus_addr &= PAGE_MASK;
spin_lock_irqsave(&iommu->lock, flags);
@@ -327,11 +341,12 @@ void pci_unmap_single(struct pci_dev *pdev, u32 bus_addr, long sz)
spin_unlock_irqrestore(&iommu->lock, flags);
}
-static inline struct scatterlist *fill_sg(iopte_t *iopte, struct scatterlist *sg, int nents, unsigned long ctx, int streaming)
+static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, unsigned long ctx, int streaming)
{
struct scatterlist *dma_sg = sg;
+ int i;
- do {
+ for (i = 0; i < nused; i++) {
unsigned long pteval = ~0UL;
u32 dma_npages;
@@ -396,8 +411,7 @@ static inline struct scatterlist *fill_sg(iopte_t *iopte, struct scatterlist *sg
pteval = ~0UL;
} while (dma_npages != 0);
dma_sg++;
- } while (dma_sg->dvma_length != 0);
- return dma_sg;
+ }
}
/* Map a set of buffers described by SGLIST with NELEMS array
@@ -414,7 +428,7 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems)
iopte_t *base;
u32 dma_base;
struct scatterlist *sgtmp;
- int tmp;
+ int used;
/* Fast path single entry scatterlists. */
if (nelems == 1) {
@@ -422,11 +436,16 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems)
sglist->dvma_length = sglist->length;
return 1;
}
-
+
pcp = pdev->sysdata;
iommu = &pcp->pbm->parent->iommu;
strbuf = &pcp->pbm->stc;
+ /* We still don't support devices which don't recognize at least 30 bits
+ of bus address. Bug me to code it (is pretty easy actually). -jj */
+ if ((pdev->dma_mask & 0x3fffffff) != 0x3fffffff)
+ BUG();
+
/* Step 1: Prepare scatter list. */
npages = prepare_sg(sglist, nelems);
@@ -439,13 +458,15 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems)
dma_base = iommu->page_table_map_base + ((base - iommu->page_table) << PAGE_SHIFT);
/* Step 3: Normalize DMA addresses. */
- tmp = nelems;
+ used = nelems;
sgtmp = sglist;
- while (tmp-- && sgtmp->dvma_length) {
+ while (used && sgtmp->dvma_length) {
sgtmp->dvma_address += dma_base;
sgtmp++;
+ used--;
}
+ used = nelems - used;
/* Step 4: Choose a context if necessary. */
ctx = 0;
@@ -453,7 +474,7 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems)
ctx = iommu->iommu_cur_ctx++;
/* Step 5: Create the mappings. */
- sgtmp = fill_sg (base, sglist, nelems, ctx, strbuf->strbuf_enabled);
+ fill_sg (base, sglist, used, ctx, strbuf->strbuf_enabled);
#ifdef VERIFY_SG
verify_sglist(sglist, nelems, base, npages);
#endif
@@ -468,33 +489,39 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems)
spin_unlock_irqrestore(&iommu->lock, flags);
- return sgtmp - sglist;
+ return used;
}
/* Unmap a set of streaming mode DMA translations. */
void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems)
{
- struct pcidev_cookie *pcp = pdev->sysdata;
- struct pci_iommu *iommu = &pcp->pbm->parent->iommu;
- struct pci_strbuf *strbuf = &pcp->pbm->stc;
+ struct pcidev_cookie *pcp;
+ struct pci_iommu *iommu;
+ struct pci_strbuf *strbuf;
iopte_t *base;
unsigned long flags, ctx, i, npages;
u32 bus_addr;
+
+ pcp = pdev->sysdata;
+ iommu = &pcp->pbm->parent->iommu;
+ strbuf = &pcp->pbm->stc;
bus_addr = sglist->dvma_address & PAGE_MASK;
- i = 0;
- if (nelems > 1) {
- for (; i < nelems; i++)
- if (sglist[i].dvma_length == 0)
- break;
- i--;
- }
+ for (i = 1; i < nelems; i++)
+ if (sglist[i].dvma_length == 0)
+ break;
+ i--;
npages = (PAGE_ALIGN(sglist[i].dvma_address + sglist[i].dvma_length) - bus_addr) >> PAGE_SHIFT;
base = iommu->page_table +
((bus_addr - iommu->page_table_map_base) >> PAGE_SHIFT);
+#ifdef DEBUG_PCI_IOMMU
+ if (iopte_val(*base) == IOPTE_INVALID)
+ printk("pci_unmap_sg called on non-mapped region %08x,%d from %016lx\n", sglist->dvma_address, nelems, __builtin_return_address(0));
+#endif
+
spin_lock_irqsave(&iommu->lock, flags);
/* Step 1: Kick data out of streaming buffers if necessary. */
@@ -538,16 +565,20 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems)
spin_unlock_irqrestore(&iommu->lock, flags);
}
-/* Make physical memory consistant for a single
+/* Make physical memory consistent for a single
* streaming mode DMA translation after a transfer.
*/
-void pci_dma_sync_single(struct pci_dev *pdev, u32 bus_addr, long sz)
+void pci_dma_sync_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz)
{
- struct pcidev_cookie *pcp = pdev->sysdata;
- struct pci_iommu *iommu = &pcp->pbm->parent->iommu;
- struct pci_strbuf *strbuf = &pcp->pbm->stc;
+ struct pcidev_cookie *pcp;
+ struct pci_iommu *iommu;
+ struct pci_strbuf *strbuf;
unsigned long flags, ctx, npages;
+ pcp = pdev->sysdata;
+ iommu = &pcp->pbm->parent->iommu;
+ strbuf = &pcp->pbm->stc;
+
if (!strbuf->strbuf_enabled)
return;
@@ -595,16 +626,20 @@ void pci_dma_sync_single(struct pci_dev *pdev, u32 bus_addr, long sz)
spin_unlock_irqrestore(&iommu->lock, flags);
}
-/* Make physical memory consistant for a set of streaming
+/* Make physical memory consistent for a set of streaming
* mode DMA translations after a transfer.
*/
void pci_dma_sync_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems)
{
- struct pcidev_cookie *pcp = pdev->sysdata;
- struct pci_iommu *iommu = &pcp->pbm->parent->iommu;
- struct pci_strbuf *strbuf = &pcp->pbm->stc;
+ struct pcidev_cookie *pcp;
+ struct pci_iommu *iommu;
+ struct pci_strbuf *strbuf;
unsigned long flags, ctx;
+ pcp = pdev->sysdata;
+ iommu = &pcp->pbm->parent->iommu;
+ strbuf = &pcp->pbm->stc;
+
if (!strbuf->strbuf_enabled)
return;
@@ -636,15 +671,12 @@ void pci_dma_sync_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelem
unsigned long i, npages;
u32 bus_addr;
- i = 0;
bus_addr = sglist[0].dvma_address & PAGE_MASK;
- if (nelems > 1) {
- for(; i < nelems; i++)
- if (!sglist[i].dvma_length)
- break;
- i--;
- }
+ for(i = 1; i < nelems; i++)
+ if (!sglist[i].dvma_length)
+ break;
+ i--;
npages = (PAGE_ALIGN(sglist[i].dvma_address + sglist[i].dvma_length) - bus_addr) >> PAGE_SHIFT;
for (i = 0; i < npages; i++, bus_addr += PAGE_SIZE)
pci_iommu_write(strbuf->strbuf_pflush, bus_addr);
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index c12b5182d..559769b87 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -1284,6 +1284,10 @@ static void __init psycho_iommu_init(struct pci_controller_info *p)
memset((char *)tsbbase, 0, PAGE_SIZE << 7);
#endif
+ /* Make sure DMA address 0 is never returned just to allow catching
+ of buggy drivers. */
+ p->iommu.lowest_free[0] = 1;
+
#ifndef NEW_PCI_DMA_MAP
iopte = (iopte_t *)tsbbase;
/* Initialize to "none" settings. */
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 7409b3164..2f82de9ce 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -1150,6 +1150,10 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
p->iommu.page_table_map_base = dvma_offset;
memset((char *)tsbbase, 0, PAGE_SIZE << order);
+ /* Make sure DMA address 0 is never returned just to allow catching
+ of buggy drivers. */
+ p->iommu.lowest_free[0] = 1;
+
#ifndef NEW_PCI_DMA_MAP
iopte = (iopte_t *)tsbbase;
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 922e74d2e..503f5b875 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.102 1999/12/15 22:24:49 davem Exp $
+/* $Id: process.c,v 1.103 2000/01/21 11:38:53 jj Exp $
* arch/sparc64/kernel/process.c
*
* Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -364,8 +364,6 @@ void show_thread(struct thread_struct *thread)
printk("kregs: 0x%016lx\n", (unsigned long)thread->kregs);
show_regs(thread->kregs);
#endif
- printk("sig_address: 0x%016lx\n", thread->sig_address);
- printk("sig_desc: 0x%016lx\n", thread->sig_desc);
printk("ksp: 0x%016lx\n", thread->ksp);
if (thread->w_saved) {
@@ -701,7 +699,6 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
memcpy(&dump->fpu.fpstatus.fregs.regs[0], &current->thread.float_regs[0], (sizeof(unsigned long) * 32));
dump->fpu.fpstatus.fsr = current->thread.fsr;
dump->fpu.fpstatus.flags = dump->fpu.fpstatus.extra = 0;
- dump->sigcode = current->thread.sig_desc;
#endif
}
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index 9e24c7bb3..a73387754 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -212,8 +212,8 @@ static void free_streaming_cluster(struct sbus_iommu *iommu, u32 base, unsigned
iommu->lowest_free[cnum] = ent;
}
-/* We allocate consistant mappings from the end of cluster zero. */
-static iopte_t *alloc_consistant_cluster(struct sbus_iommu *iommu, unsigned long npages)
+/* We allocate consistent mappings from the end of cluster zero. */
+static iopte_t *alloc_consistent_cluster(struct sbus_iommu *iommu, unsigned long npages)
{
iopte_t *iopte;
@@ -235,7 +235,7 @@ static iopte_t *alloc_consistant_cluster(struct sbus_iommu *iommu, unsigned long
return NULL;
}
-static void free_consistant_cluster(struct sbus_iommu *iommu, u32 base, unsigned long npages)
+static void free_consistent_cluster(struct sbus_iommu *iommu, u32 base, unsigned long npages)
{
iopte_t *iopte = iommu->page_table + ((base - MAP_BASE) >> PAGE_SHIFT);
@@ -243,7 +243,7 @@ static void free_consistant_cluster(struct sbus_iommu *iommu, u32 base, unsigned
*iopte++ = __iopte(0UL);
}
-void *sbus_alloc_consistant(struct sbus_dev *sdev, long size, u32 *dvma_addr)
+void *sbus_alloc_consistent(struct sbus_dev *sdev, size_t size, dma_addr_t *dvma_addr)
{
unsigned long order, first_page, flags;
struct sbus_iommu *iommu;
@@ -269,7 +269,7 @@ void *sbus_alloc_consistant(struct sbus_dev *sdev, long size, u32 *dvma_addr)
iommu = sdev->bus->iommu;
spin_lock_irqsave(&iommu->lock, flags);
- iopte = alloc_consistant_cluster(iommu, size >> PAGE_SHIFT);
+ iopte = alloc_consistent_cluster(iommu, size >> PAGE_SHIFT);
if (iopte == NULL) {
spin_unlock_irqrestore(&iommu->lock, flags);
free_pages(first_page, order);
@@ -291,7 +291,7 @@ void *sbus_alloc_consistant(struct sbus_dev *sdev, long size, u32 *dvma_addr)
return ret;
}
-void sbus_free_consistant(struct sbus_dev *sdev, long size, void *cpu, u32 dvma)
+void sbus_free_consistent(struct sbus_dev *sdev, size_t size, void *cpu, dma_addr_t dvma)
{
unsigned long order, npages;
struct sbus_iommu *iommu;
@@ -303,7 +303,7 @@ void sbus_free_consistant(struct sbus_dev *sdev, long size, void *cpu, u32 dvma)
iommu = sdev->bus->iommu;
spin_lock_irq(&iommu->lock);
- free_consistant_cluster(iommu, dvma, npages);
+ free_consistent_cluster(iommu, dvma, npages);
spin_unlock_irq(&iommu->lock);
for (order = 0; order < 10; order++) {
@@ -314,7 +314,7 @@ void sbus_free_consistant(struct sbus_dev *sdev, long size, void *cpu, u32 dvma)
free_pages((unsigned long)cpu, order);
}
-u32 sbus_map_single(struct sbus_dev *sdev, void *ptr, long size)
+dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t size)
{
struct sbus_iommu *iommu = sdev->bus->iommu;
unsigned long npages, phys_base, flags;
@@ -344,7 +344,7 @@ u32 sbus_map_single(struct sbus_dev *sdev, void *ptr, long size)
return (dma_base | offset);
}
-void sbus_unmap_single(struct sbus_dev *sdev, u32 dma_addr, long size)
+void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size)
{
struct sbus_iommu *iommu = sdev->bus->iommu;
u32 dma_base = dma_addr & PAGE_MASK;
@@ -358,11 +358,12 @@ void sbus_unmap_single(struct sbus_dev *sdev, u32 dma_addr, long size)
spin_unlock_irqrestore(&iommu->lock, flags);
}
-static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nents)
+static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused)
{
struct scatterlist *dma_sg = sg;
+ int i;
- do {
+ for (i = 0; i < nused; i++) {
unsigned long pteval = ~0UL;
u32 dma_npages;
@@ -426,7 +427,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nents)
pteval = ~0UL;
} while (dma_npages != 0);
dma_sg++;
- } while (dma_sg->dvma_length != 0);
+ }
}
int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents)
@@ -436,7 +437,7 @@ int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents)
iopte_t *iopte;
u32 dma_base;
struct scatterlist *sgtmp;
- int unused;
+ int used;
/* Fast path single entry scatterlists. */
if (nents == 1) {
@@ -453,22 +454,23 @@ int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents)
/* Normalize DVMA addresses. */
sgtmp = sg;
- unused = nents;
+ used = nents;
- while (unused && sgtmp->dvma_length) {
+ while (used && sgtmp->dvma_length) {
sgtmp->dvma_address += dma_base;
sgtmp++;
- unused--;
+ used--;
}
+ used = nents - used;
- fill_sg(iopte, sg, nents);
+ fill_sg(iopte, sg, used);
#ifdef VERIFY_SG
verify_sglist(sg, nents, iopte, npages);
#endif
iommu_flush(iommu, dma_base, npages);
spin_unlock_irqrestore(&iommu->lock, flags);
- return nents - unused;
+ return used;
}
void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents)
@@ -499,7 +501,7 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents)
spin_unlock_irqrestore(&iommu->lock, flags);
}
-void sbus_dma_sync_single(struct sbus_dev *sdev, u32 base, long size)
+void sbus_dma_sync_single(struct sbus_dev *sdev, dma_addr_t base, size_t size)
{
struct sbus_iommu *iommu = sdev->bus->iommu;
unsigned long flags;
@@ -1054,6 +1056,10 @@ void __init sbus_iommu_init(int prom_node, struct sbus_bus *sbus)
memset(iommu, 0, sizeof(*iommu));
+ /* Make sure DMA address 0 is never returned just to allow catching
+ of buggy drivers. */
+ iommu->lowest_free[0] = 1;
+
/* Setup spinlock. */
spin_lock_init(&iommu->lock);
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index f0e512666..f226a8ae5 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -1,4 +1,4 @@
-/* $Id: signal32.c,v 1.58 2000/01/14 09:40:08 jj Exp $
+/* $Id: signal32.c,v 1.59 2000/01/21 11:38:52 jj Exp $
* arch/sparc64/kernel/signal32.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -101,6 +101,44 @@ struct rt_signal_frame32 {
#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame32) + 7) & (~7)))
#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 7) & (~7)))
+int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from)
+{
+ int err;
+
+ if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
+ return -EFAULT;
+
+ err = __put_user(from->si_signo, &to->si_signo);
+ err |= __put_user(from->si_errno, &to->si_errno);
+ err |= __put_user(from->si_code, &to->si_code);
+ if (from->si_code < 0)
+ err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
+ else {
+ int signo = from->si_signo;
+ if (from->si_code == SI_USER || from->si_code == SI_KERNEL)
+ signo = SIGRTMIN;
+ switch (signo) {
+ case SIGCHLD:
+ err |= __put_user(from->si_utime, &to->si_utime);
+ err |= __put_user(from->si_stime, &to->si_stime);
+ err |= __put_user(from->si_status, &to->si_status);
+ default:
+ err |= __put_user(from->si_pid, &to->si_pid);
+ err |= __put_user(from->si_uid, &to->si_uid);
+ break;
+ case SIGSEGV:
+ case SIGILL:
+ case SIGFPE:
+ case SIGBUS:
+ case SIGEMT:
+ err |= __put_user(from->si_trapno, &to->si_trapno);
+ err |= __put_user((long)from->si_addr, &to->si_addr);
+ break;
+ }
+ }
+ return err;
+}
+
/*
* atomically swap in the new signal mask, and wait for a signal.
* This is really tricky on the Sparc, watch out...
@@ -436,13 +474,16 @@ static inline void *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
}
static void
-setup_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
- struct pt_regs *regs, int signr, sigset_t *oldset)
+setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info)
{
struct signal_sframe32 *sframep;
struct sigcontext32 *sc;
unsigned seta[_NSIG_WORDS32];
int err = 0;
+ void *sig_address;
+ int sig_code;
+ unsigned long pc = regs->tpc;
+ unsigned long npc = regs->tnpc;
#if 0
int window = 0;
@@ -513,17 +554,61 @@ setup_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
current->thread.w_saved = 0; /* So process is allowed to execute. */
err |= __put_user(signr, &sframep->sig_num);
- if(signr == SIGSEGV ||
- signr == SIGILL ||
- signr == SIGFPE ||
- signr == SIGBUS ||
- signr == SIGEMT) {
- err |= __put_user(current->thread.sig_desc, &sframep->sig_code);
- err |= __put_user(current->thread.sig_address, &sframep->sig_address);
- } else {
- err |= __put_user(0, &sframep->sig_code);
- err |= __put_user(0, &sframep->sig_address);
+ sig_address = NULL;
+ sig_code = 0;
+ if (SI_FROMKERNEL (info) && (info->si_code & __SI_MASK) == __SI_FAULT) {
+ sig_address = info->si_addr;
+ switch (signr) {
+ case SIGSEGV:
+ switch (info->si_code) {
+ case SEGV_MAPERR: sig_code = SUBSIG_NOMAPPING; break;
+ default: sig_code = SUBSIG_PROTECTION; break;
+ }
+ break;
+ case SIGILL:
+ switch (info->si_code) {
+ case ILL_ILLOPC: sig_code = SUBSIG_ILLINST; break;
+ case ILL_PRVOPC: sig_code = SUBSIG_PRIVINST; break;
+ case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP (info->si_trapno); break;
+ default: sig_code = SUBSIG_STACK; break;
+ }
+ break;
+ case SIGFPE:
+ switch (info->si_code) {
+ case FPE_INTDIV: sig_code = SUBSIG_IDIVZERO; break;
+ case FPE_INTOVF: sig_code = SUBSIG_FPINTOVFL; break;
+ case FPE_FLTDIV: sig_code = SUBSIG_FPDIVZERO; break;
+ case FPE_FLTOVF: sig_code = SUBSIG_FPOVFLOW; break;
+ case FPE_FLTUND: sig_code = SUBSIG_FPUNFLOW; break;
+ case FPE_FLTRES: sig_code = SUBSIG_FPINEXACT; break;
+ case FPE_FLTINV: sig_code = SUBSIG_FPOPERROR; break;
+ default: sig_code = SUBSIG_FPERROR; break;
+ }
+ break;
+ case SIGBUS:
+ switch (info->si_code) {
+ case BUS_ADRALN: sig_code = SUBSIG_ALIGNMENT; break;
+ case BUS_ADRERR: sig_code = SUBSIG_MISCERROR; break;
+ default: sig_code = SUBSIG_BUSTIMEOUT; break;
+ }
+ break;
+ case SIGEMT:
+ switch (info->si_code) {
+ case EMT_TAGOVF: sig_code = SUBSIG_TAG; break;
+ }
+ break;
+ case SIGSYS:
+ if (info->si_code == (__SI_FAULT|0x100)) {
+ /* See sys_sunos32.c */
+ sig_code = info->si_trapno;
+ break;
+ }
+ default:
+ sig_address = NULL;
+ }
}
+ err |= __put_user((long)sig_address, &sframep->sig_address);
+ err |= __put_user(sig_code, &sframep->sig_code);
err |= __put_user((u64)sc, &sframep->sig_scptr);
if (err)
goto sigsegv;
@@ -790,8 +875,7 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
/* Setup the signal information. Solaris expects a bunch of
* information to be passed to the signal handler, we don't provide
- * that much currently, should use those that David already
- * is providing with thread.sig_desc
+ * that much currently, should use siginfo.
*/
err |= __put_user(signr, &si->siginfo.signo);
err |= __put_user(SVR4_SINOINFO, &si->siginfo.code);
@@ -1034,61 +1118,8 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs
err |= __put_user(0, &sf->fpu_save);
}
- /* Update the siginfo structure. Is this good? */
- if (info->si_code == 0) {
- info->si_signo = signr;
- info->si_errno = 0;
-
- switch (signr) {
- case SIGSEGV:
- case SIGILL:
- case SIGFPE:
- case SIGBUS:
- case SIGEMT:
- info->si_code = current->thread.sig_desc;
- info->si_addr = (void *)current->thread.sig_address;
- info->si_trapno = 0;
- break;
- default:
- break;
- }
- }
-
- err = __put_user (info->si_signo, &sf->info.si_signo);
- err |= __put_user (info->si_errno, &sf->info.si_errno);
- err |= __put_user (info->si_code, &sf->info.si_code);
- if (info->si_code < 0)
- err |= __copy_to_user (sf->info._sifields._pad, info->_sifields._pad, SI_PAD_SIZE);
- else {
- i = info->si_signo;
- if (info->si_code == SI_USER)
- i = SIGRTMIN;
- switch (i) {
- case SIGPOLL:
- err |= __put_user (info->si_band, &sf->info.si_band);
- err |= __put_user (info->si_fd, &sf->info.si_fd);
- break;
- case SIGCHLD:
- err |= __put_user (info->si_pid, &sf->info.si_pid);
- err |= __put_user (info->si_uid, &sf->info.si_uid);
- err |= __put_user (info->si_status, &sf->info.si_status);
- err |= __put_user (info->si_utime, &sf->info.si_utime);
- err |= __put_user (info->si_stime, &sf->info.si_stime);
- break;
- case SIGSEGV:
- case SIGILL:
- case SIGFPE:
- case SIGBUS:
- case SIGEMT:
- err |= __put_user ((long)info->si_addr, &sf->info.si_addr);
- err |= __put_user (info->si_trapno, &sf->info.si_trapno);
- break;
- default:
- err |= __put_user (info->si_pid, &sf->info.si_pid);
- err |= __put_user (info->si_uid, &sf->info.si_uid);
- break;
- }
- }
+ /* Update the siginfo structure. */
+ err |= copy_siginfo_to_user32(&sf->info, info);
/* Setup sigaltstack */
err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
@@ -1174,7 +1205,7 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
else if (current->thread.flags & SPARC_FLAG_NEWSIGNALS)
new_setup_frame32(ka, regs, signr, oldset);
else
- setup_frame32(&ka->sa, regs->tpc, regs->tnpc, regs, signr, oldset);
+ setup_frame32(&ka->sa, regs, signr, oldset, info);
}
if(ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 2fa4945d8..6e8899435 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -38,7 +38,7 @@ extern unsigned prom_cpu_nodes[];
struct cpuinfo_sparc cpu_data[NR_CPUS] __attribute__ ((aligned (64)));
-volatile int cpu_number_map[NR_CPUS] __attribute__ ((aligned (64)));
+volatile int __cpu_number_map[NR_CPUS] __attribute__ ((aligned (64)));
volatile int __cpu_logical_map[NR_CPUS] __attribute__ ((aligned (64)));
/* Please don't make this stuff initdata!!! --DaveM */
@@ -243,7 +243,7 @@ void __init smp_boot_cpus(void)
udelay(100);
}
if(callin_flag) {
- cpu_number_map[i] = cpucount;
+ __cpu_number_map[i] = cpucount;
__cpu_logical_map[cpucount] = i;
prom_cpu_nodes[i] = linux_cpus[no].prom_node;
prom_printf("OK\n");
@@ -255,7 +255,7 @@ void __init smp_boot_cpus(void)
}
if(!callin_flag) {
cpu_present_map &= ~(1UL << i);
- cpu_number_map[i] = -1;
+ __cpu_number_map[i] = -1;
}
}
cpu_new_task = NULL;
@@ -697,10 +697,10 @@ void __init smp_tick_init(void)
for(i = 0; i < linux_num_cpus; i++)
cpu_present_map |= (1UL << linux_cpus[i].mid);
for(i = 0; i < NR_CPUS; i++) {
- cpu_number_map[i] = -1;
+ __cpu_number_map[i] = -1;
__cpu_logical_map[i] = -1;
}
- cpu_number_map[boot_cpu_id] = 0;
+ __cpu_number_map[boot_cpu_id] = 0;
prom_cpu_nodes[boot_cpu_id] = linux_cpus[0].prom_node;
__cpu_logical_map[0] = boot_cpu_id;
current->processor = boot_cpu_id;
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index aa28151c8..418b2f7b2 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -185,8 +185,8 @@ EXPORT_SYMBOL(request_fast_irq);
EXPORT_SYMBOL(sbus_root);
EXPORT_SYMBOL(dma_chain);
EXPORT_SYMBOL(sbus_set_sbus64);
-EXPORT_SYMBOL(sbus_alloc_consistant);
-EXPORT_SYMBOL(sbus_free_consistant);
+EXPORT_SYMBOL(sbus_alloc_consistent);
+EXPORT_SYMBOL(sbus_free_consistent);
EXPORT_SYMBOL(sbus_map_single);
EXPORT_SYMBOL(sbus_unmap_single);
EXPORT_SYMBOL(sbus_map_sg);
@@ -209,6 +209,16 @@ EXPORT_SYMBOL(insb);
EXPORT_SYMBOL(insw);
EXPORT_SYMBOL(insl);
#endif
+#ifdef NEW_PCI_DMA_MAP
+EXPORT_SYMBOL(pci_alloc_consistent);
+EXPORT_SYMBOL(pci_free_consistent);
+EXPORT_SYMBOL(pci_map_single);
+EXPORT_SYMBOL(pci_unmap_single);
+EXPORT_SYMBOL(pci_map_sg);
+EXPORT_SYMBOL(pci_unmap_sg);
+EXPORT_SYMBOL(pci_dma_sync_single);
+EXPORT_SYMBOL(pci_dma_sync_sg);
+#endif
/* Solaris/SunOS binary compatibility */
EXPORT_SYMBOL(_sigpause_common);
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index af4743ec1..3c3a5c1c6 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.33 2000/01/11 17:33:25 jj Exp $
+/* $Id: sys_sparc.c,v 1.34 2000/01/21 11:39:06 jj Exp $
* linux/arch/sparc64/kernel/sys_sparc.c
*
* This file contains various random system calls that
@@ -223,11 +223,18 @@ c_sys_nis_syscall (struct pt_regs *regs)
asmlinkage void
sparc_breakpoint (struct pt_regs *regs)
{
+ siginfo_t info;
+
lock_kernel();
#ifdef DEBUG_SPARC_BREAKPOINT
printk ("TRAP: Entering kernel PC=%lx, nPC=%lx\n", regs->tpc, regs->tnpc);
#endif
- force_sig(SIGTRAP, current);
+ info.si_signo = SIGTRAP;
+ info.si_errno = 0;
+ info.si_code = TRAP_BRKPT;
+ info.si_addr = (void *)regs->tpc;
+ info.si_trapno = 0;
+ force_sig_info(SIGTRAP, &info, current);
#ifdef DEBUG_SPARC_BREAKPOINT
printk ("TRAP: Returning to space: PC=%lx nPC=%lx\n", regs->tpc, regs->tnpc);
#endif
@@ -241,7 +248,7 @@ asmlinkage int sys_getdomainname(char *name, int len)
int nlen;
int err = -EFAULT;
- down(&uts_sem);
+ down_read(&uts_sem);
nlen = strlen(system_utsname.domainname) + 1;
@@ -253,7 +260,7 @@ asmlinkage int sys_getdomainname(char *name, int len)
goto done;
err = 0;
done:
- up(&uts_sem);
+ up_read(&uts_sem);
return err;
}
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 408368060..61b9a3397 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.130 2000/01/14 09:40:07 jj Exp $
+/* $Id: sys_sparc32.c,v 1.131 2000/01/21 11:38:54 jj Exp $
* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -2082,7 +2082,7 @@ sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
sigset_t s;
sigset_t32 s32;
struct timespec t;
- int ret, err, i;
+ int ret;
mm_segment_t old_fs = get_fs();
siginfo_t info;
@@ -2104,42 +2104,8 @@ sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize);
set_fs (old_fs);
if (ret >= 0 && uinfo) {
- err = put_user (info.si_signo, &uinfo->si_signo);
- err |= __put_user (info.si_errno, &uinfo->si_errno);
- err |= __put_user (info.si_code, &uinfo->si_code);
- if (info.si_code < 0)
- err |= __copy_to_user (uinfo->_sifields._pad, info._sifields._pad, SI_PAD_SIZE);
- else {
- i = info.si_signo;
- if (info.si_code == SI_USER)
- i = SIGRTMIN;
- switch (i) {
- case SIGPOLL:
- err |= __put_user (info.si_band, &uinfo->si_band);
- err |= __put_user (info.si_fd, &uinfo->si_fd);
- break;
- case SIGCHLD:
- err |= __put_user (info.si_pid, &uinfo->si_pid);
- err |= __put_user (info.si_uid, &uinfo->si_uid);
- err |= __put_user (info.si_status, &uinfo->si_status);
- err |= __put_user (info.si_utime, &uinfo->si_utime);
- err |= __put_user (info.si_stime, &uinfo->si_stime);
- break;
- case SIGSEGV:
- case SIGILL:
- case SIGFPE:
- case SIGBUS:
- case SIGEMT:
- err |= __put_user ((long)info.si_addr, &uinfo->si_addr);
- err |= __put_user (info.si_trapno, &uinfo->si_trapno);
- break;
- default:
- err |= __put_user (info.si_pid, &uinfo->si_pid);
- err |= __put_user (info.si_uid, &uinfo->si_uid);
- break;
- }
- }
- if (err)
+ extern int copy_siginfo_to_user32(siginfo_t32 *, siginfo_t *);
+ if (copy_siginfo_to_user32(uinfo, &info))
ret = -EFAULT;
}
return ret;
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index ffc72b74d..6beb0531f 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos32.c,v 1.35 2000/01/06 23:51:50 davem Exp $
+/* $Id: sys_sunos32.c,v 1.37 2000/01/21 11:39:03 jj Exp $
* sys_sunos32.c: SunOS binary compatability layer on sparc64.
*
* Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -323,6 +323,7 @@ asmlinkage u32 sunos_sigblock(u32 blk_mask)
spin_lock_irq(&current->sigmask_lock);
old = (u32) current->blocked.sig[0];
current->blocked.sig[0] |= (blk_mask & _BLOCKABLE);
+ recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
return old;
}
@@ -334,6 +335,7 @@ asmlinkage u32 sunos_sigsetmask(u32 newmask)
spin_lock_irq(&current->sigmask_lock);
retval = (u32) current->blocked.sig[0];
current->blocked.sig[0] = (newmask & _BLOCKABLE);
+ recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
return retval;
}
@@ -541,29 +543,36 @@ asmlinkage int sunos_uname(struct sunos_utsname *name)
{
int ret;
- down(&uts_sem);
+ down_read(&uts_sem);
ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1);
ret |= copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1);
ret |= put_user('\0', &name->nname[8]);
ret |= copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1);
ret |= copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1);
ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1);
- up(&uts_sem);
+ up_read(&uts_sem);
return ret;
}
asmlinkage int sunos_nosys(void)
{
struct pt_regs *regs;
+ siginfo_t info;
+ static int cnt;
lock_kernel();
regs = current->thread.kregs;
- current->thread.sig_address = regs->tpc;
- current->thread.sig_desc = regs->u_regs[UREG_G1];
- send_sig(SIGSYS, current, 1);
- printk("Process makes ni_syscall number %d, register dump:\n",
- (int) regs->u_regs[UREG_G1]);
- show_regs(regs);
+ info.si_signo = SIGSYS;
+ info.si_errno = 0;
+ info.si_code = __SI_FAULT|0x100;
+ info.si_addr = (void *)regs->tpc;
+ info.si_trapno = regs->u_regs[UREG_G1];
+ send_sig_info(SIGSYS, &info, current);
+ if (cnt++ < 4) {
+ printk("Process makes ni_syscall number %d, register dump:\n",
+ (int) regs->u_regs[UREG_G1]);
+ show_regs(regs);
+ }
unlock_kernel();
return -ENOSYS;
}
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index b66a116b4..2c61f6623 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.65 2000/01/14 07:12:34 davem Exp $
+/* $Id: systbls.S,v 1.66 2000/01/16 06:20:48 davem Exp $
* systbls.S: System call entry point tables for OS compatibility.
* The native Linux system call table lives here also.
*
@@ -34,15 +34,15 @@ sys_call_table32:
/*60*/ .word sys_umask, sys_chroot, sys32_newfstat, sys_fstat64, sys_getpagesize
.word sys_msync, sys_vfork, sys32_pread, sys32_pwrite, sys_geteuid
/*70*/ .word sys_getegid, sys32_mmap, sys_setreuid, sys_munmap, sys_mprotect
- .word sys_setregid, sys_vhangup, sys32_truncate64, sys_getgroups, sys32_getgroups16
+ .word sys_nis_syscall, sys_vhangup, sys32_truncate64, sys_nis_syscall, sys32_getgroups16
/*80*/ .word sys32_setgroups16, sys_getpgrp, sys_setgroups, sys32_setitimer, sys32_ftruncate64
.word sys_swapon, sys32_getitimer, sys_setuid, sys_sethostname, sys_setgid
/*90*/ .word sys_dup2, sys_setfsuid, sys32_fcntl, sys32_select, sys_setfsgid
.word sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
/*100*/ .word sys_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending
.word sys32_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_setresuid, sys_getresuid
-/*110*/ .word sys_setresgid, sys_getresgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
- .word sys_nis_syscall, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
+/*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
+ .word sys_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
/*120*/ .word sys32_readv, sys32_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod
.word sys_nis_syscall, sys32_setreuid16, sys32_setregid16, sys_rename, sys_truncate
/*130*/ .word sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 845809709..29032a901 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -1,8 +1,8 @@
-/* $Id: traps.c,v 1.64 1999/12/19 23:53:13 davem Exp $
+/* $Id: traps.c,v 1.65 2000/01/21 11:39:01 jj Exp $
* arch/sparc64/kernel/traps.c
*
* Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1997,1999 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com)
*/
/*
@@ -253,6 +253,8 @@ void rtrap_check(struct pt_regs *regs)
void bad_trap (struct pt_regs *regs, long lvl)
{
+ siginfo_t info;
+
lock_kernel ();
if (lvl < 0x100) {
char buffer[24];
@@ -262,9 +264,12 @@ void bad_trap (struct pt_regs *regs, long lvl)
}
if (regs->tstate & TSTATE_PRIV)
die_if_kernel ("Kernel bad trap", regs);
- current->thread.sig_desc = SUBSIG_BADTRAP(lvl - 0x100);
- current->thread.sig_address = regs->tpc;
- force_sig(SIGILL, current);
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = ILL_ILLTRP;
+ info.si_addr = (void *)regs->tpc;
+ info.si_trapno = lvl - 0x100;
+ force_sig_info(SIGILL, &info, current);
unlock_kernel ();
}
@@ -281,6 +286,8 @@ void bad_trap_tl1 (struct pt_regs *regs, long lvl)
void instruction_access_exception (struct pt_regs *regs,
unsigned long sfsr, unsigned long sfar)
{
+ siginfo_t info;
+
lock_kernel();
if (regs->tstate & TSTATE_PRIV) {
#if 1
@@ -289,15 +296,20 @@ void instruction_access_exception (struct pt_regs *regs,
#endif
die_if_kernel("Iax", regs);
}
- current->thread.sig_desc = SUBSIG_ILLINST;
- current->thread.sig_address = regs->tpc;
- force_sig(SIGILL, current);
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ info.si_code = SEGV_MAPERR;
+ info.si_addr = (void *)regs->tpc;
+ info.si_trapno = 0;
+ force_sig_info(SIGSEGV, &info, current);
unlock_kernel();
}
void data_access_exception (struct pt_regs *regs,
unsigned long sfsr, unsigned long sfar)
{
+ siginfo_t info;
+
if (regs->tstate & TSTATE_PRIV) {
/* Test if this comes from uaccess places. */
unsigned long fixup, g2;
@@ -326,8 +338,13 @@ void data_access_exception (struct pt_regs *regs,
else
rtrap_check(regs);
#endif
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ info.si_code = SEGV_MAPERR;
+ info.si_addr = (void *)sfar;
+ info.si_trapno = 0;
lock_kernel();
- force_sig(SIGSEGV, current);
+ force_sig_info(SIGSEGV, &info, current);
unlock_kernel();
}
@@ -361,6 +378,22 @@ static __inline__ void clean_and_reenable_l1_caches(void)
: "memory");
}
+void do_iae(struct pt_regs *regs)
+{
+ siginfo_t info;
+
+ clean_and_reenable_l1_caches();
+
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = BUS_OBJERR;
+ info.si_addr = (void *)0;
+ info.si_trapno = 0;
+ lock_kernel();
+ force_sig_info(SIGBUS, &info, current);
+ unlock_kernel();
+}
+
void do_dae(struct pt_regs *regs)
{
#ifdef CONFIG_PCI
@@ -381,19 +414,7 @@ void do_dae(struct pt_regs *regs)
return;
}
#endif
- clean_and_reenable_l1_caches();
- lock_kernel();
- force_sig(SIGSEGV, current);
- unlock_kernel();
-}
-
-void do_iae(struct pt_regs *regs)
-{
- clean_and_reenable_l1_caches();
-
- lock_kernel();
- force_sig(SIGSEGV, current);
- unlock_kernel();
+ do_iae(regs);
}
static char ecc_syndrome_table[] = {
@@ -521,22 +542,26 @@ void do_fpe_common(struct pt_regs *regs)
regs->tnpc += 4;
} else {
unsigned long fsr = current->thread.xfsr[0];
+ siginfo_t info;
- current->thread.sig_address = regs->tpc;
- current->thread.sig_desc = SUBSIG_FPERROR;
+ info.si_signo = SIGFPE;
+ info.si_errno = 0;
+ info.si_addr = (void *)regs->tpc;
+ info.si_trapno = 0;
+ info.si_code = __SI_FAULT;
if ((fsr & 0x1c000) == (1 << 14)) {
- if (fsr & 0x01)
- current->thread.sig_desc = SUBSIG_FPINEXACT;
- else if (fsr & 0x02)
- current->thread.sig_desc = SUBSIG_FPDIVZERO;
- else if (fsr & 0x04)
- current->thread.sig_desc = SUBSIG_FPUNFLOW;
+ if (fsr & 0x10)
+ info.si_code = FPE_FLTINV;
else if (fsr & 0x08)
- current->thread.sig_desc = SUBSIG_FPOVFLOW;
- else if (fsr & 0x10)
- current->thread.sig_desc = SUBSIG_FPINTOVFL;
+ info.si_code = FPE_FLTOVF;
+ else if (fsr & 0x04)
+ info.si_code = FPE_FLTUND;
+ else if (fsr & 0x02)
+ info.si_code = FPE_FLTDIV;
+ else if (fsr & 0x01)
+ info.si_code = FPE_FLTRES;
}
- send_sig(SIGFPE, current, 1);
+ send_sig_info(SIGFPE, &info, current);
}
}
@@ -570,24 +595,34 @@ void do_fpother(struct pt_regs *regs)
void do_tof(struct pt_regs *regs)
{
+ siginfo_t info;
+
if(regs->tstate & TSTATE_PRIV)
die_if_kernel("Penguin overflow trap from kernel mode", regs);
- current->thread.sig_address = regs->tpc;
- current->thread.sig_desc = SUBSIG_TAG; /* as good as any */
- send_sig(SIGEMT, current, 1);
+ info.si_signo = SIGEMT;
+ info.si_errno = 0;
+ info.si_code = EMT_TAGOVF;
+ info.si_addr = (void *)regs->tpc;
+ info.si_trapno = 0;
+ send_sig_info(SIGEMT, &info, current);
}
void do_div0(struct pt_regs *regs)
{
- current->thread.sig_address = regs->tpc;
- current->thread.sig_desc = SUBSIG_IDIVZERO;
- send_sig(SIGFPE, current, 1);
+ siginfo_t info;
+
+ info.si_signo = SIGFPE;
+ info.si_errno = 0;
+ info.si_code = FPE_INTDIV;
+ info.si_addr = (void *)regs->tpc;
+ info.si_trapno = 0;
+ send_sig_info(SIGFPE, &info, current);
}
void instruction_dump (unsigned int *pc)
{
int i;
-
+
if((((unsigned long) pc) & 3))
return;
@@ -671,6 +706,7 @@ void do_illegal_instruction(struct pt_regs *regs)
unsigned long pc = regs->tpc;
unsigned long tstate = regs->tstate;
u32 insn;
+ siginfo_t info;
if(tstate & TSTATE_PRIV)
die_if_kernel("Kernel illegal instruction", regs);
@@ -685,56 +721,48 @@ void do_illegal_instruction(struct pt_regs *regs)
return;
}
}
- current->thread.sig_address = pc;
- current->thread.sig_desc = SUBSIG_ILLINST;
- send_sig(SIGILL, current, 1);
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = ILL_ILLOPC;
+ info.si_addr = (void *)pc;
+ info.si_trapno = 0;
+ send_sig_info(SIGILL, &info, current);
}
void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr)
{
+ siginfo_t info;
+
if(regs->tstate & TSTATE_PRIV) {
extern void kernel_unaligned_trap(struct pt_regs *regs,
unsigned int insn,
unsigned long sfar, unsigned long sfsr);
return kernel_unaligned_trap(regs, *((unsigned int *)regs->tpc), sfar, sfsr);
- } else {
- current->thread.sig_address = regs->tpc;
- current->thread.sig_desc = SUBSIG_PRIVINST;
- send_sig(SIGBUS, current, 1);
}
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = BUS_ADRALN;
+ info.si_addr = (void *)sfar;
+ info.si_trapno = 0;
+ send_sig_info(SIGBUS, &info, current);
}
void do_privop(struct pt_regs *regs)
{
- current->thread.sig_address = regs->tpc;
- current->thread.sig_desc = SUBSIG_PRIVINST;
- send_sig(SIGILL, current, 1);
-}
-
-void do_privact(struct pt_regs *regs)
-{
- current->thread.sig_address = regs->tpc;
- current->thread.sig_desc = SUBSIG_PRIVINST;
- send_sig(SIGILL, current, 1);
-}
+ siginfo_t info;
-void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc,
- unsigned long tstate)
-{
- if(tstate & TSTATE_PRIV)
- die_if_kernel("Penguin instruction from Penguin mode??!?!", regs);
- current->thread.sig_address = pc;
- current->thread.sig_desc = SUBSIG_PRIVINST;
- send_sig(SIGILL, current, 1);
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = ILL_PRVOPC;
+ info.si_addr = (void *)regs->tpc;
+ info.si_trapno = 0;
+ send_sig_info(SIGILL, &info, current);
}
-void handle_hw_divzero(struct pt_regs *regs, unsigned long pc,
- unsigned long npc, unsigned long psr)
+void do_privact(struct pt_regs *regs)
{
- current->thread.sig_address = regs->tpc;
- current->thread.sig_desc = SUBSIG_IDIVZERO;
- send_sig(SIGFPE, current, 1);
+ do_privop(regs);
}
/* Trap level 1 stuff or other traps we should never see... */
diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile
index 90d1c4e7c..f3067cad6 100644
--- a/arch/sparc64/lib/Makefile
+++ b/arch/sparc64/lib/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.19 1999/07/03 22:11:08 davem Exp $
+# $Id: Makefile,v 1.20 2000/01/19 04:06:03 davem Exp $
# Makefile for Sparc library files..
#
@@ -6,8 +6,8 @@ CFLAGS := $(CFLAGS)
OBJS = PeeCeeI.o blockops.o debuglocks.o strlen.o strncmp.o \
memscan.o strncpy_from_user.o strlen_user.o memcmp.o checksum.o \
- VIScopy.o VISbzero.o VISmemset.o VIScsum.o VIScsumcopy.o VISsave.o \
- atomic.o rwlock.o
+ VIScopy.o VISbzero.o VISmemset.o VIScsum.o VIScsumcopy.o \
+ VIScsumcopyusr.o VISsave.o atomic.o rwlock.o
lib.a: $(OBJS)
$(AR) rcs lib.a $(OBJS)
diff --git a/arch/sparc64/lib/VIScsumcopy.S b/arch/sparc64/lib/VIScsumcopy.S
index dbf89b4f6..3f89eea29 100644
--- a/arch/sparc64/lib/VIScsumcopy.S
+++ b/arch/sparc64/lib/VIScsumcopy.S
@@ -1,4 +1,4 @@
-/* $Id: VIScsumcopy.S,v 1.6 1999/05/25 16:53:03 jj Exp $
+/* $Id: VIScsumcopy.S,v 1.7 2000/01/19 04:06:03 davem Exp $
* VIScsumcopy.S: High bandwidth IP checksumming with simultaneous
* copying utilizing the UltraSparc Visual Instruction Set.
*
@@ -75,7 +75,7 @@
membar #Sync
-#define DO_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,F0,F2,F4,F6,F8,F10,F12,F14,DUMMY1,A0,A2,A4,A6,A8,A10,A12,A14,B14,DYMMY2,LOAD,STORE1,STORE2,STORE3,STORE4,STORE5,STORE6,STORE7,STORE8,DUMMY3,BRANCH...) \
+#define DO_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,F0,F2,F4,F6,F8,F10,F12,F14,DUMMY1,A0,A2,A4,A6,A8,A10,A12,A14,B14,DUMMY2,LOAD,STORE1,STORE2,STORE3,STORE4,STORE5,STORE6,STORE7,STORE8,DUMMY3,BRANCH...) \
LOAD /* Load Group */; \
faligndata %A14, %F0, %A14 /* FPA Group */; \
inc %x5 /* IEU0 */; \
diff --git a/arch/sparc64/lib/VIScsumcopyusr.S b/arch/sparc64/lib/VIScsumcopyusr.S
new file mode 100644
index 000000000..17bbe78b1
--- /dev/null
+++ b/arch/sparc64/lib/VIScsumcopyusr.S
@@ -0,0 +1,914 @@
+/* $Id: VIScsumcopyusr.S,v 1.1 2000/01/19 04:06:04 davem Exp $
+ * VIScsumcopyusr.S: High bandwidth IP checksumming with simultaneous
+ * copying utilizing the UltraSparc Visual Instruction Set.
+ *
+ * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 2000 David S. Miller (davem@redhat.com)
+ *
+ * Based on older sparc32/sparc64 checksum.S, which is:
+ *
+ * Copyright(C) 1995 Linus Torvalds
+ * Copyright(C) 1995 Miguel de Icaza
+ * Copyright(C) 1996,1997 David S. Miller
+ * derived from:
+ * Linux/Alpha checksum c-code
+ * Linux/ix86 inline checksum assembly
+ * RFC1071 Computing the Internet Checksum (esp. Jacobsons m68k code)
+ * David Mosberger-Tang for optimized reference c-code
+ * BSD4.4 portable checksum routine
+ */
+
+#ifdef __sparc_v9__
+#define STACKOFF 0x7ff+128
+#else
+#define STACKOFF 64
+#endif
+
+#ifdef __KERNEL__
+#include <asm/head.h>
+#include <asm/asi.h>
+#include <asm/page.h>
+#include <asm/visasm.h>
+#define ASI_BLK_XOR 0
+#define ASI_BLK_XOR1 (ASI_BLK_P ^ (ASI_BLK_P >> 3) ^ ASI_P)
+#define ASI_BLK_OR (ASI_BLK_P & ~ASI_P)
+#else
+#define ASI_P 0x80
+#define ASI_BLK_P 0xf0
+#define FRPS_FEF 0x04
+#define FPRS_DU 0x02
+#define FPRS_DL 0x01
+#define ASI_BLK_XOR (ASI_BLK_P ^ ASI_P)
+#endif
+
+#define src o0
+#define dst o1
+#define len o2
+#define sum o3
+#define x1 g1
+#define x2 g2
+#define x3 o4
+#define x4 g4
+#define x5 g5
+#define x6 g7
+#define x7 g3
+#define x8 o5
+
+/* Dobrou noc, SunSoft engineers. Spete sladce.
+ * This has a couple of tricks in and those
+ * tricks are UltraLinux trade secrets :))
+ * Once AGAIN, the SunSoft engineers are caught
+ * asleep at the keyboard :)).
+ * The main loop does about 20 superscalar cycles
+ * per 64bytes checksummed/copied.
+ */
+
+#define LDBLK(O0) \
+ ldda [%src] ASI_BLK_P, %O0 /* Load Group */
+
+#define STBLK \
+ stda %f48, [%dst] %asi /* Store */
+
+#ifdef __KERNEL__
+#define STBLK_XORASI(tmpreg1,tmpreg2) \
+ stda %f48, [%dst] %asi /* Store */; \
+ rd %asi, %tmpreg1; \
+ srl %tmpreg1, 3, %tmpreg2; \
+ xor %tmpreg1, ASI_BLK_XOR1, %tmpreg1; \
+ wr %tmpreg1, %tmpreg2, %asi;
+#else
+#define STBLK_XORASI(tmpreg1,tmpreg2) \
+ stda %f48, [%dst] %asi /* Store */; \
+ rd %asi, %tmpreg1; \
+ wr %tmpreg1, ASI_BLK_XOR, %asi;
+#endif
+
+#define ST(fx,off) \
+ stda %fx, [%dst + off] %asi /* Store */
+
+#define SYNC \
+ membar #Sync
+
+
+#define DO_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,F0,F2,F4,F6,F8,F10,F12,F14,DUMMY1,A0,A2,A4,A6,A8,A10,A12,A14,B14,DUMMY2,LOAD,STORE1,STORE2,STORE3,STORE4,STORE5,STORE6,STORE7,STORE8,DUMMY3,BRANCH...) \
+ LOAD /* Load Group */; \
+ faligndata %A14, %F0, %A14 /* FPA Group */; \
+ inc %x5 /* IEU0 */; \
+ STORE1 /* Store (optional) */; \
+ faligndata %F0, %F2, %A0 /* FPA Group */; \
+ srl %x5, 1, %x5 /* IEU0 */; \
+ add %sum, %x4, %sum /* IEU1 */; \
+ fpadd32 %F0, %f0, %F0 /* FPA Group */; \
+ inc %x6 /* IEU0 */; \
+ STORE2 /* Store (optional) */; \
+ faligndata %F2, %F4, %A2 /* FPA Group */; \
+ srl %x6, 1, %x6 /* IEU0 */; \
+ add %sum, %x5, %sum /* IEU1 */; \
+ fpadd32 %F2, %f2, %F2 /* FPA Group */; \
+ add %src, 64, %src /* IEU0 */; \
+ add %dst, 64, %dst /* IEU1 */; \
+ fcmpgt32 %f0, %F0, %x1 /* FPM Group */; \
+ inc %x7 /* IEU0 */; \
+ STORE3 /* Store (optional) */; \
+ faligndata %F4, %F6, %A4 /* FPA */; \
+ srl %x7, 1, %x7 /* IEU0 Group */; \
+ add %sum, %x6, %sum /* IEU1 */; \
+ fpadd32 %F4, %f4, %F4 /* FPA */; \
+ fcmpgt32 %f2, %F2, %x2 /* FPM Group */; \
+ inc %x8 /* IEU0 */; \
+ STORE4 /* Store (optional) */; \
+ faligndata %F6, %F8, %A6 /* FPA */; \
+ srl %x8, 1, %x8 /* IEU0 Group */; \
+ add %sum, %x7, %sum /* IEU1 */; \
+ fpadd32 %F6, %f6, %F6 /* FPA */; \
+ fcmpgt32 %f4, %F4, %x3 /* FPM Group */; \
+ inc %x1 /* IEU0 */; \
+ STORE5 /* Store (optional) */; \
+ faligndata %F8, %F10, %A8 /* FPA */; \
+ srl %x1, 1, %x1 /* IEU0 Group */; \
+ add %sum, %x8, %sum /* IEU1 */; \
+ fpadd32 %F8, %f8, %F8 /* FPA */; \
+ fcmpgt32 %f6, %F6, %x4 /* FPM Group */; \
+ inc %x2 /* IEU0 */; \
+ STORE6 /* Store (optional) */; \
+ faligndata %F10, %F12, %A10 /* FPA */; \
+ srl %x2, 1, %x2 /* IEU0 Group */; \
+ add %sum, %x1, %sum /* IEU1 */; \
+ fpadd32 %F10, %f10, %F10 /* FPA */; \
+ fcmpgt32 %f8, %F8, %x5 /* FPM Group */; \
+ inc %x3 /* IEU0 */; \
+ STORE7 /* Store (optional) */; \
+ faligndata %F12, %F14, %A12 /* FPA */; \
+ srl %x3, 1, %x3 /* IEU0 Group */; \
+ add %sum, %x2, %sum /* IEU1 */; \
+ fpadd32 %F12, %f12, %F12 /* FPA */; \
+ fcmpgt32 %f10, %F10, %x6 /* FPM Group */; \
+ inc %x4 /* IEU0 */; \
+ STORE8 /* Store (optional) */; \
+ fmovd %F14, %B14 /* FPA */; \
+ srl %x4, 1, %x4 /* IEU0 Group */; \
+ add %sum, %x3, %sum /* IEU1 */; \
+ fpadd32 %F14, %f14, %F14 /* FPA */; \
+ fcmpgt32 %f12, %F12, %x7 /* FPM Group */; \
+ subcc %len, 64, %len /* IEU1 */; \
+ BRANCH /* CTI */; \
+ fcmpgt32 %f14, %F14, %x8 /* FPM Group */; \
+
+#define END_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,FA,FB,S0,S1,S2,S3,T0,T1,U0,fz) \
+ inc %x5 /* IEU0 Group */; \
+ fpadd32 %f2, %f0, %S0 /* FPA */; \
+ srl %x5, 1, %x5 /* IEU0 Group */; \
+ add %sum, %x4, %sum /* IEU1 */; \
+ fpadd32 %f6, %f4, %S1 /* FPA */; \
+ inc %x6 /* IEU0 Group */; \
+ add %sum, %x5, %sum /* IEU1 */; \
+ fcmpgt32 %f0, %S0, %x1 /* FPM Group */; \
+ srl %x6, 1, %x6 /* IEU0 */; \
+ inc %x7 /* IEU1 */; \
+ fpadd32 %f10, %f8, %S2 /* FPA */; \
+ fcmpgt32 %f4, %S1, %x2 /* FPM Group */; \
+ srl %x7, 1, %x7 /* IEU0 */; \
+ add %sum, %x6, %sum /* IEU1 */; \
+ fpadd32 %f14, %f12, %S3 /* FPA */; \
+ inc %x8 /* IEU0 Group */; \
+ add %sum, %x7, %sum /* IEU1 */; \
+ fzero %fz /* FPA */; \
+ fcmpgt32 %f8, %S2, %x3 /* FPM Group */; \
+ srl %x8, 1, %x8 /* IEU0 */; \
+ inc %x1 /* IEU1 */; \
+ fpadd32 %S0, %S1, %T0 /* FPA */; \
+ fcmpgt32 %f12, %S3, %x4 /* FPM Group */; \
+ srl %x1, 1, %x1 /* IEU0 */; \
+ add %sum, %x8, %sum /* IEU1 */; \
+ fpadd32 %S2, %S3, %T1 /* FPA */; \
+ inc %x2 /* IEU0 Group */; \
+ add %sum, %x1, %sum /* IEU1 */; \
+ fcmpgt32 %S0, %T0, %x5 /* FPM Group */; \
+ srl %x2, 1, %x2 /* IEU0 */; \
+ inc %x3 /* IEU1 */; \
+ fcmpgt32 %S2, %T1, %x6 /* FPM Group */; \
+ srl %x3, 1, %x3 /* IEU0 */; \
+ add %sum, %x2, %sum /* IEU1 */; \
+ inc %x4 /* IEU0 Group */; \
+ add %sum, %x3, %sum /* IEU1 */; \
+ fcmpgt32 %fz, %f2, %x7 /* FPM Group */; \
+ srl %x4, 1, %x4 /* IEU0 */; \
+ inc %x5 /* IEU1 */; \
+ fpadd32 %T0, %T1, %U0 /* FPA */; \
+ fcmpgt32 %fz, %f6, %x8 /* FPM Group */; \
+ srl %x5, 1, %x5 /* IEU0 */; \
+ add %sum, %x4, %sum /* IEU1 */; \
+ inc %x6 /* IEU0 Group */; \
+ add %sum, %x5, %sum /* IEU1 */; \
+ fcmpgt32 %fz, %f10, %x1 /* FPM Group */; \
+ srl %x6, 1, %x6 /* IEU0 */; \
+ inc %x7 /* IEU1 */; \
+ fcmpgt32 %fz, %f14, %x2 /* FPM Group */; \
+ ba,pt %xcc, ett /* CTI */; \
+ fmovd %FA, %FB /* FPA */; \
+
+#define END_THE_TRICK1(f0,f2,f4,f6,f8,f10,f12,f14,FA,FB) \
+ END_THE_TRICK(f0,f2,f4,f6,f8,f10,f12,f14,FA,FB,f48,f50,f52,f54,f56,f58,f60,f62)
+
+#define END_THE_TRICK2(S0,S1,S2,S3,T0,T1,U0,U1,V0,fz) \
+ fpadd32 %U0, %U1, %V0 /* FPA Group */; \
+ srl %x7, 1, %x7 /* IEU0 */; \
+ add %sum, %x6, %sum /* IEU1 */; \
+ std %V0, [%sp + STACKOFF] /* Store Group */; \
+ inc %x8 /* IEU0 */; \
+ sub %sum, %x7, %sum /* IEU1 */; \
+ fcmpgt32 %fz, %S1, %x3 /* FPM Group */; \
+ srl %x8, 1, %x8 /* IEU0 */; \
+ inc %x1 /* IEU1 */; \
+ fcmpgt32 %fz, %S3, %x4 /* FPM Group */; \
+ srl %x1, 1, %x1 /* IEU0 */; \
+ sub %sum, %x8, %sum /* IEU1 */; \
+ ldx [%sp + STACKOFF], %x8 /* Load Group */; \
+ inc %x2 /* IEU0 */; \
+ sub %sum, %x1, %sum /* IEU1 */; \
+ fcmpgt32 %fz, %T1, %x5 /* FPM Group */; \
+ srl %x2, 1, %x2 /* IEU0 */; \
+ inc %x3 /* IEU1 */; \
+ fcmpgt32 %T0, %U0, %x6 /* FPM Group */; \
+ srl %x3, 1, %x3 /* IEU0 */; \
+ sub %sum, %x2, %sum /* IEU1 */; \
+ inc %x4 /* IEU0 Group */; \
+ sub %sum, %x3, %sum /* IEU1 */; \
+ fcmpgt32 %fz, %U1, %x7 /* FPM Group */; \
+ srl %x4, 1, %x4 /* IEU0 */; \
+ inc %x5 /* IEU1 */; \
+ fcmpgt32 %U0, %V0, %x1 /* FPM Group */; \
+ srl %x5, 1, %x5 /* IEU0 */; \
+ sub %sum, %x4, %sum /* IEU1 */; \
+ fcmpgt32 %fz, %V0, %x2 /* FPM Group */; \
+ inc %x6 /* IEU0 */; \
+ sub %sum, %x5, %sum /* IEU1 */; \
+ srl %x6, 1, %x6 /* IEU0 Group */; \
+ inc %x7 /* IEU1 */; \
+ srl %x7, 1, %x7 /* IEU0 Group */; \
+ add %sum, %x6, %sum /* IEU1 */; \
+ inc %x1 /* IEU0 Group */; \
+ sub %sum, %x7, %sum /* IEU1 */; \
+ srl %x1, 1, %x1 /* IEU0 Group */; \
+ inc %x2 /* IEU1 */; \
+ srl %x2, 1, %x2 /* IEU0 Group */; \
+ add %sum, %x1, %sum /* IEU1 */; \
+ sub %sum, %x2, %sum /* IEU0 Group */; \
+ addcc %sum, %x8, %sum /* IEU Group */; \
+ bcs,a,pn %xcc, 33f /* CTI */; \
+ add %sum, 1, %sum /* IEU0 */; \
+33: /* That's it */;
+
+ .text
+ .globl csum_partial_copy_user_vis
+ .align 32
+/* %asi should be either ASI_P or ASI_AIUS for csum_partial_copy resp. csum_partial_copy_from_user */
+/* This assumes that !((%src^%dst)&3) && !((%src|%dst)&1) && %len >= 256 */
+csum_partial_copy_user_vis:
+ andcc %dst, 7, %g0 /* IEU1 Group */
+ be,pt %icc, 4f /* CTI */
+ and %dst, 0x38, %o4 /* IEU0 */
+ mov 1, %g5 /* IEU0 Group */
+ andcc %dst, 2, %g0 /* IEU1 */
+ be,pt %icc, 1f /* CTI */
+ and %dst, 4, %g7 /* IEU0 Group */
+ lduh [%src], %g2 /* Load */
+ sub %len, 2, %len /* IEU0 Group */
+ add %dst, 2, %dst /* IEU1 */
+ andcc %dst, 4, %g7 /* IEU1 Group */
+ sll %g5, 16, %g5 /* IEU0 */
+ stha %g2, [%dst - 2] %asi /* Store Group */
+ sll %g2, 16, %g2 /* IEU0 */
+ add %src, 2, %src /* IEU1 */
+ addcc %g2, %sum, %sum /* IEU1 Group */
+ bcs,a,pn %icc, 1f /* CTI */
+ add %sum, %g5, %sum /* IEU0 */
+1: lduw [%src], %g2 /* Load */
+ brz,a,pn %g7, 4f /* CTI+IEU1 Group */
+ and %dst, 0x38, %o4 /* IEU0 */
+ add %dst, 4, %dst /* IEU0 Group */
+ sub %len, 4, %len /* IEU1 */
+ addcc %g2, %sum, %sum /* IEU1 Group */
+ bcs,a,pn %icc, 1f /* CTI */
+ add %sum, 1, %sum /* IEU0 */
+1: and %dst, 0x38, %o4 /* IEU0 Group */
+ stwa %g2, [%dst - 4] %asi /* Store */
+ add %src, 4, %src /* IEU1 */
+4:
+#ifdef __KERNEL__
+ VISEntry
+#endif
+ mov %src, %g7 /* IEU1 Group */
+ fzero %f48 /* FPA */
+ alignaddr %src, %g0, %src /* Single Group */
+ subcc %g7, %src, %g7 /* IEU1 Group */
+ be,pt %xcc, 1f /* CTI */
+ mov 0x40, %g1 /* IEU0 */
+ lduw [%src], %g2 /* Load Group */
+ subcc %sum, %g2, %sum /* IEU1 Group+load stall */
+ bcs,a,pn %icc, 1f /* CTI */
+ sub %sum, 1, %sum /* IEU0 */
+1: srl %sum, 0, %sum /* IEU0 Group */
+ clr %g5 /* IEU1 */
+ brz,pn %o4, 3f /* CTI+IEU1 Group */
+ sub %g1, %o4, %g1 /* IEU0 */
+ ldd [%src], %f0 /* Load */
+ clr %o4 /* IEU0 Group */
+ andcc %dst, 8, %g0 /* IEU1 */
+ be,pn %icc, 1f /* CTI */
+ ldd [%src + 8], %f2 /* Load Group */
+ add %src, 8, %src /* IEU0 */
+ sub %len, 8, %len /* IEU1 */
+ fpadd32 %f0, %f48, %f50 /* FPA */
+ addcc %dst, 8, %dst /* IEU1 Group */
+ faligndata %f0, %f2, %f16 /* FPA */
+ fcmpgt32 %f48, %f50, %o4 /* FPM Group */
+ fmovd %f2, %f0 /* FPA Group */
+ ldd [%src + 8], %f2 /* Load */
+ stda %f16, [%dst - 8] %asi /* Store */
+ fmovd %f50, %f48 /* FPA */
+1: andcc %g1, 0x10, %g0 /* IEU1 Group */
+ be,pn %icc, 1f /* CTI */
+ and %g1, 0x20, %g1 /* IEU0 */
+ fpadd32 %f0, %f48, %f50 /* FPA */
+ ldd [%src + 16], %f4 /* Load Group */
+ add %src, 16, %src /* IEU0 */
+ add %dst, 16, %dst /* IEU1 */
+ faligndata %f0, %f2, %f16 /* FPA */
+ fcmpgt32 %f48, %f50, %g5 /* FPM Group */
+ sub %len, 16, %len /* IEU0 */
+ inc %o4 /* IEU1 */
+ stda %f16, [%dst - 16] %asi /* Store Group */
+ fpadd32 %f2, %f50, %f48 /* FPA */
+ srl %o4, 1, %o5 /* IEU0 */
+ faligndata %f2, %f4, %f18 /* FPA Group */
+ stda %f18, [%dst - 8] %asi /* Store */
+ fcmpgt32 %f50, %f48, %o4 /* FPM Group */
+ add %o5, %sum, %sum /* IEU0 */
+ ldd [%src + 8], %f2 /* Load */
+ fmovd %f4, %f0 /* FPA */
+1: brz,a,pn %g1, 4f /* CTI+IEU1 Group */
+ rd %asi, %g2 /* LSU Group + 4 bubbles */
+ inc %g5 /* IEU0 */
+ fpadd32 %f0, %f48, %f50 /* FPA */
+ ldd [%src + 16], %f4 /* Load Group */
+ srl %g5, 1, %g5 /* IEU0 */
+ add %dst, 32, %dst /* IEU1 */
+ faligndata %f0, %f2, %f16 /* FPA */
+ fcmpgt32 %f48, %f50, %o5 /* FPM Group */
+ inc %o4 /* IEU0 */
+ ldd [%src + 24], %f6 /* Load */
+ srl %o4, 1, %o4 /* IEU0 Group */
+ add %g5, %sum, %sum /* IEU1 */
+ ldd [%src + 32], %f8 /* Load */
+ fpadd32 %f2, %f50, %f48 /* FPA */
+ faligndata %f2, %f4, %f18 /* FPA Group */
+ sub %len, 32, %len /* IEU0 */
+ stda %f16, [%dst - 32] %asi /* Store */
+ fcmpgt32 %f50, %f48, %g3 /* FPM Group */
+ inc %o5 /* IEU0 */
+ add %o4, %sum, %sum /* IEU1 */
+ fpadd32 %f4, %f48, %f50 /* FPA */
+ faligndata %f4, %f6, %f20 /* FPA Group */
+ srl %o5, 1, %o5 /* IEU0 */
+ fcmpgt32 %f48, %f50, %g5 /* FPM Group */
+ add %o5, %sum, %sum /* IEU0 */
+ stda %f18, [%dst - 24] %asi /* Store */
+ fpadd32 %f6, %f50, %f48 /* FPA */
+ inc %g3 /* IEU0 Group */
+ stda %f20, [%dst - 16] %asi /* Store */
+ add %src, 32, %src /* IEU1 */
+ faligndata %f6, %f8, %f22 /* FPA */
+ fcmpgt32 %f50, %f48, %o4 /* FPM Group */
+ srl %g3, 1, %g3 /* IEU0 */
+ stda %f22, [%dst - 8] %asi /* Store */
+ add %g3, %sum, %sum /* IEU0 Group */
+3: rd %asi, %g2 /* LSU Group + 4 bubbles */
+#ifdef __KERNEL__
+4: sethi %hi(vis0s), %g7 /* IEU0 Group */
+ or %g2, ASI_BLK_OR, %g2 /* IEU1 */
+#else
+4: rd %pc, %g7 /* LSU Group + 4 bubbles */
+#endif
+ inc %g5 /* IEU0 Group */
+ and %src, 0x38, %g3 /* IEU1 */
+ membar #StoreLoad /* LSU Group */
+ srl %g5, 1, %g5 /* IEU0 */
+ inc %o4 /* IEU1 */
+ sll %g3, 8, %g3 /* IEU0 Group */
+ sub %len, 0xc0, %len /* IEU1 */
+ addcc %g5, %sum, %sum /* IEU1 Group */
+ srl %o4, 1, %o4 /* IEU0 */
+ add %g7, %g3, %g7 /* IEU0 Group */
+ add %o4, %sum, %sum /* IEU1 */
+#ifdef __KERNEL__
+ jmpl %g7 + %lo(vis0s), %g0 /* CTI+IEU1 Group */
+#else
+ jmpl %g7 + (vis0s - 4b), %g0 /* CTI+IEU1 Group */
+#endif
+ fzero %f32 /* FPA */
+
+ .align 2048
+vis0s: wr %g2, ASI_BLK_XOR, %asi /* LSU Group */
+ ldda [%src] ASI_BLK_P, %f0 /* Load Group */
+ add %src, 64, %src /* IEU0 Group */
+ ldda [%src] ASI_BLK_P, %f16 /* Load Group */
+ add %src, 64, %src /* IEU0 Group */
+ fmovd %f48, %f62 /* FPA Group f0 available */
+ faligndata %f0, %f2, %f48 /* FPA Group f2 available */
+ fcmpgt32 %f32, %f2, %x1 /* FPM Group f4 available */
+ fpadd32 %f0, %f62, %f0 /* FPA */
+ fcmpgt32 %f32, %f4, %x2 /* FPM Group f6 available */
+ faligndata %f2, %f4, %f50 /* FPA */
+ fcmpgt32 %f62, %f0, %x3 /* FPM Group f8 available */
+ faligndata %f4, %f6, %f52 /* FPA */
+ fcmpgt32 %f32, %f6, %x4 /* FPM Group f10 available */
+ inc %x1 /* IEU0 */
+ faligndata %f6, %f8, %f54 /* FPA */
+ fcmpgt32 %f32, %f8, %x5 /* FPM Group f12 available */
+ srl %x1, 1, %x1 /* IEU0 */
+ inc %x2 /* IEU1 */
+ faligndata %f8, %f10, %f56 /* FPA */
+ fcmpgt32 %f32, %f10, %x6 /* FPM Group f14 available */
+ srl %x2, 1, %x2 /* IEU0 */
+ add %sum, %x1, %sum /* IEU1 */
+ faligndata %f10, %f12, %f58 /* FPA */
+ fcmpgt32 %f32, %f12, %x7 /* FPM Group */
+ inc %x3 /* IEU0 */
+ add %sum, %x2, %sum /* IEU1 */
+ faligndata %f12, %f14, %f60 /* FPA */
+ fcmpgt32 %f32, %f14, %x8 /* FPM Group */
+ srl %x3, 1, %x3 /* IEU0 */
+ inc %x4 /* IEU1 */
+ fmovd %f14, %f62 /* FPA */
+ srl %x4, 1, %x4 /* IEU0 Group */
+ add %sum, %x3, %sum /* IEU1 */
+vis0: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f48,f50,f52,f54,f56,f58,f60,f62,f62,
+ ,LDBLK(f32), STBLK,,,,,,,,
+ ,bcs,pn %icc, vis0e1)
+ DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f48,f50,f52,f54,f56,f58,f60,f62,f62,
+ ,LDBLK(f0), STBLK,,,,,,,,
+ ,bcs,pn %icc, vis0e2)
+ DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f48,f50,f52,f54,f56,f58,f60,f62,f62,
+ ,LDBLK(f16), STBLK,,,,,,,,
+ ,bcc,pt %icc, vis0)
+vis0e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f48,f50,f52,f54,f56,f58,f60,f62,f32,
+ ,SYNC, STBLK_XORASI(x1,x2),ST(f48,64),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),ST(f60,48),
+ ,add %dst, 56, %dst; add %len, 192 - 8*8, %len; ba,pt %icc, e2)
+vis0e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f48,f50,f52,f54,f56,f58,f60,f62,f0,
+ ,SYNC, STBLK_XORASI(x1,x2),ST(f48,64),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),ST(f60,48),
+ ,add %dst, 56, %dst; add %len, 192 - 8*8, %len; ba,pt %icc, e3)
+vis0e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f48,f50,f52,f54,f56,f58,f60,f62,f16,
+ ,SYNC, STBLK_XORASI(x1,x2),ST(f48,64),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),ST(f60,48),
+ ,add %dst, 56, %dst; add %len, 192 - 8*8, %len; ba,pt %icc, e1)
+ .align 2048
+vis1s: wr %g2, ASI_BLK_XOR, %asi /* LSU Group */
+ sub %src, 8, %src /* IEU0 Group */
+ ldda [%src] ASI_BLK_P, %f0 /* Load Group */
+ add %src, 64, %src /* IEU0 Group */
+ ldda [%src] ASI_BLK_P, %f16 /* Load Group */
+ add %src, 64, %src /* IEU0 Group */
+ fmovd %f0, %f58 /* FPA Group */
+ fmovd %f48, %f0 /* FPA Group */
+ fcmpgt32 %f32, %f2, %x2 /* FPM Group */
+ faligndata %f2, %f4, %f48 /* FPA */
+ fcmpgt32 %f32, %f4, %x3 /* FPM Group */
+ faligndata %f4, %f6, %f50 /* FPA */
+ fcmpgt32 %f32, %f6, %x4 /* FPM Group */
+ faligndata %f6, %f8, %f52 /* FPA */
+ fcmpgt32 %f32, %f8, %x5 /* FPM Group */
+ inc %x2 /* IEU1 */
+ faligndata %f8, %f10, %f54 /* FPA */
+ fcmpgt32 %f32, %f10, %x6 /* FPM Group */
+ srl %x2, 1, %x2 /* IEU0 */
+ faligndata %f10, %f12, %f56 /* FPA */
+ fcmpgt32 %f32, %f12, %x7 /* FPM Group */
+ inc %x3 /* IEU0 */
+ add %sum, %x2, %sum /* IEU1 */
+ faligndata %f12, %f14, %f58 /* FPA */
+ fcmpgt32 %f32, %f14, %x8 /* FPM Group */
+ srl %x3, 1, %x3 /* IEU0 */
+ inc %x4 /* IEU1 */
+ fmovd %f14, %f60 /* FPA */
+ srl %x4, 1, %x4 /* IEU0 Group */
+ add %sum, %x3, %sum /* IEU1 */
+vis1: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f62,f48,f50,f52,f54,f56,f58,f60,f60,
+ ,LDBLK(f32), ,STBLK,,,,,,,
+ ,bcs,pn %icc, vis1e1)
+ DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f62,f48,f50,f52,f54,f56,f58,f60,f60,
+ ,LDBLK(f0), ,STBLK,,,,,,,
+ ,bcs,pn %icc, vis1e2)
+ DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f62,f48,f50,f52,f54,f56,f58,f60,f60,
+ ,LDBLK(f16), ,STBLK,,,,,,,
+ ,bcc,pt %icc, vis1)
+vis1e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f62,f48,f50,f52,f54,f56,f58,f60,f32,
+ ,SYNC, ,STBLK_XORASI(x1,x2),ST(f48,0),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),
+ ,add %dst, 48, %dst; add %len, 192 - 7*8, %len; ba,pt %icc, e2)
+vis1e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f62,f48,f50,f52,f54,f56,f58,f60,f0,
+ ,SYNC, ,STBLK_XORASI(x1,x2),ST(f48,0),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),
+ ,add %dst, 48, %dst; add %len, 192 - 7*8, %len; ba,pt %icc, e3)
+vis1e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f62,f48,f50,f52,f54,f56,f58,f60,f16,
+ ,SYNC, ,STBLK_XORASI(x1,x2),ST(f48,0),ST(f50,8),ST(f52,16),ST(f54,24),ST(f56,32),ST(f58,40),
+ ,add %dst, 48, %dst; add %len, 192 - 7*8, %len; ba,pt %icc, e1)
+ .align 2048
+vis2s: wr %g2, ASI_BLK_XOR, %asi /* LSU Group */
+ sub %src, 16, %src /* IEU0 Group */
+ ldda [%src] ASI_BLK_P, %f0 /* Load Group */
+ add %src, 64, %src /* IEU0 Group */
+ ldda [%src] ASI_BLK_P, %f16 /* Load Group */
+ add %src, 64, %src /* IEU0 Group */
+ fmovd %f0, %f56 /* FPA Group */
+ fmovd %f48, %f0 /* FPA Group */
+ sub %dst, 64, %dst /* IEU0 */
+ fpsub32 %f2, %f2, %f2 /* FPA Group */
+ fcmpgt32 %f32, %f4, %x3 /* FPM Group */
+ faligndata %f4, %f6, %f48 /* FPA */
+ fcmpgt32 %f32, %f6, %x4 /* FPM Group */
+ faligndata %f6, %f8, %f50 /* FPA */
+ fcmpgt32 %f32, %f8, %x5 /* FPM Group */
+ faligndata %f8, %f10, %f52 /* FPA */
+ fcmpgt32 %f32, %f10, %x6 /* FPM Group */
+ faligndata %f10, %f12, %f54 /* FPA */
+ fcmpgt32 %f32, %f12, %x7 /* FPM Group */
+ inc %x3 /* IEU0 */
+ faligndata %f12, %f14, %f56 /* FPA */
+ fcmpgt32 %f32, %f14, %x8 /* FPM Group */
+ srl %x3, 1, %x3 /* IEU0 */
+ inc %x4 /* IEU1 */
+ fmovd %f14, %f58 /* FPA */
+ srl %x4, 1, %x4 /* IEU0 Group */
+ add %sum, %x3, %sum /* IEU1 */
+vis2: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f60,f62,f48,f50,f52,f54,f56,f58,f58,
+ ,LDBLK(f32), ,,STBLK,,,,,,
+ ,bcs,pn %icc, vis2e1)
+ DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f60,f62,f48,f50,f52,f54,f56,f58,f58,
+ ,LDBLK(f0), ,,STBLK,,,,,,
+ ,bcs,pn %icc, vis2e2)
+ DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f60,f62,f48,f50,f52,f54,f56,f58,f58,
+ ,LDBLK(f16), ,,STBLK,,,,,,
+ ,bcc,pt %icc, vis2)
+vis2e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f60,f62,f48,f50,f52,f54,f56,f58,f32,
+ ,SYNC, ,,STBLK_XORASI(x2,x3),ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88),ST(f56,96),
+ ,add %dst, 104, %dst; add %len, 192 - 6*8, %len; ba,pt %icc, e2)
+vis2e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f60,f62,f48,f50,f52,f54,f56,f58,f0,
+ ,SYNC, ,,STBLK_XORASI(x2,x3),ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88),ST(f56,96),
+ ,add %dst, 104, %dst; add %len, 192 - 6*8, %len; ba,pt %icc, e3)
+vis2e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f60,f62,f48,f50,f52,f54,f56,f58,f16,
+ ,SYNC, ,,STBLK_XORASI(x2,x3),ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88),ST(f56,96),
+ ,add %dst, 104, %dst; add %len, 192 - 6*8, %len; ba,pt %icc, e1)
+ .align 2048
+vis3s: wr %g2, ASI_BLK_XOR, %asi /* LSU Group */
+ sub %src, 24, %src /* IEU0 Group */
+ ldda [%src] ASI_BLK_P, %f0 /* Load Group */
+ add %src, 64, %src /* IEU0 Group */
+ ldda [%src] ASI_BLK_P, %f16 /* Load Group */
+ add %src, 64, %src /* IEU0 Group */
+ fmovd %f0, %f54 /* FPA Group */
+ fmovd %f48, %f0 /* FPA Group */
+ sub %dst, 64, %dst /* IEU0 */
+ fpsub32 %f2, %f2, %f2 /* FPA Group */
+ fpsub32 %f4, %f4, %f4 /* FPA Group */
+ fcmpgt32 %f32, %f6, %x4 /* FPM Group */
+ faligndata %f6, %f8, %f48 /* FPA */
+ fcmpgt32 %f32, %f8, %x5 /* FPM Group */
+ faligndata %f8, %f10, %f50 /* FPA */
+ fcmpgt32 %f32, %f10, %x6 /* FPM Group */
+ faligndata %f10, %f12, %f52 /* FPA */
+ fcmpgt32 %f32, %f12, %x7 /* FPM Group */
+ faligndata %f12, %f14, %f54 /* FPA */
+ fcmpgt32 %f32, %f14, %x8 /* FPM Group */
+ fmovd %f14, %f56 /* FPA */
+ inc %x4 /* IEU0 */
+ srl %x4, 1, %x4 /* IEU0 Group */
+vis3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f58,f60,f62,f48,f50,f52,f54,f56,f56,
+ ,LDBLK(f32), ,,,STBLK,,,,,
+ ,bcs,pn %icc, vis3e1)
+ DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f58,f60,f62,f48,f50,f52,f54,f56,f56,
+ ,LDBLK(f0), ,,,STBLK,,,,,
+ ,bcs,pn %icc, vis3e2)
+ DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f58,f60,f62,f48,f50,f52,f54,f56,f56,
+ ,LDBLK(f16), ,,,STBLK,,,,,
+ ,bcc,pt %icc, vis3)
+vis3e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f58,f60,f62,f48,f50,f52,f54,f56,f32,
+ ,SYNC, ,,,STBLK_XORASI(x3,x4),ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88),
+ ,add %dst, 96, %dst; add %len, 192 - 5*8, %len; ba,pt %icc, e2)
+vis3e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f58,f60,f62,f48,f50,f52,f54,f56,f0,
+ ,SYNC, ,,,STBLK_XORASI(x3,x4),ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88),
+ ,add %dst, 96, %dst; add %len, 192 - 5*8, %len; ba,pt %icc, e3)
+vis3e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f58,f60,f62,f48,f50,f52,f54,f56,f16,
+ ,SYNC, ,,,STBLK_XORASI(x3,x4),ST(f48,64),ST(f50,72),ST(f52,80),ST(f54,88),
+ ,add %dst, 96, %dst; add %len, 192 - 5*8, %len; ba,pt %icc, e1)
+ .align 2048
+vis4s: wr %g2, ASI_BLK_XOR, %asi /* LSU Group */
+ sub %src, 32, %src /* IEU0 Group */
+ ldda [%src] ASI_BLK_P, %f0 /* Load Group */
+ add %src, 64, %src /* IEU0 Group */
+ ldda [%src] ASI_BLK_P, %f16 /* Load Group */
+ add %src, 64, %src /* IEU0 Group */
+ fmovd %f0, %f52 /* FPA Group */
+ fmovd %f48, %f0 /* FPA Group */
+ sub %dst, 64, %dst /* IEU0 */
+ fpsub32 %f2, %f2, %f2 /* FPA Group */
+ fpsub32 %f4, %f4, %f4 /* FPA Group */
+ fpsub32 %f6, %f6, %f6 /* FPA Group */
+ clr %x4 /* IEU0 */
+ fcmpgt32 %f32, %f8, %x5 /* FPM Group */
+ faligndata %f8, %f10, %f48 /* FPA */
+ fcmpgt32 %f32, %f10, %x6 /* FPM Group */
+ faligndata %f10, %f12, %f50 /* FPA */
+ fcmpgt32 %f32, %f12, %x7 /* FPM Group */
+ faligndata %f12, %f14, %f52 /* FPA */
+ fcmpgt32 %f32, %f14, %x8 /* FPM Group */
+ fmovd %f14, %f54 /* FPA */
+vis4: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f56,f58,f60,f62,f48,f50,f52,f54,f54,
+ ,LDBLK(f32), ,,,,STBLK,,,,
+ ,bcs,pn %icc, vis4e1)
+ DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f56,f58,f60,f62,f48,f50,f52,f54,f54,
+ ,LDBLK(f0), ,,,,STBLK,,,,
+ ,bcs,pn %icc, vis4e2)
+ DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f56,f58,f60,f62,f48,f50,f52,f54,f54,
+ ,LDBLK(f16), ,,,,STBLK,,,,
+ ,bcc,pt %icc, vis4)
+vis4e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f56,f58,f60,f62,f48,f50,f52,f54,f32,
+ ,SYNC, ,,,,STBLK_XORASI(x4,x5),ST(f48,64),ST(f50,72),ST(f52,80),
+ ,add %dst, 88, %dst; add %len, 192 - 4*8, %len; ba,pt %icc, e2)
+vis4e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f56,f58,f60,f62,f48,f50,f52,f54,f0,
+ ,SYNC, ,,,,STBLK_XORASI(x4,x5),ST(f48,64),ST(f50,72),ST(f52,80),
+ ,add %dst, 88, %dst; add %len, 192 - 4*8, %len; ba,pt %icc, e3)
+vis4e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f56,f58,f60,f62,f48,f50,f52,f54,f16,
+ ,SYNC, ,,,,STBLK_XORASI(x4,x5),ST(f48,64),ST(f50,72),ST(f52,80),
+ ,add %dst, 88, %dst; add %len, 192 - 4*8, %len; ba,pt %icc, e1)
+ .align 2048
+vis5s: ldd [%src+0], %f10 /* Load Group */
+ ldd [%src+8], %f12 /* Load Group */
+ ldd [%src+16], %f14 /* Load Group */
+ add %src, 24, %src /* IEU0 Group */
+ wr %g2, ASI_BLK_XOR, %asi /* LSU Group */
+ ldda [%src] ASI_BLK_P, %f16 /* Load Group */
+ add %src, 64, %src /* IEU0 Group */
+ fmovd %f48, %f0 /* FPA Group */
+ fmuld %f32, %f32, %f2 /* FPM */
+ clr %x4 /* IEU0 */
+ faddd %f32, %f32, %f4 /* FPA Group */
+ fmuld %f32, %f32, %f6 /* FPM */
+ clr %x5 /* IEU0 */
+ faddd %f32, %f32, %f8 /* FPA Group */
+ fcmpgt32 %f32, %f10, %x6 /* FPM Group */
+ sub %dst, 64, %dst /* IEU0 */
+ faligndata %f10, %f12, %f48 /* FPA */
+ fcmpgt32 %f32, %f12, %x7 /* FPM Group */
+ faligndata %f12, %f14, %f50 /* FPA */
+ fcmpgt32 %f32, %f14, %x8 /* FPM Group */
+ fmovd %f14, %f52 /* FPA */
+vis5: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f54,f56,f58,f60,f62,f48,f50,f52,f52,
+ ,LDBLK(f32), ,,,,,STBLK,,,
+ ,bcs,pn %icc, vis5e1)
+ DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f54,f56,f58,f60,f62,f48,f50,f52,f52,
+ ,LDBLK(f0), ,,,,,STBLK,,,
+ ,bcs,pn %icc, vis5e2)
+ DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f54,f56,f58,f60,f62,f48,f50,f52,f52,
+ ,LDBLK(f16), ,,,,,STBLK,,,
+ ,bcc,pt %icc, vis5)
+vis5e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f54,f56,f58,f60,f62,f48,f50,f52,f32,
+ ,SYNC, ,,,,,STBLK_XORASI(x5,x6),ST(f48,64),ST(f50,72),
+ ,add %dst, 80, %dst; add %len, 192 - 3*8, %len; ba,pt %icc, e2)
+vis5e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f54,f56,f58,f60,f62,f48,f50,f52,f0,
+ ,SYNC, ,,,,,STBLK_XORASI(x5,x6),ST(f48,64),ST(f50,72),
+ ,add %dst, 80, %dst; add %len, 192 - 3*8, %len; ba,pt %icc, e3)
+vis5e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f54,f56,f58,f60,f62,f48,f50,f52,f16,
+ ,SYNC, ,,,,,STBLK_XORASI(x5,x6),ST(f48,64),ST(f50,72),
+ ,add %dst, 80, %dst; add %len, 192 - 3*8, %len; ba,pt %icc, e1)
+ .align 2048
+vis6s: ldd [%src+0], %f12 /* Load Group */
+ ldd [%src+8], %f14 /* Load Group */
+ add %src, 16, %src /* IEU0 Group */
+ wr %g2, ASI_BLK_XOR, %asi /* LSU Group */
+ ldda [%src] ASI_BLK_P, %f16 /* Load Group */
+ add %src, 64, %src /* IEU0 Group */
+ fmovd %f48, %f0 /* FPA Group */
+ fmuld %f32, %f32, %f2 /* FPM */
+ clr %x4 /* IEU0 */
+ faddd %f32, %f32, %f4 /* FPA Group */
+ fmuld %f32, %f32, %f6 /* FPM */
+ clr %x5 /* IEU0 */
+ faddd %f32, %f32, %f8 /* FPA Group */
+ fmuld %f32, %f32, %f10 /* FPM */
+ clr %x6 /* IEU0 */
+ fcmpgt32 %f32, %f12, %x7 /* FPM Group */
+ sub %dst, 64, %dst /* IEU0 */
+ fcmpgt32 %f32, %f14, %x8 /* FPM Group */
+ faligndata %f12, %f14, %f48 /* FPA */
+ fmovd %f14, %f50 /* FPA Group */
+vis6: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f52,f54,f56,f58,f60,f62,f48,f50,f50,
+ ,LDBLK(f32), ,,,,,,STBLK,,
+ ,bcs,pn %icc, vis6e1)
+ DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f52,f54,f56,f58,f60,f62,f48,f50,f50,
+ ,LDBLK(f0), ,,,,,,STBLK,,
+ ,bcs,pn %icc, vis6e2)
+ DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f52,f54,f56,f58,f60,f62,f48,f50,f50,
+ ,LDBLK(f16), ,,,,,,STBLK,,
+ ,bcc,pt %icc, vis6)
+vis6e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f52,f54,f56,f58,f60,f62,f48,f50,f32,
+ ,SYNC, ,,,,,,STBLK_XORASI(x6,x7),ST(f48,64),
+ ,add %dst, 72, %dst; add %len, 192 - 2*8, %len; ba,pt %icc, e2)
+vis6e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f52,f54,f56,f58,f60,f62,f48,f50,f0,
+ ,SYNC, ,,,,,,STBLK_XORASI(x6,x7),ST(f48,64),
+ ,add %dst, 72, %dst; add %len, 192 - 2*8, %len; ba,pt %icc, e3)
+vis6e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f52,f54,f56,f58,f60,f62,f48,f50,f16,
+ ,SYNC, ,,,,,,STBLK_XORASI(x6,x7),ST(f48,64),
+ ,add %dst, 72, %dst; add %len, 192 - 2*8, %len; ba,pt %icc, e1)
+ .align 2048
+vis7s: ldd [%src+0], %f14 /* Load Group */
+ add %src, 8, %src /* IEU0 Group */
+ wr %g2, ASI_BLK_XOR, %asi /* LSU Group */
+ ldda [%src] ASI_BLK_P, %f16 /* Load Group */
+ add %src, 64, %src /* IEU0 Group */
+ fmovd %f48, %f0 /* FPA Group */
+ fmuld %f32, %f32, %f2 /* FPM */
+ clr %x4 /* IEU0 */
+ faddd %f32, %f32, %f4 /* FPA Group */
+ fmuld %f32, %f32, %f6 /* FPM */
+ clr %x5 /* IEU0 */
+ faddd %f32, %f32, %f8 /* FPA Group */
+ fmuld %f32, %f32, %f10 /* FPM */
+ clr %x6 /* IEU0 */
+ faddd %f32, %f32, %f12 /* FPA Group */
+ clr %x7 /* IEU0 */
+ fcmpgt32 %f32, %f14, %x8 /* FPM Group */
+ sub %dst, 64, %dst /* IEU0 */
+ fmovd %f14, %f48 /* FPA */
+vis7: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f50,f52,f54,f56,f58,f60,f62,f48,f48,
+ ,LDBLK(f32), ,,,,,,,STBLK,
+ ,bcs,pn %icc, vis7e1)
+ DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f50,f52,f54,f56,f58,f60,f62,f48,f48,
+ ,LDBLK(f0), ,,,,,,,STBLK,
+ ,bcs,pn %icc, vis7e2)
+ DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f50,f52,f54,f56,f58,f60,f62,f48,f48,
+ ,LDBLK(f16), ,,,,,,,STBLK,
+ ,bcc,pt %icc, vis7)
+vis7e3: DO_THE_TRICK( f0,f2,f4,f6,f8,f10,f12,f14,f16,f18,f20,f22,f24,f26,f28,f30,
+ ,f50,f52,f54,f56,f58,f60,f62,f48,f32,
+ ,SYNC, ,,,,,,,STBLK_XORASI(x7,x8),
+ ,add %dst, 64, %dst; add %len, 192 - 1*8, %len; ba,pt %icc, e2)
+vis7e1: DO_THE_TRICK( f16,f18,f20,f22,f24,f26,f28,f30,f32,f34,f36,f38,f40,f42,f44,f46,
+ ,f50,f52,f54,f56,f58,f60,f62,f48,f0,
+ ,SYNC, ,,,,,,,STBLK_XORASI(x7,x8),
+ ,add %dst, 64, %dst; add %len, 192 - 1*8, %len; ba,pt %icc, e3)
+vis7e2: DO_THE_TRICK( f32,f34,f36,f38,f40,f42,f44,f46,f0,f2,f4,f6,f8,f10,f12,f14,
+ ,f50,f52,f54,f56,f58,f60,f62,f48,f16,
+ ,SYNC, ,,,,,,,STBLK_XORASI(x7,x8),
+ ,add %dst, 64, %dst; add %len, 192 - 1*8, %len; ba,pt %icc, e1)
+e1: END_THE_TRICK1( f0,f2,f4,f6,f8,f10,f12,f14,f16,f6)
+e2: END_THE_TRICK1( f16,f18,f20,f22,f24,f26,f28,f30,f32,f6)
+e3: END_THE_TRICK1( f32,f34,f36,f38,f40,f42,f44,f46,f0,f6)
+ett: rd %gsr, %x3 /* LSU Group+4bubbles */
+ andcc %x3, 7, %x3 /* IEU1 Group */
+ add %dst, 8, %dst /* IEU0 */
+ bne,pn %icc, 1f /* CTI */
+ fzero %f10 /* FPA */
+ brz,a,pn %len, 2f /* CTI+IEU1 Group */
+ stda %f6, [%dst - 8] %asi /* Store */
+1: cmp %len, 8 /* IEU1 */
+ blu,pn %icc, 3f /* CTI */
+ sub %src, 64, %src /* IEU0 Group */
+1: ldd [%src], %f2 /* Load Group */
+ fpadd32 %f10, %f2, %f12 /* FPA Group+load stall */
+ add %src, 8, %src /* IEU0 */
+ add %dst, 8, %dst /* IEU1 */
+ faligndata %f6, %f2, %f14 /* FPA Group */
+ fcmpgt32 %f10, %f12, %x5 /* FPM Group */
+ stda %f14, [%dst - 16] %asi /* Store */
+ fmovd %f2, %f6 /* FPA */
+ fmovd %f12, %f10 /* FPA Group */
+ sub %len, 8, %len /* IEU1 */
+ fzero %f16 /* FPA Group - FPU nop */
+ fzero %f18 /* FPA Group - FPU nop */
+ inc %x5 /* IEU0 */
+ srl %x5, 1, %x5 /* IEU0 Group (regdep) */
+ cmp %len, 8 /* IEU1 */
+ bgeu,pt %icc, 1b /* CTI */
+ add %x5, %sum, %sum /* IEU0 Group */
+3: brz,a,pt %x3, 2f /* CTI+IEU1 */
+ stda %f6, [%dst - 8] %asi /* Store Group */
+ sta %f7, [%dst - 8] %asi /* Store Group */
+ sub %dst, 4, %dst /* IEU0 */
+ add %len, 4, %len /* IEU1 */
+2:
+#ifdef __KERNEL__
+ sub %sp, 8, %sp /* IEU0 Group */
+#endif
+ END_THE_TRICK2( f48,f50,f52,f54,f56,f58,f60,f10,f12,f62)
+ membar #Sync /* LSU Group */
+#ifdef __KERNEL__
+ VISExit
+ add %sp, 8, %sp /* IEU0 Group */
+#endif
+23: brnz,pn %len, 26f /* CTI+IEU1 Group */
+24: sllx %sum, 32, %g1 /* IEU0 */
+25: addcc %sum, %g1, %src /* IEU1 Group */
+ srlx %src, 32, %src /* IEU0 Group (regdep) */
+ bcs,a,pn %xcc, 1f /* CTI */
+ add %src, 1, %src /* IEU1 */
+#ifndef __KERNEL__
+1: retl /* CTI Group brk forced */
+ srl %src, 0, %src /* IEU0 */
+#else
+1: sethi %uhi(PAGE_OFFSET), %g4 /* IEU0 Group */
+ retl /* CTI Group brk forced */
+ sllx %g4, 32, %g4 /* IEU0 */
+#endif
+26: andcc %len, 8, %g0 /* IEU1 Group */
+ be,pn %icc, 1f /* CTI */
+ lduw [%src], %o4 /* Load */
+ lduw [%src+4], %g2 /* Load Group */
+ add %src, 8, %src /* IEU0 */
+ add %dst, 8, %dst /* IEU1 */
+ sllx %o4, 32, %g5 /* IEU0 Group */
+ stwa %o4, [%dst - 8] %asi /* Store */
+ or %g5, %g2, %g5 /* IEU0 Group */
+ stwa %g2, [%dst - 4] %asi /* Store */
+ addcc %g5, %sum, %sum /* IEU1 Group */
+ bcs,a,pn %xcc, 1f /* CTI */
+ add %sum, 1, %sum /* IEU0 */
+1: andcc %len, 4, %g0 /* IEU1 Group */
+ be,a,pn %icc, 1f /* CTI */
+ clr %g2 /* IEU0 */
+ lduw [%src], %g7 /* Load */
+ add %src, 4, %src /* IEU0 Group */
+ add %dst, 4, %dst /* IEU1 */
+ sllx %g7, 32, %g2 /* IEU0 Group */
+ stwa %g7, [%dst - 4] %asi /* Store */
+1: andcc %len, 2, %g0 /* IEU1 */
+ be,a,pn %icc, 1f /* CTI */
+ clr %g3 /* IEU0 Group */
+ lduh [%src], %g7 /* Load */
+ add %src, 2, %src /* IEU1 */
+ add %dst, 2, %dst /* IEU0 Group */
+ sll %g7, 16, %g3 /* IEU0 Group */
+ stha %g7, [%dst - 2] %asi /* Store */
+1: andcc %len, 1, %g0 /* IEU1 */
+ be,a,pn %icc, 1f /* CTI */
+ clr %o5 /* IEU0 Group */
+ ldub [%src], %g7 /* Load */
+ sll %g7, 8, %o5 /* IEU0 Group */
+ stba %g7, [%dst] %asi /* Store */
+1: or %g2, %g3, %g3 /* IEU1 */
+ or %o5, %g3, %g3 /* IEU0 Group (regdep) */
+ addcc %g3, %sum, %sum /* IEU1 Group (regdep) */
+ bcs,a,pn %xcc, 1f /* CTI */
+ add %sum, 1, %sum /* IEU0 */
+1: ba,pt %xcc, 25b /* CTI Group */
+ sllx %sum, 32, %g1 /* IEU0 */
+
+#ifdef __KERNEL__
+end:
+
+ .section __ex_table
+ .align 4
+ .word csum_partial_copy_user_vis, 0, end, cpc_handler
+#endif
diff --git a/arch/sparc64/lib/checksum.S b/arch/sparc64/lib/checksum.S
index 07d10ba42..4e962ed47 100644
--- a/arch/sparc64/lib/checksum.S
+++ b/arch/sparc64/lib/checksum.S
@@ -2,7 +2,7 @@
*
* Copyright(C) 1995 Linus Torvalds
* Copyright(C) 1995 Miguel de Icaza
- * Copyright(C) 1996 David S. Miller
+ * Copyright(C) 1996, 2000 David S. Miller
* Copyright(C) 1997 Jakub Jelinek
*
* derived from:
@@ -263,6 +263,238 @@ ccslow: mov 0, %g5
srl %o0, 0, %o0
cpc_end:
+ /* Now the version with userspace as the destination */
+#define CSUMCOPY_LASTCHUNK_USER(off, t0, t1) \
+ ldx [%src - off - 0x08], t0; \
+ ldx [%src - off - 0x00], t1; \
+ nop; nop; \
+ addcc t0, %sum, %sum; \
+ stwa t0, [%dst - off - 0x04] %asi; \
+ srlx t0, 32, t0; \
+ bcc,pt %xcc, 51f; \
+ stwa t0, [%dst - off - 0x08] %asi; \
+ add %sum, 1, %sum; \
+51: addcc t1, %sum, %sum; \
+ stwa t1, [%dst - off + 0x04] %asi; \
+ srlx t1, 32, t1; \
+ bcc,pt %xcc, 52f; \
+ stwa t1, [%dst - off - 0x00] %asi; \
+ add %sum, 1, %sum; \
+52:
+
+cpc_user_start:
+cc_user_end_cruft:
+ andcc %g7, 8, %g0 ! IEU1 Group
+ be,pn %icc, 1f ! CTI
+ and %g7, 4, %g5 ! IEU0
+ ldx [%src + 0x00], %g2 ! Load Group
+ add %dst, 8, %dst ! IEU0
+ add %src, 8, %src ! IEU1
+ addcc %g2, %sum, %sum ! IEU1 Group + 2 bubbles
+ stwa %g2, [%dst - 0x04] %asi ! Store
+ srlx %g2, 32, %g2 ! IEU0
+ bcc,pt %xcc, 1f ! CTI Group
+ stwa %g2, [%dst - 0x08] %asi ! Store
+ add %sum, 1, %sum ! IEU0
+1: brz,pt %g5, 1f ! CTI Group
+ clr %g2 ! IEU0
+ lduw [%src + 0x00], %g2 ! Load
+ add %dst, 4, %dst ! IEU0 Group
+ add %src, 4, %src ! IEU1
+ stwa %g2, [%dst - 0x04] %asi ! Store Group + 2 bubbles
+ sllx %g2, 32, %g2 ! IEU0
+1: andcc %g7, 2, %g0 ! IEU1
+ be,pn %icc, 1f ! CTI Group
+ clr %o4 ! IEU1
+ lduh [%src + 0x00], %o4 ! Load
+ add %src, 2, %src ! IEU0 Group
+ add %dst, 2, %dst ! IEU1
+ stha %o4, [%dst - 0x2] %asi ! Store Group + 2 bubbles
+ sll %o4, 16, %o4 ! IEU0
+1: andcc %g7, 1, %g0 ! IEU1
+ be,pn %icc, 1f ! CTI Group
+ clr %o5 ! IEU0
+ ldub [%src + 0x00], %o5 ! Load
+ stba %o5, [%dst + 0x00] %asi ! Store Group + 2 bubbles
+ sll %o5, 8, %o5 ! IEU0
+1: or %g2, %o4, %o4 ! IEU1
+ or %o5, %o4, %o4 ! IEU0 Group
+ addcc %o4, %sum, %sum ! IEU1
+ bcc,pt %xcc, ccuserfold ! CTI
+ sethi %uhi(PAGE_OFFSET), %g4 ! IEU0 Group
+ b,pt %xcc, ccuserfold ! CTI
+ add %sum, 1, %sum ! IEU1
+
+cc_user_fixit:
+ cmp %len, 6 ! IEU1 Group
+ bl,a,pn %icc, ccuserte ! CTI
+ andcc %len, 0xf, %g7 ! IEU1 Group
+ andcc %src, 2, %g0 ! IEU1 Group
+ be,pn %icc, 1f ! CTI
+ andcc %src, 0x4, %g0 ! IEU1 Group
+ lduh [%src + 0x00], %g4 ! Load
+ sub %len, 2, %len ! IEU0
+ add %src, 2, %src ! IEU0 Group
+ add %dst, 2, %dst ! IEU1
+ sll %g4, 16, %g3 ! IEU0 Group + 1 bubble
+ addcc %g3, %sum, %sum ! IEU1
+ bcc,pt %xcc, 0f ! CTI
+ srl %sum, 16, %g3 ! IEU0 Group
+ add %g3, 1, %g3 ! IEU0 4 clocks (mispredict)
+0: andcc %src, 0x4, %g0 ! IEU1 Group
+ stha %g4, [%dst - 0x2] %asi ! Store
+ sll %sum, 16, %sum ! IEU0
+ sll %g3, 16, %g3 ! IEU0 Group
+ srl %sum, 16, %sum ! IEU0 Group
+ or %g3, %sum, %sum ! IEU0 Group (regdep)
+1: be,pt %icc, ccusermerge ! CTI
+ andcc %len, 0xf0, %g1 ! IEU1
+ lduw [%src + 0x00], %g4 ! Load Group
+ sub %len, 4, %len ! IEU0
+ add %src, 4, %src ! IEU1
+ add %dst, 4, %dst ! IEU0 Group
+ addcc %g4, %sum, %sum ! IEU1 Group + 1 bubble
+ stwa %g4, [%dst - 0x4] %asi ! Store
+ bcc,pt %xcc, ccusermerge ! CTI
+ andcc %len, 0xf0, %g1 ! IEU1 Group
+ b,pt %xcc, ccusermerge ! CTI 4 clocks (mispredict)
+ add %sum, 1, %sum ! IEU0
+
+ .align 32
+ .globl csum_partial_copy_user_sparc64
+csum_partial_copy_user_sparc64: /* %o0=src, %o1=dest, %o2=len, %o3=sum */
+ xorcc %src, %dst, %o4 ! IEU1 Group
+ srl %sum, 0, %sum ! IEU0
+ andcc %o4, 3, %g0 ! IEU1 Group
+ srl %len, 0, %len ! IEU0
+ bne,pn %icc, ccuserslow ! CTI
+ andcc %src, 1, %g0 ! IEU1 Group
+ bne,pn %icc, ccuserslow ! CTI
+ cmp %len, 256 ! IEU1 Group
+ bgeu,pt %icc, csum_partial_copy_user_vis ! CTI
+ andcc %src, 7, %g0 ! IEU1 Group
+ bne,pn %icc, cc_user_fixit ! CTI
+ andcc %len, 0xf0, %g1 ! IEU1 Group
+ccusermerge:
+ be,pn %icc, ccuserte ! CTI
+ andcc %len, 0xf, %g7 ! IEU1 Group
+ sll %g1, 2, %o4 ! IEU0
+13: sethi %hi(12f), %o5 ! IEU0 Group
+ add %src, %g1, %src ! IEU1
+ sub %o5, %o4, %o5 ! IEU0 Group
+ jmpl %o5 + %lo(12f), %g0 ! CTI Group brk forced
+ add %dst, %g1, %dst ! IEU0 Group
+ccusertbl:
+ CSUMCOPY_LASTCHUNK_USER(0xe8,%g2,%g3)
+ CSUMCOPY_LASTCHUNK_USER(0xd8,%g2,%g3)
+ CSUMCOPY_LASTCHUNK_USER(0xc8,%g2,%g3)
+ CSUMCOPY_LASTCHUNK_USER(0xb8,%g2,%g3)
+ CSUMCOPY_LASTCHUNK_USER(0xa8,%g2,%g3)
+ CSUMCOPY_LASTCHUNK_USER(0x98,%g2,%g3)
+ CSUMCOPY_LASTCHUNK_USER(0x88,%g2,%g3)
+ CSUMCOPY_LASTCHUNK_USER(0x78,%g2,%g3)
+ CSUMCOPY_LASTCHUNK_USER(0x68,%g2,%g3)
+ CSUMCOPY_LASTCHUNK_USER(0x58,%g2,%g3)
+ CSUMCOPY_LASTCHUNK_USER(0x48,%g2,%g3)
+ CSUMCOPY_LASTCHUNK_USER(0x38,%g2,%g3)
+ CSUMCOPY_LASTCHUNK_USER(0x28,%g2,%g3)
+ CSUMCOPY_LASTCHUNK_USER(0x18,%g2,%g3)
+ CSUMCOPY_LASTCHUNK_USER(0x08,%g2,%g3)
+12:
+ andcc %len, 0xf, %g7 ! IEU1 Group
+ccuserte:
+ bne,pn %icc, cc_user_end_cruft ! CTI
+ sethi %uhi(PAGE_OFFSET), %g4 ! IEU0
+ccuserfold:
+ sllx %sum, 32, %o0 ! IEU0 Group
+ addcc %sum, %o0, %o0 ! IEU1 Group (regdep)
+ srlx %o0, 32, %o0 ! IEU0 Group (regdep)
+ bcs,a,pn %xcc, 1f ! CTI
+ add %o0, 1, %o0 ! IEU1 4 clocks (mispredict)
+1: retl ! CTI Group brk forced
+ sllx %g4, 32, %g4 ! IEU0 Group
+
+ccuserslow:
+ mov 0, %g5
+ brlez,pn %len, 4f
+ andcc %src, 1, %o5
+ be,a,pt %icc, 1f
+ srl %len, 1, %g7
+ sub %len, 1, %len
+ ldub [%src], %g5
+ add %src, 1, %src
+ stba %g5, [%dst] %asi
+ srl %len, 1, %g7
+ add %dst, 1, %dst
+1: brz,a,pn %g7, 3f
+ andcc %len, 1, %g0
+ andcc %src, 2, %g0
+ be,a,pt %icc, 1f
+ srl %g7, 1, %g7
+ lduh [%src], %o4
+ sub %len, 2, %len
+ srl %o4, 8, %g2
+ sub %g7, 1, %g7
+ stba %g2, [%dst] %asi
+ add %o4, %g5, %g5
+ stba %o4, [%dst + 1] %asi
+ add %src, 2, %src
+ srl %g7, 1, %g7
+ add %dst, 2, %dst
+1: brz,a,pn %g7, 2f
+ andcc %len, 2, %g0
+ lduw [%src], %o4
+5: srl %o4, 24, %g2
+ srl %o4, 16, %g3
+ stba %g2, [%dst] %asi
+ srl %o4, 8, %g2
+ stba %g3, [%dst + 1] %asi
+ add %src, 4, %src
+ stba %g2, [%dst + 2] %asi
+ addcc %o4, %g5, %g5
+ stba %o4, [%dst + 3] %asi
+ addc %g5, %g0, %g5
+ add %dst, 4, %dst
+ subcc %g7, 1, %g7
+ bne,a,pt %icc, 5b
+ lduw [%src], %o4
+ sll %g5, 16, %g2
+ srl %g5, 16, %g5
+ srl %g2, 16, %g2
+ andcc %len, 2, %g0
+ add %g2, %g5, %g5
+2: be,a,pt %icc, 3f
+ andcc %len, 1, %g0
+ lduh [%src], %o4
+ andcc %len, 1, %g0
+ srl %o4, 8, %g2
+ add %src, 2, %src
+ stba %g2, [%dst] %asi
+ add %g5, %o4, %g5
+ stba %o4, [%dst + 1] %asi
+ add %dst, 2, %dst
+3: be,a,pt %icc, 1f
+ sll %g5, 16, %o4
+ ldub [%src], %g2
+ sll %g2, 8, %o4
+ stba %g2, [%dst] %asi
+ add %g5, %o4, %g5
+ sll %g5, 16, %o4
+1: addcc %o4, %g5, %g5
+ srl %g5, 16, %o4
+ addc %g0, %o4, %g5
+ brz,pt %o5, 4f
+ srl %g5, 8, %o4
+ and %g5, 0xff, %g2
+ and %o4, 0xff, %o4
+ sll %g2, 8, %g2
+ or %g2, %o4, %g5
+4: addcc %sum, %g5, %sum
+ addc %g0, %sum, %o0
+ retl
+ srl %o0, 0, %o0
+cpc_user_end:
+
.globl cpc_handler
cpc_handler:
ldx [%sp + 0x7ff + 128], %g1
@@ -277,5 +509,5 @@ cpc_handler:
.section __ex_table
.align 4
- .word cpc_start, 0, cpc_end, cpc_handler
-
+ .word cpc_start, 0, cpc_end, cpc_handler
+ .word cpc_user_start, 0, cpc_user_end, cpc_handler
diff --git a/arch/sparc64/mm/asyncd.c b/arch/sparc64/mm/asyncd.c
index f23a04ede..b87efd590 100644
--- a/arch/sparc64/mm/asyncd.c
+++ b/arch/sparc64/mm/asyncd.c
@@ -1,4 +1,4 @@
-/* $Id: asyncd.c,v 1.11 2000/01/08 20:22:19 davem Exp $
+/* $Id: asyncd.c,v 1.12 2000/01/21 11:39:13 jj Exp $
* The asyncd kernel daemon. This handles paging on behalf of
* processes that receive page faults due to remote (async) memory
* accesses.
@@ -20,6 +20,7 @@
#include <linux/fs.h>
#include <linux/config.h>
#include <linux/interrupt.h>
+#include <linux/signal.h>
#include <asm/dma.h>
#include <asm/system.h> /* for cli()/sti() */
@@ -113,6 +114,7 @@ static int fault_in_page(int taskid,
{
static unsigned last_address;
static int last_task, loop_counter;
+ siginfo_t info;
#warning Need some fixing here... -DaveM
struct task_struct *tsk = current /* XXX task[taskid] */;
pgd_t *pgd;
@@ -181,9 +183,12 @@ no_memory:
bad_area:
stats.failure++;
- tsk->thread.sig_address = address;
- tsk->thread.sig_desc = SUBSIG_NOMAPPING;
- send_sig(SIGSEGV, tsk, 1);
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ info.si_code = SEGV_MAPERR;
+ info.si_addr = (void *)address;
+ info.si_trapno = 0;
+ send_sig_info(SIGSEGV, &info, tsk);
return 1;
}
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index 1835b874f..226246980 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.40 1999/12/01 10:44:53 davem Exp $
+/* $Id: fault.c,v 1.42 2000/01/21 11:39:13 jj Exp $
* arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -149,10 +149,13 @@ asmlinkage void do_sparc64_fault(struct pt_regs *regs, unsigned long address, in
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
unsigned int insn = 0;
+ siginfo_t info;
#ifdef DEBUG_LOCKUPS
static unsigned long lastaddr, lastpc;
static int lastwrite, lockcnt;
#endif
+
+ info.si_code = SEGV_MAPERR;
/*
* If we're in an interrupt or have no user
* context, we must not take the fault..
@@ -233,6 +236,7 @@ asmlinkage void do_sparc64_fault(struct pt_regs *regs, unsigned long address, in
* we can handle it..
*/
good_area:
+ info.si_code = SEGV_ACCERR;
if(write) {
if(!(vma->vm_flags & VM_WRITE))
goto bad_area;
@@ -242,8 +246,14 @@ good_area:
goto bad_area;
}
current->mm->segments = (void *) (address & PAGE_SIZE);
- if (!handle_mm_fault(current, vma, address, write))
- goto do_sigbus;
+ {
+ int fault = handle_mm_fault(current, vma, address, write);
+
+ if (fault < 0)
+ goto out_of_memory;
+ if (!fault)
+ goto do_sigbus;
+ }
up(&mm->mmap_sem);
return;
/*
@@ -324,20 +334,45 @@ do_kernel_fault:
while(1)
barrier();
#endif
- current->thread.sig_address = address;
- current->thread.sig_desc = SUBSIG_NOMAPPING;
- force_sig(SIGSEGV, current);
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ /* info.si_code set above to make clear whether
+ this was a SEGV_MAPERR or SEGV_ACCERR fault. */
+ info.si_addr = (void *)address;
+ info.si_trapno = 0;
+ force_sig_info (SIGSEGV, &info, current);
return;
}
unhandled_fault (address, current, regs);
}
return;
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+out_of_memory:
+ up(&mm->mmap_sem);
+ printk("VM: killing process %s\n", current->comm);
+ if (!(regs->tstate & TSTATE_PRIV))
+ do_exit(SIGKILL);
+ goto do_kernel_fault;
+
do_sigbus:
up(&mm->mmap_sem);
- current->thread.sig_address = address;
- current->thread.sig_desc = SUBSIG_MISCERROR;
- force_sig(SIGBUS, current);
+
+ /*
+ * Send a sigbus, regardless of whether we were in kernel
+ * or user mode.
+ */
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = BUS_ADRERR;
+ info.si_addr = (void *)address;
+ info.si_trapno = 0;
+ force_sig_info (SIGBUS, &info, current);
+
+ /* Kernel mode? Handle exceptions or die */
if (regs->tstate & TSTATE_PRIV)
goto do_kernel_fault;
}
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 1be2716f5..b4306d9ab 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.143 1999/12/16 16:15:14 davem Exp $
+/* $Id: init.c,v 1.144 2000/01/23 07:16:11 davem Exp $
* arch/sparc64/mm/init.c
*
* Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
@@ -40,8 +40,6 @@ unsigned long *sparc64_valid_addr_bitmap;
/* Ugly, but necessary... -DaveM */
unsigned long phys_base;
-static unsigned long totalram_pages = 0;
-
/* get_new_mmu_context() uses "cache + 1". */
spinlock_t ctx_alloc_lock = SPIN_LOCK_UNLOCKED;
unsigned long tlb_context_cache = CTX_FIRST_VERSION - 1;
@@ -125,7 +123,7 @@ void show_mem(void)
show_free_areas();
printk("Free swap: %6dkB\n",
nr_swap_pages << (PAGE_SHIFT-10));
- printk("%ld pages of RAM\n", totalram_pages);
+ printk("%ld pages of RAM\n", num_physpages);
printk("%d free pages\n", nr_free_pages());
printk("%d pages in page table cache\n",pgtable_cache_size);
#ifndef __SMP__
@@ -1088,7 +1086,6 @@ void __init free_mem_map_range(struct page *first, struct page *last)
ClearPageReserved(mem_map + MAP_NR(first));
set_page_count(mem_map + MAP_NR(first), 1);
free_page((unsigned long)first);
- totalram_pages++;
num_physpages++;
first = (struct page *)((unsigned long)first + PAGE_SIZE);
@@ -1180,7 +1177,7 @@ void __init mem_init(void)
#ifdef DEBUG_BOOTMEM
prom_printf("mem_init: Calling free_all_bootmem().\n");
#endif
- num_physpages = totalram_pages = free_all_bootmem();
+ num_physpages = free_all_bootmem();
#if 0
free_unused_mem_map();
#endif
@@ -1202,7 +1199,6 @@ void __init mem_init(void)
memset(empty_pg_dir, 0, sizeof(empty_pg_dir));
addr += alias_base;
free_pgd_fast((pgd_t *)addr);
- totalram_pages++;
num_physpages++;
}
#endif
@@ -1245,14 +1241,13 @@ void free_initmem (void)
ClearPageReserved(p);
set_page_count(p, 1);
__free_page(p);
- totalram_pages++;
num_physpages++;
}
}
void si_meminfo(struct sysinfo *val)
{
- val->totalram = totalram_pages;
+ val->totalram = num_physpages;
val->sharedram = 0;
val->freeram = nr_free_pages();
val->bufferram = atomic_read(&buffermem_pages);
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index 04e676907..450d2fc9e 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -242,8 +242,10 @@ asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2)
/* Let's cheat */
set_utsfield(((struct sol_uname *)A(buf))->sysname,
"SunOS", 1, 0);
+ down_read(&uts_sem);
set_utsfield(((struct sol_uname *)A(buf))->nodename,
system_utsname.nodename, 1, 1);
+ up_read(&uts_sem);
set_utsfield(((struct sol_uname *)A(buf))->release,
"2.6", 0, 0);
set_utsfield(((struct sol_uname *)A(buf))->version,
@@ -263,7 +265,7 @@ asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2)
asmlinkage int solaris_utsname(u32 buf)
{
/* Why should we not lie a bit? */
- down(&uts_sem);
+ down_read(&uts_sem);
set_utsfield(((struct sol_utsname *)A(buf))->sysname,
"SunOS", 0, 0);
set_utsfield(((struct sol_utsname *)A(buf))->nodename,
@@ -274,7 +276,7 @@ asmlinkage int solaris_utsname(u32 buf)
"Generic", 0, 0);
set_utsfield(((struct sol_utsname *)A(buf))->machine,
machine(), 0, 0);
- up(&uts_sem);
+ up_read(&uts_sem);
return 0;
}
@@ -300,8 +302,10 @@ asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count)
case SI_SYSNAME: r = "SunOS"; break;
case SI_HOSTNAME:
r = buffer + 256;
+ down_read(&uts_sem);
for (p = system_utsname.nodename, q = buffer;
q < r && *p && *p != '.'; *q++ = *p++);
+ up_read(&uts_sem);
*q = 0;
r = buffer;
break;
diff --git a/drivers/block/Config.in b/drivers/block/Config.in
index e27fb0109..5634cc488 100644
--- a/drivers/block/Config.in
+++ b/drivers/block/Config.in
@@ -59,18 +59,20 @@ else
if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a "$CONFIG_BLK_DEV_AEC6210" = "y" ]; then
bool ' AEC6210 Tuning support (EXPERIMENTAL)' CONFIG_BLK_DEV_AEC6210_TUNING
fi
+ if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then
+ bool ' ALI M15x3 chipset support' CONFIG_BLK_DEV_ALI15X3
+ if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
+ bool ' AMD Viper support (EXPERIMENTAL)' CONFIG_BLK_DEV_AMD7409
+ fi
+ fi
bool ' CMD64X chipset support' CONFIG_BLK_DEV_CMD64X
- if [ "$CONFIG_BLK_DEV_CMD64X" = "y" -a "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
+ if [ "$CONFIG_BLK_DEV_CMD64X" = "y" -a "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
bool ' CMD64X chipset RAID support (EXPERIMENTAL) (WIP)' CONFIG_BLK_DEV_CMD64X_RAID
fi
if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
bool ' CY82C693 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CY82C693
fi
if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then
- bool ' ALI M15x3 chipset support' CONFIG_BLK_DEV_ALI15X3
- if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
- bool ' AMD Viper support (EXPERIMENTAL)' CONFIG_BLK_DEV_AMD7409
- fi
bool ' HPT34X chipset support' CONFIG_BLK_DEV_HPT34X
if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a "$CONFIG_BLK_DEV_HPT34X" = "y" ]; then
bool ' HPT34X DMA support (EXPERIMENTAL)' CONFIG_BLK_DEV_HPT34X_DMA
@@ -218,15 +220,6 @@ if [ "$CONFIG_PCI" = "y" ]; then
tristate 'Mylex DAC960/DAC1100 PCI RAID Controller support' CONFIG_BLK_DEV_DAC960
fi
-# PARIDE doesn't need PARPORT, but if PARPORT is configured as a module,
-# PARIDE must also be a module. The bogus CONFIG_PARIDE_PARPORT option
-# controls the choices given to the user ...
-
-if [ "$CONFIG_PARPORT" = "y" -o "$CONFIG_PARPORT" = "n" ]; then
- define_tristate CONFIG_PARIDE_PARPORT y
-else
- define_tristate CONFIG_PARIDE_PARPORT m
-fi
dep_tristate 'Parallel port IDE device support' CONFIG_PARIDE $CONFIG_PARIDE_PARPORT
if [ "$CONFIG_PARIDE" = "y" -o "$CONFIG_PARIDE" = "m" ]; then
source drivers/block/paride/Config.in
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index b21c6c1a9..45e86000a 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -1009,6 +1009,45 @@ static boolean DAC960_ReportDeviceConfiguration(DAC960_Controller_T *Controller)
}
+static int DAC_merge_fn(request_queue_t *q, struct request *req,
+ struct buffer_head *bh)
+{
+ int max_segments;
+ DAC960_Controller_T * Controller = q->queuedata;
+
+ max_segments = Controller->MaxSegmentsPerRequest[MINOR(req->rq_dev)];
+
+ if (req->bhtail->b_data + req->bhtail->b_size != bh->b_data) {
+ if (req->nr_segments < max_segments) {
+ req->nr_segments++;
+ return 1;
+ }
+ return 0;
+ }
+
+ return 1;
+}
+
+static int DAC_merge_requests_fn(request_queue_t *q,
+ struct request *req,
+ struct request *next)
+{
+ int max_segments;
+ DAC960_Controller_T * Controller = q->queuedata;
+ int total_segments = req->nr_segments + next->nr_segments;
+
+ max_segments = Controller->MaxSegmentsPerRequest[MINOR(req->rq_dev)];
+
+ if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data)
+ total_segments--;
+
+ if (total_segments > max_segments)
+ return 0;
+
+ req->nr_segments = total_segments;
+ return 1;
+}
+
/*
DAC960_RegisterBlockDevice registers the Block Device structures
associated with Controller.
@@ -1016,6 +1055,8 @@ static boolean DAC960_ReportDeviceConfiguration(DAC960_Controller_T *Controller)
static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
{
+ request_queue_t * q;
+
static void (*RequestFunctions[DAC960_MaxControllers])(request_queue_t *) =
{ DAC960_RequestFunction0, DAC960_RequestFunction1,
DAC960_RequestFunction2, DAC960_RequestFunction3,
@@ -1036,8 +1077,13 @@ static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
/*
Initialize the I/O Request Function.
*/
- blk_init_queue(BLK_DEFAULT_QUEUE(MajorNumber),
- RequestFunctions[Controller->ControllerNumber]);
+ q = BLK_DEFAULT_QUEUE(MajorNumber);
+ blk_init_queue(q, RequestFunctions[Controller->ControllerNumber]);
+ blk_queue_headactive(q, 0);
+ q->merge_fn = DAC_merge_fn;
+ q->merge_requests_fn = DAC_merge_requests_fn;
+ q->queuedata = (void *) Controller;
+
/*
Initialize the Disk Partitions array, Partition Sizes array, Block Sizes
array, Max Sectors per Request array, and Max Segments per Request array.
@@ -1054,7 +1100,6 @@ static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
Controller->GenericDiskInfo.sizes = Controller->PartitionSizes;
blksize_size[MajorNumber] = Controller->BlockSizes;
max_sectors[MajorNumber] = Controller->MaxSectorsPerRequest;
- max_segments[MajorNumber] = Controller->MaxSegmentsPerRequest;
/*
Initialize Read Ahead to 128 sectors.
*/
diff --git a/drivers/block/alim15x3.c b/drivers/block/alim15x3.c
index 7cecae978..4b9b28e3b 100644
--- a/drivers/block/alim15x3.c
+++ b/drivers/block/alim15x3.c
@@ -411,7 +411,11 @@ static byte ali15x3_can_ultra (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
+#if 0
+ if (m5229_revision < 0x20) {
+#else
if (m5229_revision <= 0x20) {
+#endif
return 0;
} else if ((m5229_revision < 0xC2) &&
((drive->media!=ide_disk) ||
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index d9655d275..e6bf5fa0c 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1795,7 +1795,8 @@ int __init amiga_floppy_init(void)
return -EBUSY;
}
- if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE)) == NULL) {
+ if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE, "Floppy")) ==
+ NULL) {
printk("fd: cannot get chip mem buffer\n");
unregister_blkdev(MAJOR_NR,"fd");
return -ENOMEM;
diff --git a/drivers/block/buddha.c b/drivers/block/buddha.c
index 8086dac56..e5862cd31 100644
--- a/drivers/block/buddha.c
+++ b/drivers/block/buddha.c
@@ -111,24 +111,28 @@ static int buddha_ack_intr(ide_hwif_t *hwif)
static int find_buddha(void)
{
- u_int key;
- const struct ConfigDev *cd;
+ struct zorro_dev *z = NULL;
buddha_num_hwifs = 0;
- if ((key = zorro_find(ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA, 0, 0)))
- buddha_num_hwifs = BUDDHA_NUM_HWIFS;
- else if ((key = zorro_find(ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL, 0,
- 0)))
- buddha_num_hwifs = CATWEASEL_NUM_HWIFS;
- if (key) {
- cd = zorro_get_board(key);
- buddha_board = (u_long)cd->cd_BoardAddr;
- if (buddha_board) {
- buddha_board = ZTWO_VADDR(buddha_board);
- /* write to BUDDHA_IRQ_MR to enable the board IRQ */
- *(char *)(buddha_board+BUDDHA_IRQ_MR) = 0;
- zorro_config_board(key, 0);
- }
+ while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
+ unsigned long board;
+ const char *name;
+ if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) {
+ buddha_num_hwifs = BUDDHA_NUM_HWIFS;
+ name = "Buddha IDE Interface";
+ } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) {
+ buddha_num_hwifs = CATWEASEL_NUM_HWIFS;
+ name = "Catweasel IDE Interface and Floppy Controller";
+ } else
+ continue;
+ board = z->resource.start;
+ if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE"))
+ continue;
+ strcpy(z->name, name);
+ buddha_board = ZTWO_VADDR(board);
+ /* write to BUDDHA_IRQ_MR to enable the board IRQ */
+ *(char *)(buddha_board+BUDDHA_IRQ_MR) = 0;
+ break;
}
return buddha_num_hwifs;
}
diff --git a/drivers/block/cmd64x.c b/drivers/block/cmd64x.c
index 6eaa0f3bb..6346f216e 100644
--- a/drivers/block/cmd64x.c
+++ b/drivers/block/cmd64x.c
@@ -228,6 +228,7 @@ static int cmd646_1_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
dma_stat = inb(dma_base+2); /* get DMA status */
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
+ ide_destroy_dmatable(drive); /* and free any DMA resources */
return (dma_stat & 7) != 4; /* verify good DMA status */
}
diff --git a/drivers/block/hpt34x.c b/drivers/block/hpt34x.c
index f01d93152..10fe3ebc1 100644
--- a/drivers/block/hpt34x.c
+++ b/drivers/block/hpt34x.c
@@ -292,7 +292,7 @@ int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
case ide_dma_write:
if (!(count = ide_build_dmatable(drive, func)))
return 1; /* try PIO instead of DMA */
- outl(virt_to_bus(hwif->dmatable), dma_base + 4); /* PRD table */
+ outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
reading |= 0x01;
outb(reading, dma_base); /* specify r/w */
outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
@@ -307,6 +307,7 @@ int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
+ ide_destroy_dmatable(drive); /* purge DMA mappings */
return (dma_stat & 7) != 4; /* verify good DMA status */
default:
break;
diff --git a/drivers/block/hpt366.c b/drivers/block/hpt366.c
index 1b497fecc..65c695183 100644
--- a/drivers/block/hpt366.c
+++ b/drivers/block/hpt366.c
@@ -30,7 +30,6 @@
#include "ide_modes.h"
const char *bad_ata66_4[] = {
- "QUANTUM FIREBALLP KA9.1",
"WDC AC310200R",
NULL
};
@@ -423,30 +422,17 @@ no_dma_set:
int hpt366_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
{
+ byte reg50h = 0;
+
switch (func) {
case ide_dma_check:
return config_drive_xfer_rate(drive);
+ case ide_dma_lostirq:
+ pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, &reg50h);
+ pci_write_config_byte(HWIF(drive)->pci_dev, 0x50, reg50h|0x03);
+ pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, &reg50h);
+ /* ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); */
case ide_dma_timeout:
- /* ide_do_reset(drive); */
-
- if (0) {
- byte reg50h = 0, reg52h = 0;
- (void) ide_dmaproc(ide_dma_off_quietly, drive);
- pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, &reg50h);
- pci_read_config_byte(HWIF(drive)->pci_dev, 0x52, &reg52h);
- printk("%s: (ide_dma_timeout) reg52h=0x%02x\n", drive->name, reg52h);
- if (reg52h & 0x04) {
- pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, &reg50h);
- pci_write_config_byte(HWIF(drive)->pci_dev, 0x50, reg50h|0xff);
- pci_write_config_byte(HWIF(drive)->pci_dev, 0x50, reg50h);
- }
- pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, &reg50h);
- pci_read_config_byte(HWIF(drive)->pci_dev, 0x52, &reg52h);
- printk("%s: (ide_dma_timeout) reg50h=0x%02x reg52h=0x%02x :: again\n", drive->name, reg50h, reg52h);
- (void) ide_dmaproc(ide_dma_on, drive);
- if (reg52h & 0x04)
- (void) ide_dmaproc(ide_dma_off, drive);
- }
break;
default:
break;
diff --git a/drivers/block/icside.c b/drivers/block/icside.c
index d86a990f7..166d29abf 100644
--- a/drivers/block/icside.c
+++ b/drivers/block/icside.c
@@ -226,7 +226,7 @@ icside_build_dmatable(ide_drive_t *drive, int reading)
unsigned long addr, size;
unsigned char *virt_addr;
unsigned int count = 0;
- dmasg_t *sg = (dmasg_t *)HWIF(drive)->dmatable;
+ dmasg_t *sg = (dmasg_t *)HWIF(drive)->dmatable_cpu;
do {
if (bh == NULL) {
@@ -393,7 +393,7 @@ icside_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
*/
set_dma_speed(hwif->hw.dma, drive->drive_data);
- set_dma_sg(hwif->hw.dma, (dmasg_t *)hwif->dmatable, count);
+ set_dma_sg(hwif->hw.dma, (dmasg_t *)hwif->dmatable_cpu, count);
set_dma_mode(hwif->hw.dma, reading ? DMA_MODE_READ
: DMA_MODE_WRITE);
@@ -458,7 +458,7 @@ icside_setup_dma(ide_hwif_t *hwif, int autodma)
if (!table)
printk(" -- ERROR, unable to allocate DMA table\n");
else {
- hwif->dmatable = (void *)table;
+ hwif->dmatable_cpu = (void *)table;
hwif->dmaproc = icside_dmaproc;
hwif->autodma = autodma;
@@ -466,7 +466,7 @@ icside_setup_dma(ide_hwif_t *hwif, int autodma)
", auto-enable" : "");
}
- return hwif->dmatable != NULL;
+ return hwif->dmatable_cpu != NULL;
}
#endif
diff --git a/drivers/block/ide-disk.c b/drivers/block/ide-disk.c
index 14952a049..1209aa82a 100644
--- a/drivers/block/ide-disk.c
+++ b/drivers/block/ide-disk.c
@@ -572,7 +572,7 @@ static void idedisk_pre_reset (ide_drive_t *drive)
drive->special.b.recalibrate = 1;
if (OK_TO_RESET_CONTROLLER)
drive->mult_count = 0;
- if (!drive->keep_settings)
+ if (!drive->keep_settings && !drive->using_dma)
drive->mult_req = 0;
if (drive->mult_req != drive->mult_count)
drive->special.b.set_multmode = 1;
diff --git a/drivers/block/ide-dma.c b/drivers/block/ide-dma.c
index f265180ab..1e450b7e6 100644
--- a/drivers/block/ide-dma.c
+++ b/drivers/block/ide-dma.c
@@ -208,6 +208,31 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
return ide_error(drive, "dma_intr", stat);
}
+static int ide_build_sglist (ide_hwif_t *hwif, struct request *rq)
+{
+ struct buffer_head *bh;
+ struct scatterlist *sg = hwif->sg_table;
+ int nents = 0;
+
+ bh = rq->bh;
+ do {
+ unsigned char *virt_addr = bh->b_data;
+ unsigned int size = bh->b_size;
+
+ 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);
+
+ return pci_map_sg(hwif->pci_dev, sg, nents);
+}
+
/*
* ide_build_dmatable() prepares a dma request.
* Returns 0 if all went okay, returns 1 otherwise.
@@ -215,95 +240,70 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
*/
int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func)
{
- struct request *rq = HWGROUP(drive)->rq;
- struct buffer_head *bh = rq->bh;
- unsigned int size, addr, *table = (unsigned int *)HWIF(drive)->dmatable;
- unsigned char *virt_addr;
+ unsigned int *table = HWIF(drive)->dmatable_cpu;
#ifdef CONFIG_BLK_DEV_TRM290
unsigned int is_trm290_chipset = (HWIF(drive)->chipset == ide_trm290);
#else
const int is_trm290_chipset = 0;
#endif
unsigned int count = 0;
+ int i;
+ struct scatterlist *sg;
- do {
- /*
- * Determine addr and size of next buffer area. We assume that
- * individual virtual buffers are always composed linearly in
- * physical memory. For example, we assume that any 8kB buffer
- * is always composed of two adjacent physical 4kB pages rather
- * than two possibly non-adjacent physical 4kB pages.
- */
- if (bh == NULL) { /* paging requests have (rq->bh == NULL) */
- virt_addr = rq->buffer;
- addr = virt_to_bus (virt_addr);
- size = rq->nr_sectors << 9;
- } else {
- /* group sequential buffers into one large buffer */
- virt_addr = bh->b_data;
- addr = virt_to_bus (virt_addr);
- size = bh->b_size;
- while ((bh = bh->b_reqnext) != NULL) {
- if ((addr + size) != virt_to_bus (bh->b_data))
- break;
- size += bh->b_size;
- }
- }
- /*
- * Fill in the dma table, without crossing any 64kB boundaries.
- * Most hardware requires 16-bit alignment of all blocks,
- * but the trm290 requires 32-bit alignment.
- */
- if ((addr & 3)) {
- printk("%s: misaligned DMA buffer\n", drive->name);
- return 0;
- }
+ HWIF(drive)->sg_nents = i = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq);
- /*
- * Some CPUs without cache snooping need to invalidate/write
- * back their caches before DMA transfers to guarantee correct
- * data. -- rmk
- */
- if (size) {
- if (func == ide_dma_read) {
- dma_cache_inv((unsigned int)virt_addr, size);
- } else {
- dma_cache_wback((unsigned int)virt_addr, size);
- }
- }
+ sg = HWIF(drive)->sg_table;
+ while (i && sg_dma_len(sg)) {
+ u32 cur_addr;
+ u32 cur_len;
+
+ cur_addr = sg_dma_address(sg);
+ cur_len = sg_dma_len(sg);
- while (size) {
+ while (cur_len) {
if (++count >= PRD_ENTRIES) {
printk("%s: DMA table too small\n", drive->name);
+ pci_unmap_sg(HWIF(drive)->pci_dev,
+ HWIF(drive)->sg_table,
+ HWIF(drive)->sg_nents);
return 0; /* revert to PIO for this request */
} else {
- unsigned int xcount, bcount = 0x10000 - (addr & 0xffff);
- if (bcount > size)
- bcount = size;
- *table++ = cpu_to_le32(addr);
+ u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);
+
+ if (bcount > cur_len)
+ bcount = cur_len;
+ *table++ = cpu_to_le32(cur_addr);
xcount = bcount & 0xffff;
if (is_trm290_chipset)
xcount = ((xcount >> 2) - 1) << 16;
*table++ = cpu_to_le32(xcount);
- addr += bcount;
- size -= bcount;
+ cur_addr += bcount;
+ cur_len -= bcount;
}
}
- } while (bh != NULL);
- if (!count) {
- printk("%s: empty DMA table?\n", drive->name);
- } else {
- if (!is_trm290_chipset)
- *--table |= cpu_to_le32(0x80000000); /* set End-Of-Table (EOT) bit */
- /*
- * Some CPUs need to flush the DMA table to physical RAM
- * before DMA can start. -- rmk
- */
- dma_cache_wback((unsigned long)HWIF(drive)->dmatable, count * sizeof(unsigned int) * 2);
+
+ sg++;
+ i--;
}
+
+ if (!count)
+ printk("%s: empty DMA table?\n", drive->name);
+ else if (!is_trm290_chipset)
+ *--table |= cpu_to_le32(0x80000000);
+
return count;
}
+/* Teardown mappings after DMA has completed. */
+void ide_destroy_dmatable (ide_drive_t *drive)
+{
+ struct pci_dev *dev = HWIF(drive)->pci_dev;
+ struct scatterlist *sg = HWIF(drive)->sg_table;
+ int nents = HWIF(drive)->sg_nents;
+
+ pci_unmap_sg(dev, sg, nents);
+}
+
/*
* For both Blacklisted and Whitelisted drives.
* This is setup to be called as an extern for future support
@@ -413,7 +413,7 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
case ide_dma_write:
if (!(count = ide_build_dmatable(drive, func)))
return 1; /* try PIO instead of DMA */
- outl(virt_to_bus(hwif->dmatable), dma_base + 4); /* PRD table */
+ outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
outb(reading, dma_base); /* specify r/w */
outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
drive->waiting_for_dma = 1;
@@ -434,6 +434,7 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
+ ide_destroy_dmatable(drive); /* purge DMA mappings */
return (dma_stat & 7) != 4; /* verify good DMA status */
case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
dma_stat = inb(dma_base+2);
@@ -458,9 +459,16 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
*/
int ide_release_dma (ide_hwif_t *hwif)
{
- if (hwif->dmatable) {
- clear_page((void *)hwif->dmatable); /* clear PRD 1st */
- free_page((unsigned long)hwif->dmatable); /* free PRD 2nd */
+ if (hwif->dmatable_cpu) {
+ pci_free_consistent(hwif->pci_dev,
+ PRD_ENTRIES * PRD_BYTES,
+ hwif->dmatable_cpu,
+ hwif->dmatable_dma);
+ hwif->dmatable_cpu = NULL;
+ }
+ if (hwif->sg_table) {
+ kfree(hwif->sg_table);
+ hwif->sg_table = NULL;
}
if ((hwif->dma_extra) && (hwif->channel == 0))
release_region((hwif->dma_base + 16), hwif->dma_extra);
@@ -474,9 +482,6 @@ int ide_release_dma (ide_hwif_t *hwif)
void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_ports)
{
- static unsigned long dmatable = 0;
- static unsigned leftover = 0;
-
printk(" %s: BM-DMA at 0x%04lx-0x%04lx", hwif->name, dma_base, dma_base + num_ports - 1);
if (check_region(dma_base, num_ports)) {
printk(" -- ERROR, PORT ADDRESSES ALREADY IN USE\n");
@@ -484,31 +489,33 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
}
request_region(dma_base, num_ports, hwif->name);
hwif->dma_base = dma_base;
- if (leftover < (PRD_ENTRIES * PRD_BYTES)) {
- /*
- * The BM-DMA uses full 32bit addr, so we can
- * safely use __get_free_page() here instead
- * of __get_dma_pages() -- no ISA limitations.
- */
- dmatable = __get_free_pages(GFP_KERNEL,1);
- leftover = dmatable ? PAGE_SIZE : 0;
+ hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev,
+ PRD_ENTRIES * PRD_BYTES,
+ &hwif->dmatable_dma);
+ if (hwif->dmatable_cpu == NULL)
+ goto dma_alloc_failure;
+
+ hwif->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
+ GFP_KERNEL);
+ if (hwif->sg_table == NULL) {
+ pci_free_consistent(hwif->pci_dev, PRD_ENTRIES * PRD_BYTES,
+ hwif->dmatable_cpu, hwif->dmatable_dma);
+ goto dma_alloc_failure;
}
- if (!dmatable) {
- printk(" -- ERROR, UNABLE TO ALLOCATE PRD TABLE\n");
- } else {
- hwif->dmatable = (unsigned long *) dmatable;
- dmatable += (PRD_ENTRIES * PRD_BYTES);
- leftover -= (PRD_ENTRIES * PRD_BYTES);
- hwif->dmaproc = &ide_dmaproc;
-
- if (hwif->chipset != ide_trm290) {
- byte dma_stat = inb(dma_base+2);
- printk(", BIOS settings: %s:%s, %s:%s",
- hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio",
- hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio");
- }
- printk("\n");
+
+ hwif->dmaproc = &ide_dmaproc;
+
+ if (hwif->chipset != ide_trm290) {
+ byte dma_stat = inb(dma_base+2);
+ printk(", BIOS settings: %s:%s, %s:%s",
+ hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio",
+ hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio");
}
+ printk("\n");
+ return;
+
+dma_alloc_failure:
+ printk(" -- ERROR, UNABLE TO ALLOCATE DMA TABLES\n");
}
/*
diff --git a/drivers/block/ide-pci.c b/drivers/block/ide-pci.c
index 6ee45c49d..7f429eff2 100644
--- a/drivers/block/ide-pci.c
+++ b/drivers/block/ide-pci.c
@@ -29,8 +29,8 @@
#define DEVID_PIIXb ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_1})
#define DEVID_PIIX3 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1})
#define DEVID_PIIX4 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB})
-#define DEVID_PIIX4E ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1})
-#define DEVID_PIIX4U ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1})
+#define DEVID_PIIX4E ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1})
+#define DEVID_PIIX4U ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1})
#define DEVID_VIA_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561})
#define DEVID_VP_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1})
#define DEVID_PDC20246 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246})
@@ -696,70 +696,45 @@ static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_devic
* ide_scan_pcibus() gets invoked at boot time from ide.c.
* It finds all PCI IDE controllers and calls ide_setup_pci_device for them.
*/
-void __init ide_forward_scan_pcibus (void)
+void __init ide_scan_pcidev (struct pci_dev *dev)
{
- struct pci_dev *dev;
ide_pci_devid_t devid;
ide_pci_device_t *d;
- pci_for_each_dev(dev) {
- devid.vid = dev->vendor;
- devid.did = dev->device;
- for (d = ide_pci_chipsets; d->devid.vid && !IDE_PCI_DEVID_EQ(d->devid, devid); ++d);
- if (d->init_hwif == IDE_IGNORE)
- printk("%s: ignored by ide_scan_pci_device() (uses own driver)\n", d->name);
- else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_OPTI621V) && !(PCI_FUNC(dev->devfn) & 1))
- continue; /* OPTI Viper-M uses same devid for functions 0 and 1 */
- else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) && (!(PCI_FUNC(dev->devfn) & 1) || !((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)))
- continue; /* CY82C693 is more than only a IDE controller */
- else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886A) && !(PCI_FUNC(dev->devfn) & 1))
- continue; /* UM8886A/BF pair */
- else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366))
- hpt366_device_order_fixup(dev, d);
- else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
- if (IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL))
- printk("%s: unknown IDE controller on PCI bus %02x device %02x, VID=%04x, DID=%04x\n",
- d->name, dev->bus->number, dev->devfn, devid.vid, devid.did);
- else
- printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn);
- ide_setup_pci_device(dev, d);
- }
+ devid.vid = dev->vendor;
+ devid.did = dev->device;
+ for (d = ide_pci_chipsets; d->devid.vid && !IDE_PCI_DEVID_EQ(d->devid, devid); ++d);
+ if (d->init_hwif == IDE_IGNORE)
+ printk("%s: ignored by ide_scan_pci_device() (uses own driver)\n", d->name);
+ else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_OPTI621V) && !(PCI_FUNC(dev->devfn) & 1))
+ return;
+ else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) && (!(PCI_FUNC(dev->devfn) & 1) || !((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)))
+ return; /* CY82C693 is more than only a IDE controller */
+ else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886A) && !(PCI_FUNC(dev->devfn) & 1))
+ return; /* UM8886A/BF pair */
+ else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366))
+ hpt366_device_order_fixup(dev, d);
+ else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
+ if (IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL))
+ printk("%s: unknown IDE controller on PCI bus %02x device %02x, VID=%04x, DID=%04x\n",
+ d->name, dev->bus->number, dev->devfn, devid.vid, devid.did);
+ else
+ printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn);
+ ide_setup_pci_device(dev, d);
}
}
-void __init ide_reverse_scan_pcibus (void)
+void __init ide_scan_pcibus (int scan_direction)
{
- struct pci_dev *dev;
- ide_pci_devid_t devid;
- ide_pci_device_t *d;
+ struct pci_dev *dev;
- pci_for_each_dev_reverse(dev) {
- devid.vid = dev->vendor;
- devid.did = dev->device;
- for (d = ide_pci_chipsets; d->devid.vid && !IDE_PCI_DEVID_EQ(d->devid, devid); ++d);
- if (d->init_hwif == IDE_IGNORE)
- printk("%s: ignored by ide_scan_pci_device() (uses own driver)\n", d->name);
- else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_OPTI621V) && !(PCI_FUNC(dev->devfn) & 1))
- continue; /* OPTI Viper-M uses same devid for functions 0 and 1 */
- else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) && (!(PCI_FUNC(dev->devfn) & 1) || !((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)))
- continue; /* CY82C693 is more than only a IDE controller */
- else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886A) && !(PCI_FUNC(dev->devfn) & 1))
- continue; /* UM8886A/BF pair */
- else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366))
- hpt366_device_order_fixup(dev, d);
- else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
- if (IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL))
- printk("%s: unknown IDE controller on PCI bus %02x device %02x, VID=%04x, DID=%04x\n",
- d->name, dev->bus->number, dev->devfn, devid.vid, devid.did);
- else
- printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn);
- ide_setup_pci_device(dev, d);
+ if (!scan_direction) {
+ pci_for_each_dev(dev) {
+ ide_scan_pcidev(dev);
+ }
+ } else {
+ pci_for_each_dev_reverse(dev) {
+ ide_scan_pcidev(dev);
}
}
}
-
-void __init ide_scan_pcibus (int scan_direction)
-{
- if (!scan_direction) ide_forward_scan_pcibus();
- else ide_reverse_scan_pcibus();
-}
diff --git a/drivers/block/ide-pmac.c b/drivers/block/ide-pmac.c
index e1eadcaa2..e6947e560 100644
--- a/drivers/block/ide-pmac.c
+++ b/drivers/block/ide-pmac.c
@@ -241,9 +241,9 @@ pmac_ide_setup_dma(struct device_node *np, ide_hwif_t *hwif)
* The +2 is +1 for the stop command and +1 to allow for
* aligning the start address to a multiple of 16 bytes.
*/
- hwif->dmatable = (unsigned long *)
+ hwif->dmatable_cpu = (unsigned long *)
kmalloc((MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), GFP_KERNEL);
- if (hwif->dmatable == 0) {
+ if (hwif->dmatable_cpu == 0) {
printk(KERN_ERR "%s: unable to allocate DMA command list\n",
hwif->name);
return;
@@ -271,7 +271,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, int wr)
volatile struct dbdma_regs *dma
= (volatile struct dbdma_regs *) hwif->dma_base;
- table = tstart = (struct dbdma_cmd *) DBDMA_ALIGN(hwif->dmatable);
+ table = tstart = (struct dbdma_cmd *) DBDMA_ALIGN(hwif->dmatable_cpu);
out_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
do {
diff --git a/drivers/block/ide-probe.c b/drivers/block/ide-probe.c
index efb4705f3..1c6f19eba 100644
--- a/drivers/block/ide-probe.c
+++ b/drivers/block/ide-probe.c
@@ -285,6 +285,7 @@ static int do_probe (ide_drive_t *drive, byte cmd)
drive->name, drive->present, drive->media,
(cmd == WIN_IDENTIFY) ? "ATA" : "ATAPI");
#endif
+ ide_delay_50ms(); /* needed for some systems (e.g. crw9624 as drive0 with disk as slave) */
SELECT_DRIVE(hwif,drive);
ide_delay_50ms();
if (IN_BYTE(IDE_SELECT_REG) != drive->select.all && !drive->present) {
diff --git a/drivers/block/ide-tape.c b/drivers/block/ide-tape.c
index 429888f32..cba18bced 100644
--- a/drivers/block/ide-tape.c
+++ b/drivers/block/ide-tape.c
@@ -384,7 +384,7 @@
* sharing a (fast) ATA-2 disk with any (slow) new ATAPI device.
*/
-#define IDETAPE_VERSION "1.16e"
+#define IDETAPE_VERSION "1.16f"
#include <linux/config.h>
#include <linux/module.h>
@@ -409,6 +409,9 @@
#include <asm/unaligned.h>
#include <asm/bitops.h>
+
+#define NO_LONGER_REQUIRE (1)
+
/*
* OnStream support
*/
@@ -1735,7 +1738,7 @@ static void idetape_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
aux = stage->aux;
p = stage->bh->b_data;
if (ntohl(aux->logical_blk_num) < 11300 && ntohl(aux->logical_blk_num) > 11100)
- printk(KERN_INFO "ide-tape: finished writing logical blk %lu (data %x %x %x %x)\n", ntohl(aux->logical_blk_num), *p++, *p++, *p++, *p++);
+ printk(KERN_INFO "ide-tape: finished writing logical blk %u (data %x %x %x %x)\n", ntohl(aux->logical_blk_num), *p++, *p++, *p++, *p++);
}
}
#endif
@@ -2695,14 +2698,14 @@ static idetape_stage_t *__idetape_kmalloc_stage (idetape_tape_t *tape, int full,
goto abort;
if (clear)
memset(b_data, 0, PAGE_SIZE);
- if (bh->b_data == b_data + PAGE_SIZE && virt_to_bus (bh->b_data) == virt_to_bus (b_data) + PAGE_SIZE) {
+ if (bh->b_data == b_data + PAGE_SIZE) {
bh->b_size += PAGE_SIZE;
bh->b_data -= PAGE_SIZE;
if (full)
atomic_add(PAGE_SIZE, &bh->b_count);
continue;
}
- if (b_data == bh->b_data + bh->b_size && virt_to_bus (b_data) == virt_to_bus (bh->b_data) + bh->b_size) {
+ if (b_data == bh->b_data + bh->b_size) {
bh->b_size += PAGE_SIZE;
if (full)
atomic_add(PAGE_SIZE, &bh->b_count);
@@ -2851,7 +2854,7 @@ static void idetape_add_stage_tail (ide_drive_t *drive,idetape_stage_t *stage)
/*
* Initialize the OnStream AUX
*/
-static void idetape_init_stage(ide_drive_t *drive, idetape_stage_t *stage, int frame_type, int logical_blk_num)
+static void idetape_init_stage (ide_drive_t *drive, idetape_stage_t *stage, int frame_type, int logical_blk_num)
{
idetape_tape_t *tape = drive->driver_data;
os_aux_t *aux = stage->aux;
@@ -2965,7 +2968,7 @@ static ide_startstop_t idetape_read_position_callback (ide_drive_t *drive)
} else {
#if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 2)
- printk (KERN_INFO "ide-tape: Block Location - %lu\n", ntohl (result->first_block));
+ printk (KERN_INFO "ide-tape: Block Location - %u\n", ntohl (result->first_block));
#endif /* IDETAPE_DEBUG_LOG */
tape->partition = result->partition;
tape->first_frame_position = ntohl (result->first_block);
@@ -3358,7 +3361,7 @@ static void idetape_onstream_write_error_recovery (ide_drive_t *drive)
unsigned int block;
if (tape->onstream_write_error == 1) {
- printk(KERN_ERR "ide-tape: %s: detected physical bad block at %lu\n", tape->name, ntohl(tape->sense.information));
+ printk(KERN_ERR "ide-tape: %s: detected physical bad block at %u\n", tape->name, ntohl(tape->sense.information));
block = ntohl(tape->sense.information) + 80;
idetape_update_stats(drive);
printk(KERN_ERR "ide-tape: %s: relocating %d buffered logical blocks to physical block %u\n", tape->name, tape->cur_frames, block);
@@ -3490,7 +3493,7 @@ static int idetape_verify_stage (ide_drive_t *drive, idetape_stage_t *stage, int
return 0;
}
if (ntohl(aux->format_id) != 0) {
- printk(KERN_INFO "ide-tape: %s: skipping frame, format_id %lu\n", tape->name, ntohl(aux->format_id));
+ printk(KERN_INFO "ide-tape: %s: skipping frame, format_id %u\n", tape->name, ntohl(aux->format_id));
return 0;
}
if (memcmp(aux->application_sig, tape->application_sig, 4) != 0) {
@@ -3514,7 +3517,7 @@ static int idetape_verify_stage (ide_drive_t *drive, idetape_stage_t *stage, int
return 0;
}
if (ntohs(par->wrt_pass_cntr) != tape->wrt_pass_cntr) {
- printk(KERN_INFO "ide-tape: %s: skipping frame, wrt_pass_cntr %d (expected %d)(logical_blk_num %lu)\n", tape->name, ntohs(par->wrt_pass_cntr), tape->wrt_pass_cntr, ntohl(aux->logical_blk_num));
+ printk(KERN_INFO "ide-tape: %s: skipping frame, wrt_pass_cntr %d (expected %d)(logical_blk_num %u)\n", tape->name, ntohs(par->wrt_pass_cntr), tape->wrt_pass_cntr, ntohl(aux->logical_blk_num));
return 0;
}
if (aux->frame_seq_num != aux->logical_blk_num) {
@@ -3523,7 +3526,7 @@ static int idetape_verify_stage (ide_drive_t *drive, idetape_stage_t *stage, int
}
if (logical_blk_num != -1 && ntohl(aux->logical_blk_num) != logical_blk_num) {
if (!quiet)
- printk(KERN_INFO "ide-tape: %s: skipping frame, logical_blk_num %lu (expected %d)\n", tape->name, ntohl(aux->logical_blk_num), logical_blk_num);
+ printk(KERN_INFO "ide-tape: %s: skipping frame, logical_blk_num %u (expected %d)\n", tape->name, ntohl(aux->logical_blk_num), logical_blk_num);
return 0;
}
if (aux->frame_type == OS_FRAME_TYPE_MARKER) {
@@ -4492,7 +4495,8 @@ static void __idetape_write_header (ide_drive_t *drive, int block, int cnt)
idetape_position_tape(drive, block, 0, 0);
memset(&header, 0, sizeof(header));
strcpy(header.ident_str, "ADR_SEQ");
- header.major_rev = header.minor_rev = 2;
+ header.major_rev = 1;
+ header.minor_rev = 2;
header.par_num = 1;
header.partition.partition_num = OS_DATA_PARTITION;
header.partition.par_desc_ver = OS_PARTITION_VERSION;
@@ -5113,7 +5117,11 @@ static int idetape_analyze_headers (ide_drive_t *drive)
for (block = 5; block < 10; block++)
if (__idetape_analyze_headers(drive, block))
goto ok;
+#if 0
+ for (block = 0xbae; block < 0xbb8; block++)
+#else
for (block = 0xbae; block < 0xbb3; block++)
+#endif
if (__idetape_analyze_headers(drive, block))
goto ok;
printk(KERN_ERR "ide-tape: %s: failed to find valid ADRL header\n", tape->name);
@@ -5866,8 +5874,7 @@ int idetape_init (void)
ide_register_module (&idetape_module);
MOD_DEC_USE_COUNT;
#if ONSTREAM_DEBUG
- if (tape->debug_level >= 6)
- printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_init\n");
+ printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_init\n");
#endif
return 0;
}
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index 873f57cc9..396369651 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -655,14 +655,17 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
static void pre_reset (ide_drive_t *drive)
{
+ if (drive->driver != NULL)
+ DRIVER(drive)->pre_reset(drive);
+
if (!drive->keep_settings) {
- drive->unmask = 0;
- drive->io_32bit = 0;
- if (drive->using_dma)
+ if (drive->using_dma) {
(void) HWIF(drive)->dmaproc(ide_dma_off, drive);
+ } else {
+ drive->unmask = 0;
+ drive->io_32bit = 0;
+ }
}
- if (drive->driver != NULL)
- DRIVER(drive)->pre_reset(drive);
}
/*
@@ -901,7 +904,7 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat)
try_to_flush_leftover_data(drive);
}
if (GET_STAT() & (BUSY_STAT|DRQ_STAT))
- rq->errors |= ERROR_RESET; /* Mmmm.. timing problem */
+ OUT_BYTE(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); /* force an abort */
if (rq->errors >= ERROR_MAX) {
if (drive->driver != NULL)
@@ -1825,7 +1828,7 @@ static void ide_init_module (int type)
revalidate_drives();
#ifdef CONFIG_KMOD
if (!found && type == IDE_PROBE_MODULE)
- (void) request_module("ide-probe");
+ (void) request_module("ide-probe-mod");
#endif /* CONFIG_KMOD */
}
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index a54f40e00..731a2aece 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -118,11 +118,6 @@ int * max_readahead[MAX_BLKDEV] = { NULL, NULL, };
*/
int * max_sectors[MAX_BLKDEV] = { NULL, NULL, };
-/*
- * Max number of segments per request
- */
-int * max_segments[MAX_BLKDEV] = { NULL, NULL, };
-
static inline int get_max_sectors(kdev_t dev)
{
if (!max_sectors[MAJOR(dev)])
@@ -130,13 +125,6 @@ static inline int get_max_sectors(kdev_t dev)
return max_sectors[MAJOR(dev)][MINOR(dev)];
}
-static inline int get_max_segments(kdev_t dev)
-{
- if (!max_segments[MAJOR(dev)])
- return MAX_SEGMENTS;
- return max_segments[MAJOR(dev)][MINOR(dev)];
-}
-
/*
* Is called with the request spinlock aquired.
* NOTE: the device-specific queue() functions
@@ -167,24 +155,52 @@ void blk_queue_pluggable(request_queue_t * q, int use_plug)
q->use_plug = use_plug;
}
+static int ll_merge_fn(request_queue_t *q, struct request *req,
+ struct buffer_head *bh)
+{
+ if (req->bhtail->b_data + req->bhtail->b_size != bh->b_data) {
+ if (req->nr_segments < MAX_SEGMENTS) {
+ req->nr_segments++;
+ return 1;
+ }
+ return 0;
+ }
+ return 1;
+}
+
+static int ll_merge_requests_fn(request_queue_t *q, struct request *req,
+ struct request *next)
+{
+ int total_segments = req->nr_segments + next->nr_segments;
+
+ if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data)
+ total_segments--;
+
+ if (total_segments > MAX_SEGMENTS)
+ return 0;
+
+ req->nr_segments = total_segments;
+ return 1;
+}
+
void blk_init_queue(request_queue_t * q, request_fn_proc * rfn)
{
- q->request_fn = rfn;
- q->current_request = NULL;
- q->merge_fn = NULL;
- q->merge_requests_fn = NULL;
- q->plug_tq.sync = 0;
- q->plug_tq.routine = &unplug_device;
- q->plug_tq.data = q;
- q->plugged = 0;
+ q->request_fn = rfn;
+ q->current_request = NULL;
+ q->merge_fn = ll_merge_fn;
+ q->merge_requests_fn = ll_merge_requests_fn;
+ q->plug_tq.sync = 0;
+ q->plug_tq.routine = unplug_device;
+ q->plug_tq.data = q;
+ q->plugged = 0;
/*
* These booleans describe the queue properties. We set the
* default (and most common) values here. Other drivers can
* use the appropriate functions to alter the queue properties.
* as appropriate.
*/
- q->use_plug = 1;
- q->head_active = 1;
+ q->use_plug = 1;
+ q->head_active = 1;
}
/*
@@ -427,11 +443,9 @@ out:
*/
static inline void attempt_merge (request_queue_t * q,
struct request *req,
- int max_sectors,
- int max_segments)
+ int max_sectors)
{
struct request *next = req->next;
- int total_segments;
if (!next)
return;
@@ -439,29 +453,15 @@ static inline void attempt_merge (request_queue_t * q,
return;
if (next->sem || req->cmd != next->cmd || req->rq_dev != next->rq_dev || req->nr_sectors + next->nr_sectors > max_sectors)
return;
- total_segments = req->nr_segments + next->nr_segments;
- if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data)
- total_segments--;
- if (total_segments > max_segments)
- return;
- if( q->merge_requests_fn != NULL )
- {
- /*
- * If we are not allowed to merge these requests, then
- * return. If we are allowed to merge, then the count
- * will have been updated to the appropriate number,
- * and we shouldn't do it here too.
- */
- if( !(q->merge_requests_fn)(q, req, next) )
- {
- return;
- }
- }
- else
- {
- req->nr_segments = total_segments;
- }
+ /*
+ * If we are not allowed to merge these requests, then
+ * return. If we are allowed to merge, then the count
+ * will have been updated to the appropriate number,
+ * and we shouldn't do it here too.
+ */
+ if(!(q->merge_requests_fn)(q, req, next))
+ return;
req->bhtail->b_reqnext = next->bh;
req->bhtail = next->bhtail;
@@ -478,7 +478,7 @@ static void __make_request(request_queue_t * q,
{
unsigned int sector, count;
struct request * req;
- int rw_ahead, max_req, max_sectors, max_segments;
+ int rw_ahead, max_req, max_sectors;
unsigned long flags;
count = bh->b_size >> 9;
@@ -570,7 +570,6 @@ static void __make_request(request_queue_t * q,
* Try to coalesce the new request with old requests
*/
max_sectors = get_max_sectors(bh->b_rdev);
- max_segments = get_max_segments(bh->b_rdev);
/*
* Now we acquire the request spinlock, we have to be mega careful
@@ -584,162 +583,88 @@ static void __make_request(request_queue_t * q,
major != DDV_MAJOR && major != NBD_MAJOR
&& q->use_plug)
plug_device(q); /* is atomic */
- } else switch (major) {
- /*
- * FIXME(eric) - this entire switch statement is going away
- * soon, and we will instead key off of q->head_active to decide
- * whether the top request in the queue is active on the device
- * or not.
- */
- case IDE0_MAJOR: /* same as HD_MAJOR */
- case IDE1_MAJOR:
- case FLOPPY_MAJOR:
- case IDE2_MAJOR:
- case IDE3_MAJOR:
- case IDE4_MAJOR:
- case IDE5_MAJOR:
- case IDE6_MAJOR:
- case IDE7_MAJOR:
- case IDE8_MAJOR:
- case IDE9_MAJOR:
- case ACSI_MAJOR:
- case MFM_ACORN_MAJOR:
+ goto get_rq;
+ }
+
+ if (q->head_active && !q->plugged) {
/*
* The scsi disk and cdrom drivers completely remove the request
* from the queue when they start processing an entry. For this
- * reason it is safe to continue to add links to the top entry for
- * those devices.
+ * reason it is safe to continue to add links to the top entry
+ * for those devices.
*
* All other drivers need to jump over the first entry, as that
- * entry may be busy being processed and we thus can't change it.
+ * entry may be busy being processed and we thus can't change
+ * it.
*/
- if (req == q->current_request)
- req = req->next;
- if (!req)
- break;
- /* fall through */
-
- case SCSI_DISK0_MAJOR:
- case SCSI_DISK1_MAJOR:
- case SCSI_DISK2_MAJOR:
- case SCSI_DISK3_MAJOR:
- case SCSI_DISK4_MAJOR:
- case SCSI_DISK5_MAJOR:
- case SCSI_DISK6_MAJOR:
- case SCSI_DISK7_MAJOR:
- case SCSI_CDROM_MAJOR:
- case DAC960_MAJOR+0:
- case DAC960_MAJOR+1:
- case DAC960_MAJOR+2:
- case DAC960_MAJOR+3:
- case DAC960_MAJOR+4:
- case DAC960_MAJOR+5:
- case DAC960_MAJOR+6:
- case DAC960_MAJOR+7:
- case I2O_MAJOR:
- case COMPAQ_SMART2_MAJOR+0:
- case COMPAQ_SMART2_MAJOR+1:
- case COMPAQ_SMART2_MAJOR+2:
- case COMPAQ_SMART2_MAJOR+3:
- case COMPAQ_SMART2_MAJOR+4:
- case COMPAQ_SMART2_MAJOR+5:
- case COMPAQ_SMART2_MAJOR+6:
- case COMPAQ_SMART2_MAJOR+7:
-
- do {
- if (req->sem)
- continue;
- if (req->cmd != rw)
- continue;
- if (req->nr_sectors + count > max_sectors)
- continue;
- if (req->rq_dev != bh->b_rdev)
+ if ((req = req->next) == NULL)
+ goto get_rq;
+ }
+
+ do {
+ if (req->sem)
+ continue;
+ if (req->cmd != rw)
+ continue;
+ if (req->nr_sectors + count > max_sectors)
+ continue;
+ if (req->rq_dev != bh->b_rdev)
+ continue;
+ /* Can we add it to the end of this request? */
+ if (req->sector + req->nr_sectors == sector) {
+ /*
+ * The merge_fn is a more advanced way
+ * of accomplishing the same task. Instead
+ * of applying a fixed limit of some sort
+ * we instead define a function which can
+ * determine whether or not it is safe to
+ * merge the request or not.
+ *
+ * See if this queue has rules that
+ * may suggest that we shouldn't merge
+ * this
+ */
+ if(!(q->merge_fn)(q, req, bh))
continue;
- /* Can we add it to the end of this request? */
- if (req->sector + req->nr_sectors == sector) {
- /*
- * The merge_fn is a more advanced way
- * of accomplishing the same task. Instead
- * of applying a fixed limit of some sort
- * we instead define a function which can
- * determine whether or not it is safe to
- * merge the request or not.
- */
- if( q->merge_fn == NULL )
- {
- if (req->bhtail->b_data + req->bhtail->b_size
- != bh->b_data) {
- if (req->nr_segments < max_segments)
- req->nr_segments++;
- else continue;
- }
- }
- else
- {
- /*
- * See if this queue has rules that
- * may suggest that we shouldn't merge
- * this
- */
- if( !(q->merge_fn)(q, req, bh) )
- {
- continue;
- }
- }
- req->bhtail->b_reqnext = bh;
- req->bhtail = bh;
- req->nr_sectors += count;
- drive_stat_acct(req, count, 0);
- /* Can we now merge this req with the next? */
- attempt_merge(q, req, max_sectors, max_segments);
- /* or to the beginning? */
- } else if (req->sector - count == sector) {
- /*
- * The merge_fn is a more advanced way
- * of accomplishing the same task. Instead
- * of applying a fixed limit of some sort
- * we instead define a function which can
- * determine whether or not it is safe to
- * merge the request or not.
- */
- if( q->merge_fn == NULL )
- {
- if (bh->b_data + bh->b_size
- != req->bh->b_data) {
- if (req->nr_segments < max_segments)
- req->nr_segments++;
- else continue;
- }
- }
- else
- {
- /*
- * See if this queue has rules that
- * may suggest that we shouldn't merge
- * this
- */
- if( !(q->merge_fn)(q, req, bh) )
- {
- continue;
- }
- }
- bh->b_reqnext = req->bh;
- req->bh = bh;
- req->buffer = bh->b_data;
- req->current_nr_sectors = count;
- req->sector = sector;
- req->nr_sectors += count;
- drive_stat_acct(req, count, 0);
- } else
+ req->bhtail->b_reqnext = bh;
+ req->bhtail = bh;
+ req->nr_sectors += count;
+ drive_stat_acct(req, count, 0);
+ /* Can we now merge this req with the next? */
+ attempt_merge(q, req, max_sectors);
+ /* or to the beginning? */
+ } else if (req->sector - count == sector) {
+ /*
+ * The merge_fn is a more advanced way
+ * of accomplishing the same task. Instead
+ * of applying a fixed limit of some sort
+ * we instead define a function which can
+ * determine whether or not it is safe to
+ * merge the request or not.
+ *
+ * See if this queue has rules that
+ * may suggest that we shouldn't merge
+ * this
+ */
+ if(!(q->merge_fn)(q, req, bh))
continue;
+ bh->b_reqnext = req->bh;
+ req->bh = bh;
+ req->buffer = bh->b_data;
+ req->current_nr_sectors = count;
+ req->sector = sector;
+ req->nr_sectors += count;
+ drive_stat_acct(req, count, 0);
+ } else
+ continue;
- spin_unlock_irqrestore(&io_request_lock,flags);
- return;
+ spin_unlock_irqrestore(&io_request_lock,flags);
+ return;
- } while ((req = req->next) != NULL);
- }
+ } while ((req = req->next) != NULL);
/* find an unused request. */
+get_rq:
req = get_request(max_req, bh->b_rdev);
spin_unlock_irqrestore(&io_request_lock,flags);
@@ -758,6 +683,7 @@ static void __make_request(request_queue_t * q,
req->nr_sectors = count;
req->current_nr_sectors = count;
req->nr_segments = 1; /* Always 1 for a new request. */
+ req->nr_hw_segments = 1; /* Always 1 for a new request. */
req->buffer = bh->b_data;
req->sem = NULL;
req->bh = bh;
diff --git a/drivers/block/ns87415.c b/drivers/block/ns87415.c
index 330943531..8b8bb3f60 100644
--- a/drivers/block/ns87415.c
+++ b/drivers/block/ns87415.c
@@ -89,6 +89,7 @@ static int ns87415_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
dma_stat = inb(hwif->dma_base+2);
outb(inb(hwif->dma_base)&~1, hwif->dma_base); /* stop DMA */
outb(inb(hwif->dma_base)|6, hwif->dma_base); /* from ERRATA: clear the INTR & ERROR bits */
+ ide_destroy_dmatable(drive); /* and free any DMA resources */
return (dma_stat & 7) != 4; /* verify good DMA status */
case ide_dma_write:
case ide_dma_read:
diff --git a/drivers/block/paride/Config.in b/drivers/block/paride/Config.in
index 8d4dc1742..28ef310f4 100644
--- a/drivers/block/paride/Config.in
+++ b/drivers/block/paride/Config.in
@@ -1,6 +1,17 @@
#
# PARIDE configuration
#
+
+# PARIDE doesn't need PARPORT, but if PARPORT is configured as a module,
+# PARIDE must also be a module. The bogus CONFIG_PARIDE_PARPORT option
+# controls the choices given to the user ...
+
+if [ "$CONFIG_PARPORT" = "y" -o "$CONFIG_PARPORT" = "n" ]; then
+ define_tristate CONFIG_PARIDE_PARPORT y
+else
+ define_tristate CONFIG_PARIDE_PARPORT m
+fi
+
comment 'Parallel IDE high-level drivers'
dep_tristate ' Parallel port IDE disks' CONFIG_PARIDE_PD $CONFIG_PARIDE
dep_tristate ' Parallel port ATAPI CD-ROMs' CONFIG_PARIDE_PCD $CONFIG_PARIDE
diff --git a/drivers/block/piix.c b/drivers/block/piix.c
index b8ffb5a4b..64cf45853 100644
--- a/drivers/block/piix.c
+++ b/drivers/block/piix.c
@@ -33,11 +33,16 @@
*
* 4a 84|21 hdb|hda
* 4b 84|21 hdd|hdc
- *
- * 00|00 udma 0
- * 01|01 udma 1
- * 10|10 udma 2
- * 11|11 reserved
+ *
+ * ata-33/82371AB
+ * ata-33/82371EB
+ * ata-33/82801AB ata-66/82801AA
+ * 00|00 udma 0 00|00 reserved
+ * 01|01 udma 1 01|01 udma 3
+ * 10|10 udma 2 10|10 udma 4
+ * 11|11 reserved 11|11 reserved
+ *
+ * 54 8421|8421 ata66 drive|ata66 enable
*
* pci_read_config_word(HWIF(drive)->pci_dev, 0x40, &reg40);
* pci_read_config_word(HWIF(drive)->pci_dev, 0x42, &reg42);
@@ -195,71 +200,78 @@ static int piix_config_drive_for_dma (ide_drive_t *drive)
struct pci_dev *dev = hwif->pci_dev;
int sitre;
- short reg4042, reg44, reg48, reg4a;
+ short reg4042, reg44, reg48, reg4a, reg54;
byte speed;
- int u_speed;
byte maslave = hwif->channel ? 0x42 : 0x40;
byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0;
int ultra = ((dev->device == PCI_DEVICE_ID_INTEL_82371AB) ||
- (dev->device == PCI_DEVICE_ID_INTEL_82801AA_1)) ? 1 : 0;
- int ultra66 = (dev->device == PCI_DEVICE_ID_INTEL_82801AB_1) ? 1 : 0;
+ (dev->device == PCI_DEVICE_ID_INTEL_82801AB_1)) ? 1 : 0;
+ int ultra66 = (dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) ? 1 : 0;
int drive_number = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
int a_speed = 2 << (drive_number * 4);
int u_flag = 1 << drive_number;
+ int u_speed = 0;
pci_read_config_word(dev, maslave, &reg4042);
- sitre = (reg4042 & 0x4000) ? 1 : 0;
+ sitre = (reg4042 & 0x4000) ? 1 : 0;
pci_read_config_word(dev, 0x44, &reg44);
pci_read_config_word(dev, 0x48, &reg48);
pci_read_config_word(dev, 0x4a, &reg4a);
+ pci_read_config_word(dev, 0x54, &reg54);
- if (id->dma_ultra && (ultra)) {
- if (!(reg48 & u_flag)) {
- pci_write_config_word(dev, 0x48, reg48|u_flag);
- }
- } else {
- if (reg48 & u_flag) {
- pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
- }
- }
-
- if (((id->dma_ultra & 0x0010) || (id->dma_ultra & 0x0008) || (id->dma_ultra & 0x0004)) && (ultra)) {
+ if ((id->dma_ultra & 0x0010) && (ultra)) {
+ u_speed = 2 << (drive_number * 4);
+ speed = ((udma_66) && (ultra66)) ? XFER_UDMA_4 : XFER_UDMA_2;
+ } else if ((id->dma_ultra & 0x0008) && (ultra)) {
+ u_speed = 1 << (drive_number * 4);
+ speed = ((udma_66) && (ultra66)) ? XFER_UDMA_3 : XFER_UDMA_1;
+ } else if ((id->dma_ultra & 0x0004) && (ultra)) {
u_speed = 2 << (drive_number * 4);
- if (!(reg4a & u_speed)) {
- pci_write_config_word(dev, 0x4a, reg4a|u_speed);
- }
speed = XFER_UDMA_2;
} else if ((id->dma_ultra & 0x0002) && (ultra)) {
u_speed = 1 << (drive_number * 4);
- if (!(reg4a & u_speed)) {
- pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
- pci_write_config_word(dev, 0x4a, reg4a|u_speed);
- }
speed = XFER_UDMA_1;
} else if ((id->dma_ultra & 0x0001) && (ultra)) {
u_speed = 0 << (drive_number * 4);
- if (!(reg4a & u_speed)) {
- pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
- pci_write_config_word(dev, 0x4a, reg4a|u_speed);
- }
speed = XFER_UDMA_0;
} else if (id->dma_mword & 0x0004) {
- if (reg4a & a_speed)
- pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
speed = XFER_MW_DMA_2;
} else if (id->dma_mword & 0x0002) {
- if (reg4a & a_speed)
- pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
speed = XFER_MW_DMA_1;
} else if (id->dma_1word & 0x0004) {
- if (reg4a & a_speed)
- pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
speed = XFER_SW_DMA_2;
} else {
speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
}
+ /*
+ * This is !@#$% ugly and stupid.............
+ * But ugly harware generates ugly code.........
+ */
+ if (speed >= XFER_UDMA_0) {
+ if (!(reg48 & u_flag))
+ pci_write_config_word(dev, 0x48, reg48|u_flag);
+ if (!(reg4a & u_speed)) {
+ pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
+ pci_write_config_word(dev, 0x4a, reg4a|u_speed);
+ }
+ if ((speed > XFER_UDMA_2) && (!(reg54 & u_flag))) {
+ pci_write_config_word(dev, 0x54, reg54|u_flag);
+ } else {
+ pci_write_config_word(dev, 0x54, reg54 & ~u_flag);
+ }
+ }
+
+ if (speed < XFER_UDMA_0) {
+ if (reg48 & u_flag)
+ pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
+ if (reg4a & a_speed)
+ pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
+ if (reg54 & u_flag)
+ pci_write_config_word(dev, 0x54, reg54 & ~u_flag);
+ }
+
piix_tune_drive(drive, piix_dma_2_pio(speed));
(void) ide_config_drive_speed(drive, speed);
@@ -301,11 +313,21 @@ unsigned int __init pci_init_piix (struct pci_dev *dev, const char *name)
return 0;
}
+/*
+ * Sheesh, someone at Intel needs to go read the ATA-4/5 T13 standards.
+ * It does not specify device detection, but channel!!!
+ * You determine later if bit 13 of word93 is set...
+ */
unsigned int __init ata66_piix (ide_hwif_t *hwif)
{
- if (0)
- return 1;
- return 0;
+ byte reg54h = 0, reg55h = 0, ata66 = 0;
+ byte mask = hwif->channel ? 0x0c : 0x03;
+
+ pci_read_config_byte(hwif->pci_dev, 0x54, &reg54h);
+ pci_read_config_byte(hwif->pci_dev, 0x55, &reg55h);
+ ata66 = (reg54h & mask) ? 0 : 1;
+
+ return ata66;
}
void __init ide_init_piix (ide_hwif_t *hwif)
diff --git a/drivers/block/trm290.c b/drivers/block/trm290.c
index 1308c7bd7..4ec1d09c6 100644
--- a/drivers/block/trm290.c
+++ b/drivers/block/trm290.c
@@ -187,7 +187,7 @@ static int trm290_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
if (!(count = ide_build_dmatable(drive, func)))
break; /* try PIO instead of DMA */
trm290_prepare_drive(drive, 1); /* select DMA xfer */
- outl(virt_to_bus(hwif->dmatable)|reading|writing, hwif->dma_base);
+ outl(hwif->dmatable_dma|reading|writing, hwif->dma_base);
drive->waiting_for_dma = 1;
outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */
if (drive->media != ide_disk)
@@ -199,6 +199,7 @@ static int trm290_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
return 0;
case ide_dma_end:
drive->waiting_for_dma = 0;
+ ide_destroy_dmatable(drive); /* purge DMA mappings */
return (inw(hwif->dma_base+2) != 0x00ff);
case ide_dma_test_irq:
return (inw(hwif->dma_base+2) == 0x00ff);
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
index dfd0b0199..e585bb34c 100644
--- a/drivers/block/z2ram.c
+++ b/drivers/block/z2ram.c
@@ -144,7 +144,7 @@ get_chipram( void )
{
chip_count++;
z2ram_map[ z2ram_size ] =
- (u_long)amiga_chip_alloc( Z2RAM_CHUNKSIZE );
+ (u_long)amiga_chip_alloc( Z2RAM_CHUNKSIZE, "z2ram" );
if ( z2ram_map[ z2ram_size ] == 0 )
{
diff --git a/drivers/cdrom/Config.in b/drivers/cdrom/Config.in
index 31210596d..7ffbfb958 100644
--- a/drivers/cdrom/Config.in
+++ b/drivers/cdrom/Config.in
@@ -7,9 +7,9 @@ tristate ' Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support' CONFIG
if [ "$CONFIG_SBPCD" = "y" ]; then
bool ' Matsushita/Panasonic, ... second CDROM controller support' CONFIG_SBPCD2
if [ "$CONFIG_SBPCD2" = "y" ]; then
- bool ' Matsushita/Panasonic, ... third CDROM controller support' CONFIG_SBPCD3
+ bool ' Matsushita/Panasonic, ... third CDROM controller support' CONFIG_SBPCD3
if [ "$CONFIG_SBPCD3" = "y" ]; then
- bool ' Matsushita/Panasonic, ... fourth CDROM controller support' CONFIG_SBPCD4
+ bool ' Matsushita/Panasonic, ... fourth CDROM controller support' CONFIG_SBPCD4
fi
fi
fi
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index f7d15edad..c40e0ae28 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -227,6 +227,7 @@
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
+
#include <asm/fcntl.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
@@ -353,8 +354,6 @@ int register_cdrom(struct cdrom_device_info *cdi)
cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);
cdi->next = topCdromPtr;
topCdromPtr = cdi;
- /*FIXME:as soon as we'll switch to real thing, pass device number here*/
- register_disk(NULL, cdi->dev, 1, &cdrom_fops, 0);
return 0;
}
#undef ENSURE
@@ -382,7 +381,6 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
prev->next = cdi->next;
else
topCdromPtr = cdi->next;
-/* unregister_disk(); */
cdi->ops->n_minors--;
cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name);
return 0;
@@ -407,12 +405,10 @@ struct cdrom_device_info *cdrom_find_device(kdev_t dev)
while (cdi != NULL && cdi->dev != cd_dev)
cdi = cdi->next;
}
-
+
return cdi;
}
-static int cdrom_setup_writemode(struct cdrom_device_info *cdi);
-
/* We use the open-option O_NONBLOCK to indicate that the
* purpose of opening is only for subsequent ioctl() calls; no device
* integrity checks are performed.
@@ -446,9 +442,6 @@ int cdrom_open(struct inode *ip, struct file *fp)
if (!ret) cdi->use_count++;
- if (fp->f_mode & FMODE_WRITE && !cdi->write.writeable)
- cdi->write.writeable = !cdrom_setup_writemode(cdi);
-
cdinfo(CD_OPEN, "Use count for \"/dev/%s\" now %d\n", cdi->name, cdi->use_count);
/* Do this on open. Don't wait for mount, because they might
not be mounting, but opening with O_NONBLOCK */
@@ -2095,8 +2088,8 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
return -ENOTTY;
}
-static int cdrom_get_track_info(kdev_t dev, __u16 track, __u8 type,
- track_information *ti)
+int cdrom_get_track_info(kdev_t dev, __u16 track, __u8 type,
+ track_information *ti)
{
struct cdrom_device_info *cdi = cdrom_find_device(dev);
struct cdrom_device_ops *cdo = cdi->ops;
@@ -2118,7 +2111,7 @@ static int cdrom_get_track_info(kdev_t dev, __u16 track, __u8 type,
return cdo->generic_packet(cdi, &cgc);
}
-static int cdrom_get_disc_info(kdev_t dev, disc_information *di)
+int cdrom_get_disc_info(kdev_t dev, disc_information *di)
{
struct cdrom_device_info *cdi = cdrom_find_device(dev);
struct cdrom_device_ops *cdo = cdi->ops;
@@ -2230,98 +2223,8 @@ use_last_written:
}
}
-/* return the buffer size of writeable drives */
-static int cdrom_read_buffer_capacity(struct cdrom_device_info *cdi)
-{
- struct cdrom_device_ops *cdo = cdi->ops;
- struct cdrom_generic_command cgc;
- struct {
- unsigned int pad;
- unsigned int buffer_size;
- unsigned int buffer_free;
- } buf;
- int ret;
-
- init_cdrom_command(&cgc, &buf, 12);
- cgc.cmd[0] = 0x5c;
- cgc.cmd[8] = 12;
-
- if ((ret = cdo->generic_packet(cdi, &cgc)))
- return ret;
-
- return be32_to_cpu(buf.buffer_size);
-}
-
-/* return 0 if succesful and the disc can be considered writeable. */
-static int cdrom_setup_writemode(struct cdrom_device_info *cdi)
-{
- struct cdrom_generic_command cgc;
- write_param_page wp;
- disc_information di;
- track_information ti;
- int ret, last_track;
-
- memset(&di, 0, sizeof(disc_information));
- memset(&ti, 0, sizeof(track_information));
- memset(&cdi->write, 0, sizeof(struct cdrom_write_settings));
-
- if ((ret = cdrom_get_disc_info(cdi->dev, &di)))
- return ret;
-
- last_track = (di.last_track_msb << 8) | di.last_track_lsb;
- if ((ret = cdrom_get_track_info(cdi->dev, last_track, 1, &ti)))
- return ret;
-
- /* if the media is erasable, then it is either CD-RW or
- * DVD-RW - use fixed packets for those. non-erasable media
- * indicated CD-R or DVD-R media, use varible sized packets for
- * those (where the packet size is a bit less than the buffer
- * capacity of the drive. */
- if (di.erasable) {
- cdi->write.fpacket = 1;
- /* FIXME: DVD-RW is 16, should get the packet size instead */
- cdi->write.packet_size = 32;
- } else {
- int buf_size;
- cdi->write.fpacket = 0;
- buf_size = cdrom_read_buffer_capacity(cdi);
- buf_size -= 100*1024;
- cdi->write.packet_size = buf_size / CD_FRAMESIZE;
- }
-
- init_cdrom_command(&cgc, &wp, 0x3c);
- if ((ret = cdrom_mode_sense(cdi, &cgc, GPMODE_WRITE_PARMS_PAGE, 0)))
- return ret;
-
- /* sanity checks */
- if ((ti.damage && !ti.nwa_v) || ti.blank) {
- cdinfo(CD_WARNING, "can't write to this disc\n");
- return 1;
- }
-
- /* NWA is only for CD-R and DVD-R. -RW media is randomly
- * writeable once it has been formatted. */
- cdi->write.nwa = ti.nwa_v ? be32_to_cpu(ti.next_writable) : 0;
-
- wp.fp = cdi->write.fpacket ? 1 : 0;
- wp.track_mode = 0;
- wp.write_type = 0;
- wp.data_block_type = 8;
- wp.session_format = 0;
- wp.multi_session = 3;
- wp.audio_pause = cpu_to_be16(0x96);
- wp.packet_size = cdi->write.fpacket ? cpu_to_be32(cdi->write.packet_size) : 0;
- wp.track_mode = 5; /* should be ok with both CD and DVD */
-
- if ((ret = cdrom_mode_select(cdi, &cgc)))
- return ret;
-
- cdinfo(CD_WARNING, "%s: writeable with %lu block %s packets\n",
- cdi->name, cdi->write.packet_size,
- cdi->write.fpacket ? "fixed" : "variable");
- return 0;
-}
-
+EXPORT_SYMBOL(cdrom_get_disc_info);
+EXPORT_SYMBOL(cdrom_get_track_info);
EXPORT_SYMBOL(cdrom_get_next_writable);
EXPORT_SYMBOL(cdrom_get_last_written);
EXPORT_SYMBOL(cdrom_count_tracks);
diff --git a/drivers/char/Config.in b/drivers/char/Config.in
index 140cc583d..42cbaab55 100644
--- a/drivers/char/Config.in
+++ b/drivers/char/Config.in
@@ -33,8 +33,8 @@ if [ "$CONFIG_SERIAL_NONSTANDARD" = "y" ]; then
tristate ' Digiboard PC/Xx Support' CONFIG_DIGI
fi
tristate ' Hayes ESP serial port support' CONFIG_ESPSERIAL
- tristate 'Moxa Intellio support' CONFIG_MOXA_INTELLIO
- tristate 'Moxa SmartIO support' CONFIG_MOXA_SMARTIO
+ tristate ' Moxa Intellio support' CONFIG_MOXA_INTELLIO
+ tristate ' Moxa SmartIO support' CONFIG_MOXA_SMARTIO
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
dep_tristate ' Multi-Tech multiport card support (EXPERIMENTAL)' CONFIG_ISI m
fi
@@ -115,6 +115,7 @@ if [ "$CONFIG_WATCHDOG" != "n" ]; then
tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG
tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT
+ tristate ' Mixcom Watchdog' CONFIG_MIXCOMWD
fi
endmenu
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index a25eda6fd..de8ee6761 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -20,8 +20,8 @@ FONTMAPFILE = cp437.uni
O_TARGET := char.o
M_OBJS :=
-O_OBJS := tty_io.o n_tty.o tty_ioctl.o mem.o random.o raw.o
-OX_OBJS := pty.o misc.o
+O_OBJS := tty_io.o n_tty.o tty_ioctl.o mem.o raw.o
+OX_OBJS := pty.o misc.o random.o
KEYMAP =defkeymap.o
KEYBD =pc_keyb.o
@@ -29,8 +29,8 @@ CONSOLE =console.o
SERIAL =serial.o
ifeq ($(ARCH),m68k)
- KEYMAP =
KEYBD =
+ SERIAL =
endif
ifeq ($(ARCH),arm)
@@ -325,6 +325,14 @@ else
endif
endif
+ifeq ($(CONFIG_MIXCOMWD),y)
+O_OBJS += mixcomwd.o
+else
+ ifeq ($(CONFIG_MIXCOMWD),m)
+ M_OBJS += mixcomwd.o
+ endif
+endif
+
ifeq ($(CONFIG_AMIGAMOUSE),y)
O_OBJS += amigamouse.o
else
diff --git a/drivers/char/console.c b/drivers/char/console.c
index 090f1066c..85c638ef2 100644
--- a/drivers/char/console.c
+++ b/drivers/char/console.c
@@ -92,7 +92,7 @@
#include <linux/version.h>
#include <linux/tqueue.h>
#include <linux/bootmem.h>
-#include <linux/acpi.h>
+#include <linux/pm.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -205,10 +205,8 @@ int (*console_blank_hook)(int) = NULL;
#define DO_UPDATE IS_VISIBLE
#endif
-static int acpi_con_transition(struct acpi_dev *dev, acpi_dstate_t state);
-static struct acpi_dev_info acpi_con_info
- = {ACPI_SYS_DEV, ACPI_VGA_HID, acpi_con_transition};
-static struct acpi_dev *acpi_con = NULL;
+static int pm_con_request(struct pm_dev *dev, pm_request_t rqst, void *data);
+static struct pm_dev *pm_con = NULL;
static inline unsigned short *screenpos(int currcons, int offset, int viewed)
{
@@ -664,8 +662,11 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
kmalloced = 1;
vc_init(currcons, video_num_lines, video_num_columns, 1);
- if (!acpi_con)
- acpi_con = acpi_register(&acpi_con_info, 0);
+ if (!pm_con) {
+ pm_con = pm_register(PM_SYS_DEV,
+ PM_SYS_VGA,
+ pm_con_request);
+ }
}
return 0;
}
@@ -2003,7 +2004,7 @@ void vt_console_print(struct console *co, const char * b, unsigned count)
if (!printable || test_and_set_bit(0, &printing))
return;
- acpi_access(acpi_con);
+ pm_access(pm_con);
if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
currcons = kmsg_redirect - 1;
@@ -2162,7 +2163,7 @@ static int con_write(struct tty_struct * tty, int from_user,
{
int retval;
- acpi_access(acpi_con);
+ pm_access(pm_con);
retval = do_con_write(tty, from_user, buf, count);
con_flush_chars(tty);
@@ -2171,7 +2172,7 @@ static int con_write(struct tty_struct * tty, int from_user,
static void con_put_char(struct tty_struct *tty, unsigned char ch)
{
- acpi_access(acpi_con);
+ pm_access(pm_con);
do_con_write(tty, 0, &ch, 1);
}
@@ -2237,7 +2238,7 @@ static void con_flush_chars(struct tty_struct *tty)
{
struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
- acpi_access(acpi_con);
+ pm_access(pm_con);
set_cursor(vt->vc_num);
}
@@ -2820,16 +2821,14 @@ void vcs_scr_writew(int currcons, u16 val, u16 *org)
}
}
-static int acpi_con_transition(struct acpi_dev *dev, acpi_dstate_t state)
+static int pm_con_request(struct pm_dev *dev, pm_request_t rqst, void *data)
{
- switch (state)
+ switch (rqst)
{
- case ACPI_D0:
+ case PM_RESUME:
unblank_screen();
break;
- case ACPI_D1:
- case ACPI_D2:
- case ACPI_D3:
+ case PM_SUSPEND:
do_blank_screen(0);
break;
}
@@ -2847,6 +2846,7 @@ EXPORT_SYMBOL(default_blu);
EXPORT_SYMBOL(video_font_height);
EXPORT_SYMBOL(video_scan_lines);
EXPORT_SYMBOL(vc_resize);
+EXPORT_SYMBOL(fg_console);
#ifndef VT_SINGLE_DRIVER
EXPORT_SYMBOL(take_over_console);
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index 8b241bde4..892f4df0f 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -47,13 +47,8 @@
#include <linux/modversions.h>
#endif
-#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
-#else
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#endif
#define KERNEL
#include <linux/types.h>
@@ -66,7 +61,7 @@
#include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */
#include <asm/uaccess.h> /* for get_user, etc. */
#include <linux/wait.h> /* for wait_queue */
-#include <linux/init.h> /* for __init */
+#include <linux/init.h> /* for __init, module_{init,exit} */
#include <linux/poll.h> /* for POLLIN, etc. */
#include <linux/dtlk.h> /* local header file for DoubleTalk values */
@@ -364,7 +359,7 @@ static int dtlk_release(struct inode *inode, struct file *file)
return 0;
}
-int __init dtlk_init(void)
+static int __init dtlk_init(void)
{
dtlk_port_lpc = 0;
dtlk_port_tts = 0;
@@ -385,13 +380,7 @@ int __init dtlk_init(void)
return 0;
}
-#ifdef MODULE
-int init_module(void)
-{
- return dtlk_init();
-}
-
-void cleanup_module(void)
+static void __exit dtlk_cleanup (void)
{
dtlk_write_bytes("goodbye", 8);
current->state = TASK_INTERRUPTIBLE;
@@ -405,7 +394,8 @@ void cleanup_module(void)
release_region(dtlk_port_lpc, DTLK_IO_EXTENT);
}
-#endif
+module_init(dtlk_init);
+module_exit(dtlk_cleanup);
/* ------------------------------------------------------------------------ */
diff --git a/drivers/char/ftape/Config.in b/drivers/char/ftape/Config.in
index 817bf5cd2..179f5ba07 100644
--- a/drivers/char/ftape/Config.in
+++ b/drivers/char/ftape/Config.in
@@ -34,5 +34,9 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
int ' Default FIFO threshold (EXPERIMENTAL)' CONFIG_FT_FDC_THR 8
int ' Maximal data rate to use (EXPERIMENTAL)' CONFIG_FT_FDC_MAX_RATE 2000
fi
-comment 'ONLY for DEC Alpha architectures'
-int ' CPU clock frequency of your DEC Alpha' CONFIG_FT_ALPHA_CLOCK 0
+
+if [ "$ARCH" = "alpha" ]; then
+ int ' CPU clock frequency of your DEC Alpha' CONFIG_FT_ALPHA_CLOCK 0
+else
+ define_int CONFIG_FT_ALPHA_CLOCK 0
+fi
diff --git a/drivers/char/h8.c b/drivers/char/h8.c
index 8e33b7d51..99b157833 100644
--- a/drivers/char/h8.c
+++ b/drivers/char/h8.c
@@ -19,7 +19,6 @@
#include <linux/stddef.h>
#include <linux/timer.h>
#include <linux/fcntl.h>
-#include <linux/malloc.h>
#include <linux/linkage.h>
#include <linux/stat.h>
#include <linux/proc_fs.h>
@@ -27,6 +26,8 @@
#include <linux/lists.h>
#include <linux/ioport.h>
#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/slab.h>
#define __KERNEL_SYSCALLS__
#include <asm/unistd.h>
@@ -294,35 +295,7 @@ static void h8_intr(int irq, void *dev_id, struct pt_regs *regs)
return;
}
-#ifdef MODULE
-
-int init_module(void)
-{
- printk("H8 module at %X(Interrupt %d)\n", h8_base, h8_irq);
- if(request_irq(h8_irq, h8_intr, SA_INTERRUPT, "h8", NULL))
- {
- printk("H8: error: IRQ %d is not free.\n", h8_irq);
- return -EIO;
- }
-
- misc_register(&h8_device);
- request_region(h8_base, 8, "h8");
-
- create_proc_info_entry("driver/h8", 0, NULL, h8_get_info);
-
- QUEUE_INIT(&h8_actq, link, h8_cmd_q_t *);
- QUEUE_INIT(&h8_cmdq, link, h8_cmd_q_t *);
- QUEUE_INIT(&h8_freeq, link, h8_cmd_q_t *);
- h8_alloc_queues();
-
- h8_hw_init();
-
- kernel_thread(h8_monitor_thread, NULL, 0);
-
- return 0;
-}
-
-void cleanup_module(void)
+static void __exit h8_cleanup (void)
{
remove_proc_entry("driver/h8", NULL);
misc_deregister(&h8_device);
@@ -330,16 +303,14 @@ void cleanup_module(void)
free_irq(h8_irq, NULL);
}
-#else /* MODULE */
-
-int h8_init(void)
+static int __init h8_init(void)
{
if(request_irq(h8_irq, h8_intr, SA_INTERRUPT, "h8", NULL))
{
- printk("H8: error: IRQ %d is not free\n", h8_irq);
+ printk(KERN_ERR "H8: error: IRQ %d is not free\n", h8_irq);
return -EIO;
}
- printk("H8 at 0x%x IRQ %d\n", h8_base, h8_irq);
+ printk(KERN_INFO "H8 at 0x%x IRQ %d\n", h8_base, h8_irq);
create_proc_info_entry("driver/h8", 0, NULL, h8_get_info);
@@ -357,9 +328,11 @@ int h8_init(void)
return 0;
}
-#endif /* MODULE */
-void h8_hw_init(void)
+module_init(h8_init);
+module_exit(h8_cleanup);
+
+static void __init h8_hw_init(void)
{
u_char buf[H8_MAX_CMD_SIZE];
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 90d95f7ba..0f676eb3b 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -41,7 +41,7 @@
#include <linux/vt_kern.h>
#include <linux/kbd_ll.h>
#include <linux/sysrq.h>
-#include <linux/acpi.h>
+#include <linux/pm.h>
#define SIZE(x) (sizeof(x)/sizeof((x)[0]))
@@ -161,8 +161,7 @@ static int sysrq_pressed;
int sysrq_enabled = 1;
#endif
-static struct acpi_dev_info acpi_kbd_info = {ACPI_SYS_DEV, ACPI_KBC_HID, NULL};
-static struct acpi_dev *acpi_kbd = NULL;
+static struct pm_dev *pm_kbd = NULL;
/*
* Many other routines do put_queue, but I think either
@@ -206,7 +205,7 @@ void handle_scancode(unsigned char scancode, int down)
char up_flag = down ? 0 : 0200;
char raw_mode;
- acpi_access(acpi_kbd);
+ pm_access(pm_kbd);
do_poke_blanked_console = 1;
mark_bh(CONSOLE_BH);
@@ -948,7 +947,7 @@ int __init kbd_init(void)
init_bh(KEYBOARD_BH, kbd_bh);
mark_bh(KEYBOARD_BH);
- acpi_kbd = acpi_register(&acpi_kbd_info, 0);
+ pm_kbd = pm_register(PM_SYS_DEV, PM_SYS_KBC, NULL);
return 0;
}
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 9e9955501..21247facb 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -159,10 +159,12 @@ static inline unsigned long pgprot_noncached(unsigned long prot)
#elif defined(__powerpc__)
prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
#elif defined(__mc68000__)
- if (CPU_IS_020_OR_030)
+ if (MMU_IS_SUN3)
+ prot |= SUN3_PAGE_NOCACHE;
+ else if (MMU_IS_851 || MMU_IS_030)
prot |= _PAGE_NOCACHE030;
/* Use no-cache mode, serialized */
- if (CPU_IS_040_OR_060)
+ else if (MMU_IS_040 || MMU_IS_060)
prot = (prot & _CACHEMASK040) | _PAGE_NOCACHE_S;
#elif defined(__mips__)
prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 217797e77..152720e28 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -67,9 +67,6 @@ extern void gfx_register(void);
#endif
extern void streamable_init(void);
extern void watchdog_init(void);
-extern void wdt_init(void);
-extern void acq_init(void);
-extern void dtlk_init(void);
extern void pcwatchdog_init(void);
extern int rtc_sun_init(void); /* Combines MK48T02 and MK48T08 */
extern int ds1286_init(void);
@@ -195,21 +192,9 @@ int __init misc_init(void)
#ifdef CONFIG_PCWATCHDOG
pcwatchdog_init();
#endif
-#ifdef CONFIG_WDT
- wdt_init();
-#endif
-#ifdef CONFIG_ACQUIRE_WDT
- acq_init();
-#endif
#ifdef CONFIG_SOFT_WATCHDOG
watchdog_init();
#endif
-#ifdef CONFIG_DTLK
- dtlk_init();
-#endif
-#ifdef CONFIG_H8
- h8_init();
-#endif
#ifdef CONFIG_MVME16x
rtc_MK48T08_init();
#endif
diff --git a/drivers/char/mixcomwd.c b/drivers/char/mixcomwd.c
new file mode 100644
index 000000000..1bb5a5b7f
--- /dev/null
+++ b/drivers/char/mixcomwd.c
@@ -0,0 +1,250 @@
+/*
+ * MixCom Watchdog: A Simple Hardware Watchdog Device
+ * Based on Softdog driver by Alan Cox and PC Watchdog driver by Ken Hollis
+ *
+ * Author: Gergely Madarasz <gorgo@itc.hu>
+ *
+ * Copyright (c) 1999 ITConsult-Pro Co. <info@itc.hu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Version 0.1 (99/04/15):
+ * - first version
+ *
+ * Version 0.2 (99/06/16):
+ * - added kernel timer watchdog ping after close
+ * since the hardware does not support watchdog shutdown
+ *
+ * Version 0.3 (99/06/21):
+ * - added WDIOC_GETSTATUS and WDIOC_GETSUPPORT ioctl calls
+ *
+ * Version 0.3.1 (99/06/22):
+ * - allow module removal while internal timer is active,
+ * print warning about probable reset
+ *
+ */
+
+#define VERSION "0.3.1"
+
+#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/ioport.h>
+#include <linux/watchdog.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+static int mixcomwd_ioports[] = { 0x180, 0x280, 0x380, 0x000 };
+
+#define MIXCOM_WATCHDOG_OFFSET 0xc10
+#define MIXCOM_ID1 0x11
+#define MIXCOM_ID2 0x13
+
+static int mixcomwd_opened;
+static int mixcomwd_port;
+
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+static int mixcomwd_timer_alive;
+static struct timer_list mixcomwd_timer;
+#endif
+
+static void mixcomwd_ping(void)
+{
+ outb_p(55,mixcomwd_port+MIXCOM_WATCHDOG_OFFSET);
+ return;
+}
+
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+static void mixcomwd_timerfun(unsigned long d)
+{
+ mixcomwd_ping();
+
+ mod_timer(&mixcomwd_timer,jiffies+ 5*HZ);
+}
+#endif
+
+/*
+ * Allow only one person to hold it open
+ */
+
+static int mixcomwd_open(struct inode *inode, struct file *file)
+{
+ if(test_and_set_bit(0,&mixcomwd_opened)) {
+ return -EBUSY;
+ }
+ mixcomwd_ping();
+
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+ if(mixcomwd_timer_alive) {
+ del_timer(&mixcomwd_timer);
+ mixcomwd_timer_alive=0;
+ }
+#endif
+ MOD_INC_USE_COUNT;
+
+ return 0;
+}
+
+static int mixcomwd_release(struct inode *inode, struct file *file)
+{
+
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+ if(mixcomwd_timer_alive) {
+ printk(KERN_ERR "mixcomwd: release called while internal timer alive");
+ return -EBUSY;
+ }
+ init_timer(&mixcomwd_timer);
+ mixcomwd_timer.expires=jiffies + 5 * HZ;
+ mixcomwd_timer.function=mixcomwd_timerfun;
+ mixcomwd_timer.data=0;
+ mixcomwd_timer_alive=1;
+ add_timer(&mixcomwd_timer);
+#endif
+ MOD_DEC_USE_COUNT;
+
+ clear_bit(0,&mixcomwd_opened);
+ return 0;
+}
+
+
+static ssize_t mixcomwd_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+ if (ppos != &file->f_pos) {
+ return -ESPIPE;
+ }
+
+ if(len)
+ {
+ mixcomwd_ping();
+ return 1;
+ }
+ return 0;
+}
+
+static int mixcomwd_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int status;
+ static struct watchdog_info ident = {
+ WDIOF_KEEPALIVEPING, 1, "MixCOM watchdog"
+ };
+
+ switch(cmd)
+ {
+ case WDIOC_GETSTATUS:
+ status=mixcomwd_opened;
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+ status|=mixcomwd_timer_alive;
+#endif
+ if (copy_to_user((int *)arg, &status, sizeof(int))) {
+ return -EFAULT;
+ }
+ break;
+ case WDIOC_GETSUPPORT:
+ if (copy_to_user((struct watchdog_info *)arg, &ident,
+ sizeof(ident))) {
+ return -EFAULT;
+ }
+ break;
+ case WDIOC_KEEPALIVE:
+ mixcomwd_ping();
+ break;
+ default:
+ return -ENOIOCTLCMD;
+ }
+ return 0;
+}
+
+static struct file_operations mixcomwd_fops=
+{
+ NULL, /* Seek */
+ NULL, /* Read */
+ mixcomwd_write, /* Write */
+ NULL, /* Readdir */
+ NULL, /* Select */
+ mixcomwd_ioctl, /* Ioctl */
+ NULL, /* MMap */
+ mixcomwd_open,
+ NULL, /* flush */
+ mixcomwd_release,
+ NULL,
+ NULL /* Fasync */
+};
+
+static struct miscdevice mixcomwd_miscdev=
+{
+ WATCHDOG_MINOR,
+ "watchdog",
+ &mixcomwd_fops
+};
+
+static int __init mixcomwd_checkcard(int port)
+{
+ int id;
+
+ if(check_region(port,1)) {
+ return 0;
+ }
+
+ id=inb_p(port + MIXCOM_WATCHDOG_OFFSET) & 0x3f;
+ if(id!=MIXCOM_ID1 && id!=MIXCOM_ID2) {
+ return 0;
+ }
+ return 1;
+}
+
+
+void __init mixcomwd_init(void)
+{
+ int i;
+ int found=0;
+
+ for (i = 0; mixcomwd_ioports[i] != 0; i++) {
+ if (mixcomwd_checkcard(mixcomwd_ioports[i])) {
+ found = 1;
+ mixcomwd_port = mixcomwd_ioports[i];
+ break;
+ }
+ }
+
+ if (!found) {
+ printk("mixcomwd: No card detected, or port not available.\n");
+ return;
+ }
+
+ request_region(mixcomwd_port+MIXCOM_WATCHDOG_OFFSET,1,"MixCOM watchdog");
+
+ misc_register(&mixcomwd_miscdev);
+ printk("MixCOM watchdog driver v%s, MixCOM card at 0x%3x\n",VERSION,mixcomwd_port);
+}
+
+#ifdef MODULE
+int init_module(void)
+{
+ mixcomwd_init();
+ return 0;
+}
+
+void cleanup_module(void)
+{
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+ if(mixcomwd_timer_alive) {
+ printk(KERN_WARNING "mixcomwd: I quit now, hardware will"
+ " probably reboot!\n");
+ del_timer(&mixcomwd_timer);
+ mixcomwd_timer_alive=0;
+ }
+#endif
+ release_region(mixcomwd_port+MIXCOM_WATCHDOG_OFFSET,1);
+ misc_deregister(&mixcomwd_miscdev);
+}
+#endif
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 44f01bb77..ca260fede 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -42,7 +42,6 @@
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
-#include <linux/config.h>
#include <linux/major.h>
#include <linux/string.h>
#include <linux/fcntl.h>
diff --git a/drivers/char/pc_keyb.c b/drivers/char/pc_keyb.c
index 5287ec93d..46702f7fd 100644
--- a/drivers/char/pc_keyb.c
+++ b/drivers/char/pc_keyb.c
@@ -412,8 +412,11 @@ static inline void handle_mouse_event(unsigned char scancode)
#endif
}
+static unsigned char kbd_exists = 1;
+
static inline void handle_keyboard_event(unsigned char scancode)
{
+ kbd_exists = 1;
#ifdef CONFIG_VT
if (do_acknowledge(scancode))
handle_scancode(scancode, !(scancode & 0x80));
@@ -482,6 +485,8 @@ static int send_data(unsigned char data)
{
int retries = 3;
+ if (!kbd_exists) return 0;
+
do {
unsigned long timeout = KBD_TIMEOUT;
@@ -497,8 +502,9 @@ static int send_data(unsigned char data)
mdelay(1);
if (!--timeout) {
#ifdef KBD_REPORT_TIMEOUTS
- printk(KERN_WARNING "Keyboard timeout[2]\n");
+ printk(KERN_WARNING "keyboard: Timeout - AT keyboard not present?\n");
#endif
+ kbd_exists = 0;
return 0;
}
}
@@ -506,6 +512,7 @@ static int send_data(unsigned char data)
#ifdef KBD_REPORT_TIMEOUTS
printk(KERN_WARNING "keyboard: Too many NACKs -- noisy kbd cable?\n");
#endif
+ kbd_exists = 0;
return 0;
}
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 31fe71317..3bef6759a 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -235,6 +235,7 @@
#include <linux/utsname.h>
#include <linux/config.h>
+#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/string.h>
@@ -626,7 +627,7 @@ static int batch_entropy_init(int size, struct entropy_store *r)
return 0;
}
-static void batch_entropy_store(__u32 a, __u32 b, int num)
+void batch_entropy_store(u32 a, u32 b, int num)
{
int new;
@@ -2238,3 +2239,12 @@ __u32 check_tcp_syn_cookie(__u32 cookie, __u32 saddr, __u32 daddr, __u16 sport,
return (cookie - tmp[17]) & COOKIEMASK; /* Leaving the data behind */
}
#endif
+
+
+
+EXPORT_SYMBOL(add_keyboard_randomness);
+EXPORT_SYMBOL(add_mouse_randomness);
+EXPORT_SYMBOL(add_interrupt_randomness);
+EXPORT_SYMBOL(add_blkdev_randomness);
+EXPORT_SYMBOL(batch_entropy_store);
+
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index c67f17491..a4fb6b5d2 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -5,8 +5,8 @@
*
* This driver allows use of the real time clock (built into
* nearly all computers) from user space. It exports the /dev/rtc
- * interface supporting various ioctl() and also the /proc/rtc
- * pseudo-file for status information.
+ * interface supporting various ioctl() and also the
+ * /proc/driver/rtc pseudo-file for status information.
*
* The ioctls can be used to set the interrupt behaviour and
* generation rate from the RTC via IRQ 8. Then the /dev/rtc
@@ -56,11 +56,11 @@
#include <linux/miscdevice.h>
#include <linux/ioport.h>
#include <linux/fcntl.h>
-#include <linux/rtc.h>
#include <linux/mc146818rtc.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -82,6 +82,8 @@ static int rtc_irq;
static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
+static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+
static struct timer_list rtc_irq_timer;
static long long rtc_llseek(struct file *file, loff_t offset, int origin);
@@ -104,7 +106,7 @@ static void mask_rtc_irq_bit(unsigned char bit);
static inline unsigned char rtc_is_updating(void);
static int rtc_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data);
+ int count, int *eof, void *data);
/*
* Bits in rtc_status. (6 bits of room for future expansion)
@@ -113,7 +115,7 @@ static int rtc_read_proc(char *page, char **start, off_t off,
#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */
#define RTC_TIMER_ON 0x02 /* missed irq timer active */
-static unsigned char rtc_status = 0; /* bitmapped status byte. */
+static atomic_t rtc_status = ATOMIC_INIT(0); /* bitmapped status byte. */
static unsigned long rtc_freq = 0; /* Current periodic IRQ rate */
static unsigned long rtc_irq_data = 0; /* our output to the world */
@@ -143,12 +145,15 @@ static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* the last read in the remainder of rtc_irq_data.
*/
+ spin_lock (&rtc_lock);
rtc_irq_data += 0x100;
rtc_irq_data &= ~0xff;
rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
+ spin_unlock (&rtc_lock);
+
wake_up_interruptible(&rtc_wait);
- if (rtc_status & RTC_TIMER_ON)
+ if (atomic_read(&rtc_status) & RTC_TIMER_ON)
mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
}
@@ -218,9 +223,10 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case RTC_PIE_OFF: /* Mask periodic int. enab. bit */
{
mask_rtc_irq_bit(RTC_PIE);
- if (rtc_status & RTC_TIMER_ON) {
+ if (atomic_read(&rtc_status) & RTC_TIMER_ON) {
del_timer(&rtc_irq_timer);
- rtc_status &= ~RTC_TIMER_ON;
+ atomic_set(&rtc_status,
+ atomic_read(&rtc_status) & ~RTC_TIMER_ON);
}
return 0;
}
@@ -234,8 +240,9 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if ((rtc_freq > 64) && (!capable(CAP_SYS_RESOURCE)))
return -EACCES;
- if (!(rtc_status & RTC_TIMER_ON)) {
- rtc_status |= RTC_TIMER_ON;
+ if (!(atomic_read(&rtc_status) & RTC_TIMER_ON)) {
+ atomic_set(&rtc_status,
+ atomic_read(&rtc_status) | RTC_TIMER_ON);
rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100;
add_timer(&rtc_irq_timer);
}
@@ -290,8 +297,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (sec >= 60)
sec = 0xff;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&rtc_lock, flags);
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) ||
RTC_ALWAYS_BCD)
{
@@ -302,7 +308,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
CMOS_WRITE(hrs, RTC_HOURS_ALARM);
CMOS_WRITE(min, RTC_MINUTES_ALARM);
CMOS_WRITE(sec, RTC_SECONDS_ALARM);
- restore_flags(flags);
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
@@ -350,8 +356,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if ((yrs -= epoch) > 255) /* They are unsigned */
return -EINVAL;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&rtc_lock, flags);
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
|| RTC_ALWAYS_BCD) {
if (yrs > 169) {
@@ -384,7 +389,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
CMOS_WRITE(save_control, RTC_CONTROL);
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
- restore_flags(flags);
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
case RTC_IRQP_READ: /* Read the periodic IRQ rate. */
@@ -419,12 +424,11 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
rtc_freq = arg;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&rtc_lock, flags);
val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
val |= (16 - tmp);
CMOS_WRITE(val, RTC_FREQ_SELECT);
- restore_flags(flags);
+ spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
#if defined(__alpha__) || defined(__mips__)
@@ -461,13 +465,18 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static int rtc_open(struct inode *inode, struct file *file)
{
- if(rtc_status & RTC_IS_OPEN)
+ unsigned long flags;
+
+ if(atomic_read(&rtc_status) & RTC_IS_OPEN)
return -EBUSY;
MOD_INC_USE_COUNT;
- rtc_status |= RTC_IS_OPEN;
+ atomic_set(&rtc_status, atomic_read(&rtc_status) | RTC_IS_OPEN);
+
+ spin_lock_irqsave (&rtc_lock, flags);
rtc_irq_data = 0;
+ spin_unlock_irqrestore (&rtc_lock, flags);
return 0;
}
@@ -481,32 +490,40 @@ static int rtc_release(struct inode *inode, struct file *file)
unsigned char tmp;
unsigned long flags;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&rtc_lock, flags);
tmp = CMOS_READ(RTC_CONTROL);
tmp &= ~RTC_PIE;
tmp &= ~RTC_AIE;
tmp &= ~RTC_UIE;
CMOS_WRITE(tmp, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS);
- restore_flags(flags);
+ spin_unlock_irqrestore(&rtc_lock, flags);
- if (rtc_status & RTC_TIMER_ON) {
- rtc_status &= ~RTC_TIMER_ON;
+ if (atomic_read(&rtc_status) & RTC_TIMER_ON) {
+ atomic_set(&rtc_status, atomic_read(&rtc_status) & ~RTC_TIMER_ON);
del_timer(&rtc_irq_timer);
}
MOD_DEC_USE_COUNT;
+ spin_lock_irqsave (&rtc_lock, flags);
rtc_irq_data = 0;
- rtc_status &= ~RTC_IS_OPEN;
+ spin_unlock_irqrestore (&rtc_lock, flags);
+ atomic_set(&rtc_status, atomic_read(&rtc_status) & ~RTC_IS_OPEN);
return 0;
}
static unsigned int rtc_poll(struct file *file, poll_table *wait)
{
+ unsigned long l, flags;
+
poll_wait(file, &rtc_wait, wait);
- if (rtc_irq_data != 0)
+
+ spin_lock_irqsave (&rtc_lock, flags);
+ l = rtc_irq_data;
+ spin_unlock_irqrestore (&rtc_lock, flags);
+
+ if (l != 0)
return POLLIN | POLLRDNORM;
return 0;
}
@@ -548,7 +565,6 @@ static int __init rtc_init(void)
struct linux_ebus_device *edev;
#endif
- printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION);
#ifdef __sparc__
for_each_ebus(ebus) {
for_each_ebusdev(edev, ebus) {
@@ -576,20 +592,26 @@ found:
printk("rtc: cannot register IRQ %d\n", rtc_irq);
return -EIO;
}
- misc_register(&rtc_dev);
#else
+ if (check_region (RTC_PORT (0), RTC_IO_EXTENT))
+ {
+ printk(KERN_ERR "rtc: I/O port %d is not free.\n", RTC_PORT (0));
+ return -EIO;
+ }
+
if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL))
{
/* Yeah right, seeing as irq 8 doesn't even hit the bus. */
printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
return -EIO;
}
- misc_register(&rtc_dev);
- create_proc_read_entry ("rtc", 0, NULL, rtc_read_proc, NULL);
- /* Check region? Naaah! Just snarf it up. */
request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
-#endif /* __sparc__ vs. Others */
+#endif /* __sparc__ vs. others */
+
+ misc_register(&rtc_dev);
+ create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL);
+
#if defined(__alpha__) || defined(__mips__)
rtc_freq = HZ;
@@ -601,11 +623,10 @@ found:
while (jiffies - uip_watchdog < 2*HZ/100)
barrier();
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&rtc_lock, flags);
year = CMOS_READ(RTC_YEAR);
ctrl = CMOS_READ(RTC_CONTROL);
- restore_flags(flags);
+ spin_unlock_irqrestore(&rtc_lock, flags);
if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
BCD_TO_BIN(year); /* This should never happen... */
@@ -625,20 +646,25 @@ found:
#endif
init_timer(&rtc_irq_timer);
rtc_irq_timer.function = rtc_dropped_irq;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&rtc_lock, flags);
/* Initialize periodic freq. to CMOS reset default, which is 1024Hz */
CMOS_WRITE(((CMOS_READ(RTC_FREQ_SELECT) & 0xF0) | 0x06), RTC_FREQ_SELECT);
- restore_flags(flags);
+ spin_unlock_irqrestore(&rtc_lock, flags);
rtc_freq = 1024;
+
+ printk(KERN_INFO "Real Time Clock Driver v" RTC_VERSION "\n");
+
return 0;
}
static void __exit rtc_exit (void)
{
- /* interrupts and timer disabled at this point by rtc_release */
+ /* interrupts and maybe timer disabled at this point by rtc_release */
+
+ if (atomic_read(&rtc_status) & RTC_TIMER_ON)
+ del_timer(&rtc_irq_timer);
- remove_proc_entry ("rtc", NULL);
+ remove_proc_entry ("driver/rtc", NULL);
misc_deregister(&rtc_dev);
#ifdef __sparc__
@@ -672,30 +698,30 @@ static void rtc_dropped_irq(unsigned long data)
printk(KERN_INFO "rtc: lost some interrupts at %ldHz.\n", rtc_freq);
mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&rtc_lock, flags);
rtc_irq_data += ((rtc_freq/HZ)<<8);
rtc_irq_data &= ~0xff;
rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); /* restart */
- restore_flags(flags);
+ spin_unlock_irqrestore(&rtc_lock, flags);
}
/*
- * Info exported via "/proc/rtc".
+ * Info exported via "/proc/driver/rtc".
*/
-static int rtc_get_status(char *buf)
+static int rtc_proc_output (char *buf)
{
+#define YN(bit) ((ctrl & bit) ? "yes" : "no")
+#define NY(bit) ((ctrl & bit) ? "no" : "yes")
char *p;
struct rtc_time tm;
unsigned char batt, ctrl;
unsigned long flags;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&rtc_lock, flags);
batt = CMOS_READ(RTC_VALID) & RTC_VRT;
ctrl = CMOS_READ(RTC_CONTROL);
- restore_flags(flags);
+ spin_unlock_irqrestore(&rtc_lock, flags);
p = buf;
@@ -745,23 +771,25 @@ static int rtc_get_status(char *buf)
"periodic_IRQ\t: %s\n"
"periodic_freq\t: %ld\n"
"batt_status\t: %s\n",
- (ctrl & RTC_DST_EN) ? "yes" : "no",
- (ctrl & RTC_DM_BINARY) ? "no" : "yes",
- (ctrl & RTC_24H) ? "yes" : "no",
- (ctrl & RTC_SQWE) ? "yes" : "no",
- (ctrl & RTC_AIE) ? "yes" : "no",
- (ctrl & RTC_UIE) ? "yes" : "no",
- (ctrl & RTC_PIE) ? "yes" : "no",
+ YN(RTC_DST_EN),
+ NY(RTC_DM_BINARY),
+ YN(RTC_24H),
+ YN(RTC_SQWE),
+ YN(RTC_AIE),
+ YN(RTC_UIE),
+ YN(RTC_PIE),
rtc_freq,
batt ? "okay" : "dead");
return p - buf;
+#undef YN
+#undef NY
}
static int rtc_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+ int count, int *eof, void *data)
{
- int len = rtc_get_status(page);
+ int len = rtc_proc_output (page);
if (len <= off+count) *eof = 1;
*start = page + off;
len -= off;
@@ -778,10 +806,9 @@ static inline unsigned char rtc_is_updating(void)
unsigned long flags;
unsigned char uip;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&rtc_lock, flags);
uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
- restore_flags(flags);
+ spin_unlock_irqrestore(&rtc_lock, flags);
return uip;
}
@@ -811,8 +838,7 @@ static void get_rtc_time(struct rtc_time *rtc_tm)
* RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
* by the RTC when initially set to a non-zero value.
*/
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&rtc_lock, flags);
rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
@@ -820,7 +846,7 @@ static void get_rtc_time(struct rtc_time *rtc_tm)
rtc_tm->tm_mon = CMOS_READ(RTC_MONTH);
rtc_tm->tm_year = CMOS_READ(RTC_YEAR);
ctrl = CMOS_READ(RTC_CONTROL);
- restore_flags(flags);
+ spin_unlock_irqrestore(&rtc_lock, flags);
if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
{
@@ -851,13 +877,12 @@ static void get_rtc_alm_time(struct rtc_time *alm_tm)
* Only the values that we read from the RTC are set. That
* means only tm_hour, tm_min, and tm_sec.
*/
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&rtc_lock, flags);
alm_tm->tm_sec = CMOS_READ(RTC_SECONDS_ALARM);
alm_tm->tm_min = CMOS_READ(RTC_MINUTES_ALARM);
alm_tm->tm_hour = CMOS_READ(RTC_HOURS_ALARM);
ctrl = CMOS_READ(RTC_CONTROL);
- restore_flags(flags);
+ spin_unlock_irqrestore(&rtc_lock, flags);
if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
{
@@ -877,19 +902,18 @@ static void get_rtc_alm_time(struct rtc_time *alm_tm)
* meddles with the interrupt enable/disable bits.
*/
-void mask_rtc_irq_bit(unsigned char bit)
+static void mask_rtc_irq_bit(unsigned char bit)
{
unsigned char val;
unsigned long flags;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&rtc_lock, flags);
val = CMOS_READ(RTC_CONTROL);
val &= ~bit;
CMOS_WRITE(val, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS);
- restore_flags(flags);
rtc_irq_data = 0;
+ spin_unlock_irqrestore(&rtc_lock, flags);
}
static void set_rtc_irq_bit(unsigned char bit)
@@ -897,12 +921,11 @@ static void set_rtc_irq_bit(unsigned char bit)
unsigned char val;
unsigned long flags;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&rtc_lock, flags);
val = CMOS_READ(RTC_CONTROL);
val |= bit;
CMOS_WRITE(val, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS);
rtc_irq_data = 0;
- restore_flags(flags);
+ spin_unlock_irqrestore(&rtc_lock, flags);
}
diff --git a/drivers/char/saa5249.c b/drivers/char/saa5249.c
index 58c6f7b83..784ae208a 100644
--- a/drivers/char/saa5249.c
+++ b/drivers/char/saa5249.c
@@ -50,7 +50,7 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <stdarg.h>
-#include <linux/i2c-old.h>
+#include <linux/i2c.h>
#include <linux/videotext.h>
#include <linux/videodev.h>
@@ -101,7 +101,7 @@ struct saa5249_device
int is_searching[NUM_DAUS];
int disp_mode;
int virtual_mode;
- struct i2c_bus *bus;
+ struct i2c_client *client;
};
@@ -109,7 +109,6 @@ struct saa5249_device
#define CCTRD 35
#define NOACK_REPEAT 10 /* Retry access this many times on failure */
#define CLEAR_DELAY (HZ/20) /* Time required to clear a page */
-#define I2C_TIMEOUT (3*HZ) /* open/close/SDA-check timeout */
#define READY_TIMEOUT (30*HZ/1000) /* Time to wait for ready signal of I²C-bus interface */
#define INIT_DELAY 500 /* Time in usec to wait at initialization of CEA interface */
#define START_DELAY 10 /* Time in usec to wait before starting write-cycle (CEA) */
@@ -135,45 +134,60 @@ struct saa5249_device
static struct video_device saa_template; /* Declared near bottom */
-/*
- * We do most of the hard work when we become a device on the i2c.
- */
-
-static int saa5249_attach(struct i2c_device *device)
+/* Addresses to scan */
+static unsigned short normal_i2c[] = {34>>1,I2C_CLIENT_END};
+static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
+static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
+static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
+static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
+static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
+static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
+
+static struct i2c_client_address_data addr_data = {
+ normal_i2c, normal_i2c_range,
+ probe, probe_range,
+ ignore, ignore_range,
+ force
+};
+
+static struct i2c_client client_template;
+
+static int saa5249_attach(struct i2c_adapter *adap, int addr, unsigned short flags, int kind)
{
int pgbuf;
int err;
+ struct i2c_client *client;
struct video_device *vd;
struct saa5249_device *t;
- /* Only attach these chips to the BT848 bus for now */
-
- if(device->bus->id!=I2C_BUSID_BT848)
- return -EINVAL;
-
- strcpy(device->name, IF_NAME);
+
+ printk(KERN_INFO "saa5249: teletext chip found.\n");
+ client=kmalloc(sizeof(*client), GFP_KERNEL);
+ if(client==NULL)
+ return -ENOMEM;
+ client_template.adapter = adap;
+ client_template.addr = addr;
+ memcpy(client, &client_template, sizeof(*client));
+ t = kmalloc(sizeof(*t), GFP_KERNEL);
+ if(t==NULL)
+ {
+ kfree(client);
+ return -ENOMEM;
+ }
+ memset(t, 0, sizeof(*t));
+ strcpy(client->name, IF_NAME);
/*
* Now create a video4linux device
*/
- vd=(struct video_device *)kmalloc(sizeof(struct video_device), GFP_KERNEL);
+ client->data = vd=(struct video_device *)kmalloc(sizeof(struct video_device), GFP_KERNEL);
if(vd==NULL)
- return -ENOMEM;
-
- memcpy(vd, &saa_template, sizeof(*vd));
-
- /*
- * Attach an saa5249 device
- */
-
- t=(struct saa5249_device *)kmalloc(sizeof(struct saa5249_device), GFP_KERNEL);
- if(t==NULL)
{
- kfree(vd);
+ kfree(t);
+ kfree(client);
return -ENOMEM;
}
-
- memset(t, 0, sizeof(*t));
+ memcpy(vd, &saa_template, sizeof(*vd));
for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++)
{
@@ -186,7 +200,6 @@ static int saa5249_attach(struct i2c_device *device)
t->is_searching[pgbuf] = FALSE;
}
vd->priv=t;
- device->data=vd;
/*
* Register it
@@ -196,22 +209,43 @@ static int saa5249_attach(struct i2c_device *device)
{
kfree(t);
kfree(vd);
+ kfree(client);
return err;
}
- t->bus = device->bus;
+ t->client = client;
+ i2c_attach_client(client);
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+/*
+ * We do most of the hard work when we become a device on the i2c.
+ */
+
+static int saa5249_probe(struct i2c_adapter *adap)
+{
+ /* Only attach these chips to the BT848 bus for now */
+
+ if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
+ {
+ return i2c_probe(adap, &addr_data, saa5249_attach);
+ }
return 0;
}
-static int saa5249_detach(struct i2c_device *device)
+static int saa5249_detach(struct i2c_client *client)
{
- struct video_device *vd=device->data;
+ struct video_device *vd=client->data;
+ i2c_detach_client(client);
video_unregister_device(vd);
kfree(vd->priv);
kfree(vd);
+ kfree(client);
+ MOD_DEC_USE_COUNT;
return 0;
}
-static int saa5249_command(struct i2c_device *device,
+static int saa5249_command(struct i2c_client *device,
unsigned int cmd, void *arg)
{
return -EINVAL;
@@ -223,12 +257,21 @@ static struct i2c_driver i2c_driver_videotext =
{
IF_NAME, /* name */
I2C_DRIVERID_VIDEOTEXT, /* in i2c.h */
- 34, 35, /* Addr range */
- saa5249_attach,
+ I2C_DF_NOTIFY,
+ saa5249_probe,
saa5249_detach,
saa5249_command
};
+static struct i2c_client client_template = {
+ "(unset)",
+ -1,
+ 0,
+ 0,
+ NULL,
+ &i2c_driver_videotext
+};
+
/*
* Wait the given number of jiffies (10ms). This calls the scheduler, so the actual
* delay may be longer.
@@ -252,109 +295,46 @@ static void jdelay(unsigned long delay)
}
-/* Send arbitrary number of bytes to I²C-bus. Start & stop handshaking is done by this routine.
- * adr should be address of I²C-device, varargs-list of values to send must be terminated by -1
- * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise
+/*
+ * I2C interfaces
*/
-
-static int i2c_senddata(struct saa5249_device *t, int adr, ...)
+
+static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data)
{
- int val, loop;
- va_list argp;
-
- for (loop = 0; loop <= NOACK_REPEAT; loop++)
- {
- i2c_start(t->bus);
- if (i2c_sendbyte(t->bus, adr, 0) != 0)
- goto loopend;
-
- va_start(argp, adr);
- while ((val = va_arg(argp, int)) != -1)
- {
- if (val < 0 || val > 255)
- {
- printk(KERN_ERR "vtx: internal error in i2c_senddata\n");
- break;
- }
- if (i2c_sendbyte(t->bus, val, 0) != 0)
- goto loopend;
- }
- va_end(argp);
- i2c_stop(t->bus);
+ char buf[64];
+
+ buf[0] = reg;
+ memcpy(buf+1, data, count);
+
+ if(i2c_master_send(t->client, buf, count+1)==count+1)
return 0;
-loopend:
- i2c_stop(t->bus);
- }
- va_end(argp);
return -1;
}
-
-/* Send count number of bytes from buffer buf to I²C-device adr. Start & stop handshaking is
- * done by this routine. If uaccess is TRUE, data is read from user-space with get_user.
- * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise
- */
-
-static int i2c_sendbuf(struct saa5249_device *t, int adr, int reg, int count, u8 *buf, int uaccess)
+static int i2c_senddata(struct saa5249_device *t, ...)
{
- int pos, loop;
- u8 val;
-
- for (loop = 0; loop <= NOACK_REPEAT; loop++)
- {
- i2c_start(t->bus);
- if (i2c_sendbyte(t->bus, adr, 0) != 0 || i2c_sendbyte(t->bus, reg, 0) != 0)
- goto loopend;
- for (pos = 0; pos < count; pos++)
- {
- /* FIXME: FAULT WITH CLI/SPINLOCK ?? */
- if (uaccess)
- get_user(val, buf + pos);
- else
- val = buf[pos];
- if (i2c_sendbyte(t->bus, val, 0) != 0)
- goto loopend;
- RESCHED;
- }
- i2c_stop(t->bus);
- return 0;
-loopend:
- i2c_stop(t->bus);
- }
- return -1;
+ unsigned char buf[64];
+ int v;
+ int ct=0;
+ va_list argp;
+ va_start(argp,t);
+
+ while((v=va_arg(argp,int))!=-1)
+ buf[ct++]=v;
+ return i2c_sendbuf(t, buf[0], ct-1, buf+1);
}
-
/* Get count number of bytes from I²C-device at address adr, store them in buf. Start & stop
* handshaking is done by this routine, ack will be sent after the last byte to inhibit further
* sending of data. If uaccess is TRUE, data is written to user-space with put_user.
* Returns -1 if I²C-device didn't send acknowledge, 0 otherwise
*/
-static int i2c_getdata(struct saa5249_device *t, int adr, int count, u8 *buf, int uaccess)
+static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
{
- int pos, loop, val;
-
- for (loop = 0; loop <= NOACK_REPEAT; loop++)
- {
- i2c_start(t->bus);
- if (i2c_sendbyte(t->bus, adr, 1) != 0)
- goto loopend;
- for (pos = 0; pos < count; pos++)
- {
- val = i2c_readbyte(t->bus, (pos==count-1) ? 1 : 0);
- if (uaccess)
- put_user(val, buf + pos);
- else
- buf[pos] = val;
- RESCHED;
- }
- i2c_stop(t->bus);
- return 0;
-loopend:
- i2c_stop(t->bus);
- }
- return -1;
+ if(i2c_master_recv(t->client, buf, count)!=count)
+ return -1;
+ return 0;
}
@@ -449,41 +429,41 @@ static int saa5249_ioctl(struct video_device *vd, unsigned int cmd, void *arg)
return -EINVAL;
if (!t->vdau[req.pgbuf].stopped)
{
- if (i2c_senddata(t, CCTWR, 2, 0, -1) ||
- i2c_sendbuf(t, CCTWR, 3, sizeof(t->vdau[0].sregs), t->vdau[req.pgbuf].sregs, FALSE) ||
- i2c_senddata(t, CCTWR, 8, 0, 25, 0, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', -1) ||
- i2c_senddata(t, CCTWR, 2, 0, t->vdau[req.pgbuf].sregs[0] | 8, -1) ||
- i2c_senddata(t, CCTWR, 8, 0, 25, 0, -1))
+ if (i2c_senddata(t, 2, 0, -1) ||
+ i2c_sendbuf(t, 3, sizeof(t->vdau[0].sregs), t->vdau[req.pgbuf].sregs) ||
+ i2c_senddata(t, 8, 0, 25, 0, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', -1) ||
+ i2c_senddata(t, 2, 0, t->vdau[req.pgbuf].sregs[0] | 8, -1) ||
+ i2c_senddata(t, 8, 0, 25, 0, -1))
return -EIO;
jdelay(PAGE_WAIT);
- if (i2c_getdata(t, CCTRD, 10, infobits, FALSE))
+ if (i2c_getdata(t, 10, infobits))
return -EIO;
if (!(infobits[8] & 0x10) && !(infobits[7] & 0xf0) && /* check FOUND-bit */
(memcmp(infobits, t->vdau[req.pgbuf].laststat, sizeof(infobits)) ||
time_after_eq(jiffies, t->vdau[req.pgbuf].expire)))
{ /* check if new page arrived */
- if (i2c_senddata(t, CCTWR, 8, 0, 0, 0, -1) ||
- i2c_getdata(t, CCTRD, VTX_PAGESIZE, t->vdau[req.pgbuf].pgbuf, FALSE))
+ if (i2c_senddata(t, 8, 0, 0, 0, -1) ||
+ i2c_getdata(t, VTX_PAGESIZE, t->vdau[req.pgbuf].pgbuf))
return -EIO;
t->vdau[req.pgbuf].expire = jiffies + PGBUF_EXPIRE;
memset(t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE, ' ', VTX_VIRTUALSIZE - VTX_PAGESIZE);
if (t->virtual_mode)
{
/* Packet X/24 */
- if (i2c_senddata(t, CCTWR, 8, 0, 0x20, 0, -1) ||
- i2c_getdata(t, CCTRD, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 20 * 40, FALSE))
+ if (i2c_senddata(t, 8, 0, 0x20, 0, -1) ||
+ i2c_getdata(t, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 20 * 40))
return -EIO;
/* Packet X/27/0 */
- if (i2c_senddata(t, CCTWR, 8, 0, 0x21, 0, -1) ||
- i2c_getdata(t, CCTRD, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 16 * 40, FALSE))
+ if (i2c_senddata(t, 8, 0, 0x21, 0, -1) ||
+ i2c_getdata(t, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 16 * 40))
return -EIO;
/* Packet 8/30/0...8/30/15
* FIXME: AFAIK, the 5249 does hamming-decoding for some bytes in packet 8/30,
* so we should undo this here.
*/
- if (i2c_senddata(t, CCTWR, 8, 0, 0x22, 0, -1) ||
- i2c_getdata(t, CCTRD, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 23 * 40, FALSE))
+ if (i2c_senddata(t, 8, 0, 0x22, 0, -1) ||
+ i2c_getdata(t, 40, t->vdau[req.pgbuf].pgbuf + VTX_PAGESIZE + 23 * 40))
return -EIO;
}
t->vdau[req.pgbuf].clrfound = FALSE;
@@ -554,20 +534,30 @@ static int saa5249_ioctl(struct video_device *vd, unsigned int cmd, void *arg)
if (req.start <= 39 && req.end >= 32)
{
+ int len;
+ char buf[16];
start = MAX(req.start, 32);
end = MIN(req.end, 39);
- if (i2c_senddata(t, CCTWR, 8, 0, 0, start, -1) ||
- i2c_getdata(t, CCTRD, end - start + 1, req.buffer + start - req.start, TRUE))
+ len=end-start+1;
+ if (i2c_senddata(t, 8, 0, 0, start, -1) ||
+ i2c_getdata(t, len, buf))
return -EIO;
+ if(copy_to_user(req.buffer+start-req.start, buf, len))
+ return -EFAULT;
}
/* Insert the current header if DAU is still searching for a page */
if (req.start <= 31 && req.end >= 7 && t->is_searching[req.pgbuf])
{
+ char buf[32];
+ int len;
start = MAX(req.start, 7);
end = MIN(req.end, 31);
- if (i2c_senddata(t, CCTWR, 8, 0, 0, start, -1) ||
- i2c_getdata(t, CCTRD, end - start + 1, req.buffer + start - req.start, TRUE))
+ len=end-start+1;
+ if (i2c_senddata(t, 8, 0, 0, start, -1) ||
+ i2c_getdata(t, len, buf))
return -EIO;
+ if(copy_to_user(req.buffer+start-req.start, buf, len))
+ return -EFAULT;
}
return 0;
}
@@ -592,11 +582,11 @@ static int saa5249_ioctl(struct video_device *vd, unsigned int cmd, void *arg)
case VTXIOCCLRCACHE:
{
- if (i2c_senddata(t ,CCTWR, 0, NUM_DAUS, 0, 8, -1) || i2c_senddata(t, CCTWR, 11,
+ if (i2c_senddata(t, 0, NUM_DAUS, 0, 8, -1) || i2c_senddata(t, 11,
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', -1))
return -EIO;
- if (i2c_senddata(t, CCTWR, 3, 0x20, -1))
+ if (i2c_senddata(t, 3, 0x20, -1))
return -EIO;
jdelay(10 * CLEAR_DELAY); /* I have no idea how long we have to wait here */
return 0;
@@ -618,14 +608,14 @@ static int saa5249_open(struct video_device *vd, int nb)
struct saa5249_device *t=vd->priv;
int pgbuf;
- if (t->bus==NULL)
+ if (t->client==NULL)
return -ENODEV;
- if (i2c_senddata(t, CCTWR, 0, 0, -1) || /* Select R11 */
+ if (i2c_senddata(t, 0, 0, -1) || /* Select R11 */
/* Turn off parity checks (we do this ourselves) */
- i2c_senddata(t, CCTWR, 1, disp_modes[t->disp_mode][0], 0, -1) ||
+ i2c_senddata(t, 1, disp_modes[t->disp_mode][0], 0, -1) ||
/* Display TV-picture, no virtual rows */
- i2c_senddata(t, CCTWR, 4, NUM_DAUS, disp_modes[t->disp_mode][1], disp_modes[t->disp_mode][2], 7, -1)) /* Set display to page 4 */
+ i2c_senddata(t, 4, NUM_DAUS, disp_modes[t->disp_mode][1], disp_modes[t->disp_mode][2], 7, -1)) /* Set display to page 4 */
{
return -EIO;
@@ -651,8 +641,8 @@ static int saa5249_open(struct video_device *vd, int nb)
static void saa5249_release(struct video_device *vd)
{
struct saa5249_device *t=vd->priv;
- i2c_senddata(t, CCTWR, 1, 0x20, -1); /* Turn off CCT */
- i2c_senddata(t, CCTWR, 5, 3, 3, -1); /* Turn off TV-display */
+ i2c_senddata(t, 1, 0x20, -1); /* Turn off CCT */
+ i2c_senddata(t, 5, 3, 3, -1); /* Turn off TV-display */
MOD_DEC_USE_COUNT;
return;
}
@@ -666,12 +656,12 @@ static int __init init_saa_5249 (void)
{
printk(KERN_INFO "SAA5249 driver (" IF_NAME " interface) for VideoText version %d.%d\n",
VTX_VER_MAJ, VTX_VER_MIN);
- return i2c_register_driver(&i2c_driver_videotext);
+ return i2c_add_driver(&i2c_driver_videotext);
}
static void __exit cleanup_saa_5249 (void)
{
- i2c_unregister_driver(&i2c_driver_videotext);
+ i2c_del_driver(&i2c_driver_videotext);
}
module_init(init_saa_5249);
diff --git a/drivers/char/serial.c b/drivers/char/serial.c
index c9c5a890c..4d3a5a8f8 100644
--- a/drivers/char/serial.c
+++ b/drivers/char/serial.c
@@ -46,8 +46,8 @@
* int rs_init(void);
*/
-static char *serial_version = "4.91";
-static char *serial_revdate = "1999-11-17";
+static char *serial_version = "4.92";
+static char *serial_revdate = "2000-1-27";
/*
* Serial driver configuration section. Here are the various options:
@@ -76,12 +76,10 @@ static char *serial_revdate = "1999-11-17";
#include <linux/config.h>
#include <linux/version.h>
-#include <linux/sysrq.h>
#undef SERIAL_PARANOIA_CHECK
#define CONFIG_SERIAL_NOPAUSE_IO
#define SERIAL_DO_RESTART
-#define CONFIG_SERIAL_PCI_MEMMAPPED
#if 0
/* These defines are normally controlled by the autoconf.h */
@@ -102,6 +100,12 @@ static char *serial_revdate = "1999-11-17";
#endif
#endif
+#ifdef CONFIG_ISAPNP
+#ifndef ENABLE_SERIAL_PNP
+#define ENABLE_SERIAL_PNP
+#endif
+#endif
+
/* Set of debugging defines */
#undef SERIAL_DEBUG_INTR
@@ -135,31 +139,13 @@ static char *serial_revdate = "1999-11-17";
#define SERIAL_INLINE
#endif
-#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
-#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
- kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s)
-#else
-#define DBG_CNT(s)
-#endif
-
/*
* End of serial driver configuration section.
*/
-#define NEW_MODULES
-#ifdef LOCAL_HEADERS /* We're building standalone */
-#define MODULE
-#endif
-
-#ifdef NEW_MODULES
#ifdef MODVERSIONS
#include <linux/modversions.h>
#endif
-#else /* !NEW_MODULES */
-#ifdef MODVERSIONS
-#define MODULE
-#endif
-#endif /* NEW_MODULES */
#include <linux/module.h>
#include <linux/types.h>
@@ -200,13 +186,19 @@ static char *serial_revdate = "1999-11-17";
#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 (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */
-#include "serial_compat.h"
+#if defined(LOCAL_HEADERS) || (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */
+#include "serial_compat.h"
#endif
#include <asm/system.h>
@@ -278,7 +270,7 @@ static struct serial_uart_config uart_config[] = {
UART_STARTECH },
{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
{ "Startech", 1, 0}, /* usurped by cyclades.c */
- { "16C950", 128, UART_CLEAR_FIFO | UART_USE_FIFO},
+ { "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 |
@@ -292,16 +284,35 @@ static struct serial_state rs_table[RS_TABLE_SIZE] = {
#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state))
-#ifdef ENABLE_SERIAL_PCI
+#if (defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP))
#define NR_PCI_BOARDS 8
+#ifdef MODULE
+/* We don't unregister PCI boards right now */
static struct pci_board_inst serial_pci_board[NR_PCI_BOARDS];
static int serial_pci_board_idx = 0;
-#ifdef PCI_NUM_RESOURCES
+#endif
+#ifndef PCI_BASE_ADDRESS
#define PCI_BASE_ADDRESS(dev, r) ((dev)->resource[r].start)
-#else
-#define PCI_BASE_ADDRESS(dev, r) ((dev)->base_address[r])
+#define PCI_BASE_REGION_SIZE(dev, r) ((dev)->resource[r].end - \
+ (dev)->resource[r].start)
+#define IS_PCI_REGION_IOPORT(dev, r) ((dev)->resource[r].flags & \
+ IORESOURCE_IO)
#endif
-#endif /* ENABLE_SERIAL_PCI */
+#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)
+#define ACTIVATE_FUNC(dev) (dev->activate)
+#define DEACTIVATE_FUNC(dev) (dev->deactivate)
+#endif
+
static struct tty_struct *serial_table[NR_PORTS];
static struct termios *serial_termios[NR_PORTS];
@@ -311,6 +322,13 @@ static struct termios *serial_termios_locked[NR_PORTS];
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
+#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
+#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
+ kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s)
+#else
+#define DBG_CNT(s)
+#endif
+
/*
* 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,
@@ -357,11 +375,9 @@ static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset)
outb(info->hub6 - 1 + offset, info->port);
return inb(info->port+1);
#endif
-#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
case SERIAL_IO_MEM:
return readb(info->iomem_base +
(offset<<info->iomem_reg_shift));
-#endif
#ifdef CONFIG_SERIAL_GSC
case SERIAL_IO_GSC:
return gsc_readb(info->iomem_base + offset);
@@ -381,12 +397,10 @@ static _INLINE_ void serial_out(struct async_struct *info, int offset,
outb(value, info->port+1);
break;
#endif
-#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
case SERIAL_IO_MEM:
writeb(value, info->iomem_base +
(offset<<info->iomem_reg_shift));
break;
-#endif
#ifdef CONFIG_SERIAL_GSC
case SERIAL_IO_GSC:
gsc_writeb(value, info->iomem_base + offset);
@@ -907,11 +921,16 @@ static void rs_interrupt_multi(int irq, void *dev_id, struct pt_regs * regs)
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) {
-#if 1
- printk("rs_multi loop break\n");
-#endif
- break; /* Prevent infinite loops */
+ 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",
@@ -1542,6 +1561,15 @@ static void change_speed(struct async_struct *info,
/* As a last resort, if the quotient is zero, default to 9600 bps */
if (!quot)
quot = baud_base / 9600;
+ /*
+ * 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) && (info->state->type == PORT_16C950) &&
+ (info->state->revision == 0x5202))
+ quot++;
+
info->quot = quot;
info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
info->timeout += HZ/50; /* Add .02 seconds of slop */
@@ -2092,6 +2120,8 @@ static int set_modem_info(struct async_struct * info, unsigned int cmd,
if (arg & TIOCM_OUT2)
info->MCR |= UART_MCR_OUT2;
#endif
+ if (arg & TIOCM_LOOP)
+ info->MCR |= UART_MCR_LOOP;
break;
case TIOCMBIC:
if (arg & TIOCM_RTS)
@@ -2104,6 +2134,8 @@ static int set_modem_info(struct async_struct * info, unsigned int cmd,
if (arg & TIOCM_OUT2)
info->MCR &= ~UART_MCR_OUT2;
#endif
+ if (arg & TIOCM_LOOP)
+ info->MCR &= ~UART_MCR_LOOP;
break;
case TIOCMSET:
info->MCR = ((info->MCR & ~(UART_MCR_RTS |
@@ -2111,12 +2143,14 @@ static int set_modem_info(struct async_struct * info, unsigned int cmd,
UART_MCR_OUT1 |
UART_MCR_OUT2 |
#endif
+ UART_MCR_LOOP |
UART_MCR_DTR))
| ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
#ifdef TIOCM_OUT1
| ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0)
| ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0)
#endif
+ | ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0)
| ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
break;
default:
@@ -2581,6 +2615,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
return;
}
info->flags |= ASYNC_CLOSING;
+ restore_flags(flags);
/*
* Save the termios structure, since this port may have
* separate termios for callout and dialin.
@@ -2632,7 +2667,6 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
ASYNC_CLOSING);
wake_up_interruptible(&info->close_wait);
MOD_DEC_USE_COUNT;
- restore_flags(flags);
}
/*
@@ -2714,6 +2748,8 @@ static void rs_hangup(struct tty_struct *tty)
state = info->state;
rs_flush_buffer(tty);
+ if (info->flags & ASYNC_CLOSING)
+ return;
shutdown(info);
info->event = 0;
state->count = 0;
@@ -2886,10 +2922,8 @@ static int get_async_struct(int line, struct async_struct **ret_info)
info->port = sstate->port;
info->flags = sstate->flags;
info->io_type = sstate->io_type;
-#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
info->iomem_base = sstate->iomem_base;
info->iomem_reg_shift = sstate->iomem_reg_shift;
-#endif
info->xmit_fifo_size = sstate->xmit_fifo_size;
info->line = line;
info->tqueue.routine = do_softint;
@@ -3125,43 +3159,47 @@ done:
* number, and identifies which options were configured into this
* driver.
*/
-static _INLINE_ void show_serial_version(void)
-{
- printk(KERN_INFO "%s version %s%s (%s) with", serial_name,
- serial_version, LOCAL_VERSTRING, serial_revdate);
+static char serial_options[] __initdata =
#ifdef CONFIG_HUB6
- printk(" HUB-6");
+ " HUB-6"
#define SERIAL_OPT
#endif
#ifdef CONFIG_SERIAL_MANY_PORTS
- printk(" MANY_PORTS");
+ " MANY_PORTS"
#define SERIAL_OPT
#endif
#ifdef CONFIG_SERIAL_MULTIPORT
- printk(" MULTIPORT");
+ " MULTIPORT"
#define SERIAL_OPT
#endif
#ifdef CONFIG_SERIAL_SHARE_IRQ
- printk(" SHARE_IRQ");
+ " SHARE_IRQ"
#define SERIAL_OPT
#endif
#ifdef CONFIG_SERIAL_DETECT_IRQ
- printk(" DETECT_IRQ");
+ " DETECT_IRQ"
#define SERIAL_OPT
#endif
#ifdef ENABLE_SERIAL_PCI
- printk(" SERIAL_PCI");
-#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
- printk(" PCI_IOMEM");
+ " SERIAL_PCI"
+#define SERIAL_OPT
#endif
+#ifdef ENABLE_SERIAL_PNP
+ " ISAPNP"
#define SERIAL_OPT
#endif
#ifdef SERIAL_OPT
- printk(" enabled\n");
+ " enabled\n";
#else
- printk(" no serial options enabled\n");
+ " 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);
}
/*
@@ -3190,11 +3228,15 @@ static unsigned detect_uart_irq (struct serial_state * state)
}
#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());
@@ -3298,7 +3340,8 @@ static void autoconfig_startech_uarts(struct async_struct *info,
(scratch3 == 0x50 || scratch3 == 0x52 ||
scratch3 == 0x54)) {
state->type = PORT_16C950;
- state->revision = serial_icr_read(info, UART_REV);
+ state->revision = serial_icr_read(info, UART_REV) |
+ (scratch3 << 8);
return;
}
}
@@ -3369,10 +3412,8 @@ static void autoconfig(struct serial_state * state)
info->hub6 = state->hub6;
#endif
info->io_type = state->io_type;
-#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
info->iomem_base = state->iomem_base;
info->iomem_reg_shift = state->iomem_reg_shift;
-#endif
save_flags(flags); cli();
@@ -3538,18 +3579,151 @@ static struct symbol_table serial_syms = {
};
#endif
+
+#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)
+
+static void __init 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 *state,
+ int idx)
+{
+ unsigned long port;
+ int base_idx;
+ int max_port;
+
+ 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_BASE_REGION_SIZE(dev, base_idx) / 8;
+ if (idx >= max_port)
+ return 1;
+ }
+
+ port = PCI_BASE_ADDRESS(dev, base_idx) + board->first_uart_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)) {
+ state->port = port;
+ return 0;
+ }
+ state->io_type = SERIAL_IO_MEM;
+ state->iomem_base = ioremap(port, board->uart_offset);
+ state->iomem_reg_shift = board->reg_shift;
+ state->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 __init start_pci_pnp_board(struct pci_dev *dev,
+ struct pci_board *board)
+{
+ int k, line;
+ struct serial_struct fake_state;
+ int base_baud;
+
+ if (PREPARE_FUNC(dev) && (PREPARE_FUNC(dev))(dev) < 0) {
+ printk("SERIAL: PNP device '");
+ printk_pnp_dev_id(board->vendor, board->device);
+ printk("' prepare failed\n");
+ return;
+ }
+
+ if (ACTIVATE_FUNC(dev) && (ACTIVATE_FUNC(dev))(dev) < 0) {
+ printk("SERIAL: PNP device '");
+ printk_pnp_dev_id(board->vendor, board->device);
+ printk("' activate failed\n");
+ return;
+ }
+
+ /*
+ * Run the initialization function, if any
+ */
+ if (board->init_fn && ((board->init_fn)(dev, board, 1) != 0))
+ return;
+
+#ifdef MODULE
+ /*
+ * Register the serial board in the array if we need to
+ * shutdown the board on a module unload.
+ */
+ if (DEACTIVATE_FUNC(dev) || board->init_fn) {
+ if (serial_pci_board_idx >= NR_PCI_BOARDS)
+ return;
+ serial_pci_board[serial_pci_board_idx].board = *board;
+ serial_pci_board[serial_pci_board_idx].dev = dev;
+ serial_pci_board_idx++;
+ }
+#endif
+
+ base_baud = board->base_baud;
+ if (!base_baud)
+ base_baud = BASE_BAUD;
+ memset(&fake_state, 0, sizeof(fake_state));
+
+ for (k=0; k < board->num_ports; k++) {
+ fake_state.irq = get_pci_irq(dev, board, k);
+ if (get_pci_port(dev, board, &fake_state, k))
+ break;
+ fake_state.flags = ASYNC_SKIP_TEST;
+#ifdef SERIAL_DEBUG_PCI
+ printk("Setup PCI/PNP port: port %x, irq %d, type %d\n",
+ fake_state.port, fake_state.irq, fake_state.io_type);
+#endif
+ line = register_serial(&fake_state);
+ if (line < 0)
+ break;
+ rs_table[line].baud_base = base_baud;
+ }
+}
+#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.
- *
- * Note that __init is a no-op if MODULE is defined; we depend on this.
*/
-static int __init pci_plx9050_fn(struct pci_dev *dev,
- struct pci_board *board,
- int enable)
+static int
+#ifndef MODULE
+__init
+#endif
+pci_plx9050_fn(struct pci_dev *dev, struct pci_board *board, int enable)
{
u8 data, *p, scratch;
@@ -3561,7 +3735,7 @@ static int __init pci_plx9050_fn(struct pci_dev *dev,
/* enable/disable interrupts */
p = ioremap(PCI_BASE_ADDRESS(dev, 0), 0x80);
- if (board->vendor == PCI_VENDOR_ID_PANACOM) {
+ if (dev->vendor == PCI_VENDOR_ID_PANACOM) {
scratch = readl(p + 0x4c);
if (enable)
scratch |= 0x40;
@@ -3600,9 +3774,11 @@ static int __init pci_plx9050_fn(struct pci_dev *dev,
#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 __init pci_siig10x_fn(struct pci_dev *dev,
- struct pci_board *board,
- int enable)
+static int
+#ifndef MODULE
+__init
+#endif
+pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
{
u16 data, *p;
@@ -3630,9 +3806,11 @@ static int __init pci_siig10x_fn(struct pci_dev *dev,
#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 __init pci_siig20x_fn(struct pci_dev *dev,
- struct pci_board *board,
- int enable)
+static int
+#ifndef MODULE
+__init
+#endif
+pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
{
u8 data;
@@ -3651,11 +3829,12 @@ static int __init pci_siig20x_fn(struct pci_dev *dev,
return 0;
}
+
/*
* This is the configuration table for all of the PCI serial boards
* which we support.
*/
-static struct pci_board pci_boards[] = {
+static struct pci_board pci_boards[] __initdata = {
/*
* Vendor ID, Device ID,
* Subvendor ID, Subdevice ID,
@@ -3754,7 +3933,7 @@ static struct pci_board pci_boards[] = {
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
PCI_SUBVENDOR_ID_KEYSPAN,
PCI_SUBDEVICE_ID_KEYSPAN_SX2,
- SPCI_FL_BASE2 | SPCI_FL_IOMEM, 2, 921600,
+ SPCI_FL_BASE2, 2, 921600, /* IOMEM */
0x400, 7, pci_plx9050_fn },
{ PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM,
PCI_ANY_ID, PCI_ANY_ID,
@@ -3800,18 +3979,47 @@ static struct pci_board pci_boards[] = {
{ PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE1, 8, 115200 },
- { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
- PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4,
- SPCI_FL_BASE0 , 4, 115200 },
{ PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954,
PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4,
SPCI_FL_BASE0 , 4, 921600 },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 , 4, 115200 },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 , 2, 115200 },
+ /* This board uses the size of PCI Base region 0 to
+ * signal now many ports are available */
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_REGION_SZ_CAP, 32, 115200 },
{ PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 , 2, 921600 },
- { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DUAL_SERIAL,
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DSERIAL,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_A,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_PLUS,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_A,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_650,
+ PCI_ANY_ID, PCI_ANY_ID,
+ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 460800 },
{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE2, 1, 460800,
@@ -3947,49 +4155,81 @@ static struct pci_board pci_boards[] = {
/* 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,
- SPCI_FL_IOMEM | SPCI_FL_BASE0, 4, 921600,
+ SPCI_FL_BASE0, 4, 921600, /* IOMEM */
0x40, 2, NULL, 0x200 },
{ PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8,
- SPCI_FL_IOMEM | SPCI_FL_BASE0, 8, 921600,
+ SPCI_FL_BASE0, 8, 921600, /* IOMEM */
0x40, 2, NULL, 0x200 },
{ PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6,
- SPCI_FL_IOMEM | SPCI_FL_BASE0, 6, 921600,
+ SPCI_FL_BASE0, 6, 921600, /* IOMEM */
0x40, 2, NULL, 0x200 },
- /*
- * Untested PCI modems, sent in from various folks...
- */
- /* at+t zoom 56K faxmodem, from dougd@shieldsbag.com */
- { PCI_VENDOR_ID_ATT, 0x442,
+ /* Digitan DS560-558, from jimd@esoft.com */
+ { PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_ATT_VENUS_MODEM,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE1, 1, 115200 },
- /* at&t unknown modem, from jimd@esoft.com */
- { PCI_VENDOR_ID_ATT, 0x480,
+ /* 3Com US Robotics 56k Voice Internal PCI model 5610 */
+ { PCI_VENDOR_ID_USR, 0x1008,
PCI_ANY_ID, PCI_ANY_ID,
- SPCI_FL_BASE1, 1, 115200 },
+ SPCI_FL_BASE0, 1, 115200 },
+ /*
+ * 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,
SPCI_FL_BASE1, 1, 115200 },
- /* 3Com US Robotics 56k* Voice Internal PCI, model# 2884 */
- /* from evidal@iti.upv.es */
- /* XXX complete guess this may not work!!! */
- { PCI_VENDOR_ID_USR, 0x1006,
- 0x12b9, 0x0060,
- SPCI_FL_BASE1 | SPCI_FL_IOMEM, 1, 115200 },
-#ifdef CONFIG_DDB5074
+ /* Generic serial board */
+ { 0, 0,
+ 0, 0,
+ SPCI_FL_BASE0, 1, 115200 },
+};
+
+/*
+ * Given a complete unknown PCI device, try to use some hueristics to
+ * guess what the configuration might be, based on the pitiful PCI
+ * serial specs. Returns 0 on success, 1 on failure.
+ */
+static int _INLINE_ serial_guess_board(struct pci_dev *dev,
+ struct pci_board *board)
+{
+ int num_iomem = 0, num_port = 0, first_port = -1;
+ int i;
+
/*
- * NEC Vrc-5074 (Nile 4) builtin UART.
- * Conditionally compiled in since this is a motherboard device.
+ * 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?)
*/
- { PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_NILE4,
- PCI_ANY_ID, PCI_ANY_ID,
- SPCI_FL_BASE0 | SPCI_FL_IOMEM, 1, 520833,
- 64, 3, NULL, 0x300 },
-#endif
- { 0, }
-};
+ if ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL ||
+ (dev->class & 0xff) > 6)
+ return 1;
+
+ for (i=0; i < 6; i++) {
+ if (IS_PCI_REGION_IOPORT(dev, i)) {
+ num_port = 0;
+ if (first_port == -1)
+ first_port = i;
+ } else {
+ 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;
+}
+
+
/*
* Query PCI space for known serial boards
@@ -3998,19 +4238,22 @@ static struct pci_board pci_boards[] = {
* Accept a maximum of eight boards
*
*/
-static void probe_serial_pci(void)
+static void __init probe_serial_pci(void)
{
- int k, line;
struct pci_dev *dev = NULL;
struct pci_board *board;
- struct serial_struct fake_state;
- int uart_offset, base_baud, base_idx;
- unsigned long port;
#ifdef SERIAL_DEBUG_PCI
printk(KERN_DEBUG "Entered probe_serial_pci()\n");
#endif
+ if (!pcibios_present()) {
+#ifdef SERIAL_DEBUG_PCI
+ printk(KERN_DEBUG "Leaving probe_serial_pci() (no pcibios)\n");
+#endif
+ return;
+ }
+
pci_for_each_dev(dev) {
for (board = pci_boards; board->vendor; board++) {
if (board->vendor != (unsigned short) PCI_ANY_ID &&
@@ -4020,122 +4263,87 @@ static void probe_serial_pci(void)
dev->device != board->device)
continue;
if (board->subvendor != (unsigned short) PCI_ANY_ID &&
- dev->subsystem_vendor != board->subvendor)
+ pci_get_subvendor(dev) != board->subvendor)
continue;
if (board->subdevice != (unsigned short) PCI_ANY_ID &&
- dev->subsystem_device != board->subdevice)
+ pci_get_subdevice(dev) != board->subdevice)
continue;
break;
}
- if (board->vendor == 0) {
+ if (board->vendor == 0 && serial_guess_board(dev, board))
+ continue;
+
+ start_pci_pnp_board(dev, board);
+ }
+
#ifdef SERIAL_DEBUG_PCI
- printk(KERN_DEBUG
- "Found unknown serial board: %x:%x, %x:%x, %x\n",
- dev->vendor, dev->device, dev->subsystem_vendor,
- dev->subsystem_device,
- dev->class);
- printk(KERN_DEBUG
- " Addresses: %lx, %lx, %lx, %lx\n",
- PCI_BASE_ADDRESS(dev, 0), PCI_BASE_ADDRESS(dev, 1),
- PCI_BASE_ADDRESS(dev, 2), PCI_BASE_ADDRESS(dev, 3));
-#endif
- continue;
- }
+ printk(KERN_DEBUG "Leaving probe_serial_pci() (probe finished)\n");
+#endif
+ return;
+}
- /*
- * Run the initialization function, if any
- */
- if (board->init_fn)
- if ((board->init_fn)(dev, board, 1) != 0)
- continue;
+#endif /* ENABLE_SERIAL_PCI */
- /*
- * Register the serial board in the array so we can
- * shutdown the board later, if necessary.
- */
- if (serial_pci_board_idx >= NR_PCI_BOARDS)
- continue;
- serial_pci_board[serial_pci_board_idx].board = board;
- serial_pci_board[serial_pci_board_idx].dev = dev;
- serial_pci_board_idx++;
+#ifdef ENABLE_SERIAL_PNP
+
+static struct pci_board pnp_devices[] __initdata = {
+ /* Rockwell 56K ACF II Fax+Data+Voice Modem */
+ { ISAPNP_VENDOR('A', 'K', 'Y'), ISAPNP_DEVICE(0x1021), 0, 0,
+ SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
+ /* Boca Research 33,600 ACF Modem */
+ { ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x1400), 0, 0,
+ SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
+ /* Best Data Products Inc. Smart One 336F PnP Modem */
+ { ISAPNP_VENDOR('B', 'D', 'P'), ISAPNP_DEVICE(0x3336), 0, 0,
+ SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
+ /* These ID's are taken from M$ documentation */
+ /* Compaq 14400 Modem */
+ { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC000), 0, 0,
+ SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
+ /* Compaq 2400/9600 Modem */
+ { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC001), 0, 0,
+ SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
+ /* Generic standard PC COM port */
+ { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0500), 0, 0,
+ SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
+ /* Generic 16550A-compatible COM port */
+ { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0501), 0, 0,
+ SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
+ { 0, }
+};
- base_idx = board->flags & SPCI_FL_BASE_MASK;
- port = PCI_BASE_ADDRESS(dev, base_idx) +
- board->first_uart_offset;
- if (board->flags & SPCI_FL_IOMEM)
- port &= PCI_BASE_ADDRESS_MEM_MASK;
- else
- port &= PCI_BASE_ADDRESS_IO_MASK;
+static void __init probe_serial_pnp(void)
+{
+ struct pci_dev *dev = NULL;
+ struct pci_board *board;
- /*
- * Set some defaults for the loop below, which
- * actually registers each serial port belonging to
- * the card.
- */
- uart_offset = board->uart_offset;
- if (!uart_offset)
- uart_offset = 8;
- base_baud = board->base_baud;
- if (!base_baud)
- base_baud = BASE_BAUD;
-#ifndef CONFIG_SERIAL_PCI_MEMMAPPED
- if (board->flags & SPCI_FL_IOMEM) {
-#ifdef SERIAL_DEBUG_PCI
- printk(KERN_DEBUG
- "Can't support memory mapped PCI serial device\n");
+#ifdef SERIAL_DEBUG_PNP
+ printk("Entered probe_serial_pnp()\n");
#endif
- continue;
- }
+ if (!isapnp_present()) {
+#ifdef SERIAL_DEBUG_PNP
+ printk("Leaving probe_serial_pnp() (no isapnp)\n");
#endif
- memset(&fake_state, 0, sizeof(fake_state));
+ return;
+ }
-#ifdef SERIAL_DEBUG_PCI
- printk(KERN_DEBUG
- "Found Serial PCI device: %x:%x, %x:%x, %x\n",
- dev->vendor, dev->device, dev->subsystem_vendor,
- dev->subsystem_device, dev->class);
- printk(KERN_DEBUG
- " IRQ: %d, base: %lx (%s), num_ports: %d\n",
- dev->irq, port, board->flags & SPCI_FL_IOMEM ?
- "iomem" : "port", board->num_ports);
-#endif
+ for (board = pnp_devices; board->vendor; board++) {
+ while ((dev = isapnp_find_dev(NULL, board->vendor,
+ board->device, dev))) {
+
+ start_pci_pnp_board(dev, board);
- for (k=0; k < board->num_ports; k++) {
- if (board->flags & SPCI_FL_BASE_TABLE) {
- port = PCI_BASE_ADDRESS(dev, base_idx++);
- if (board->flags & SPCI_FL_IOMEM)
- port &= PCI_BASE_ADDRESS_MEM_MASK;
- else
- port &= PCI_BASE_ADDRESS_IO_MASK;
- }
- fake_state.irq = dev->irq;
- fake_state.port = port;
-#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
- if (board->flags & SPCI_FL_IOMEM) {
- fake_state.io_type = SERIAL_IO_MEM;
- fake_state.iomem_base =
- ioremap(port, board->uart_offset);
- fake_state.iomem_reg_shift = board->reg_shift;
- fake_state.port = 0;
- }
-#endif
- port += uart_offset;
- fake_state.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;
- line = register_serial(&fake_state);
- if (line < 0)
- break;
- rs_table[line].baud_base = base_baud;
- }
- }
-
-#ifdef SERIAL_DEBUG_PCI
- printk(KERN_DEBUG "Leaving probe_serial_pci() (probe finished)\n");
+ }
+ }
+
+#ifdef SERIAL_DEBUG_PNP
+ printk("Leaving probe_serial_pnp() (probe finished)\n");
#endif
- return;
+ return;
}
-#endif /* ENABLE_SERIAL_PCI */
+#endif /* ENABLE_SERIAL_PNP */
/*
* The serial driver boot-time initialization code!
@@ -4283,6 +4491,9 @@ int __init rs_init(void)
#ifdef ENABLE_SERIAL_PCI
probe_serial_pci();
#endif
+#ifdef ENABLE_SERIAL_PNP
+ probe_serial_pnp();
+#endif
return 0;
}
@@ -4295,6 +4506,7 @@ int register_serial(struct serial_struct *req)
int i;
unsigned long flags;
struct serial_state *state;
+ struct async_struct *info;
save_flags(flags);
cli();
@@ -4324,13 +4536,17 @@ int register_serial(struct serial_struct *req)
state->port = req->port;
state->flags = req->flags;
state->io_type = req->io_type;
-#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
state->iomem_base = req->iomem_base;
state->iomem_reg_shift = req->iomem_reg_shift;
-#endif
if (req->baud_base)
state->baud_base = req->baud_base;
-
+ if ((info = state->info) != NULL) {
+ info->port = req->port;
+ info->flags = req->flags;
+ info->io_type = req->io_type;
+ info->iomem_base = req->iomem_base;
+ info->iomem_reg_shift = req->iomem_reg_shift;
+ }
autoconfig(state);
if (state->type == PORT_UNKNOWN) {
restore_flags(flags);
@@ -4400,17 +4616,20 @@ void cleanup_module(void)
}
if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port)
release_region(rs_table[i].port, 8);
-#if defined(ENABLE_SERIAL_PCI) && defined (CONFIG_SERIAL_PCI_MEMMAPPED)
+#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)
if (rs_table[i].iomem_base)
iounmap(rs_table[i].iomem_base);
#endif
}
-#ifdef ENABLE_SERIAL_PCI
+#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)
for (i=0; i < serial_pci_board_idx; i++) {
struct pci_board_inst *brd = &serial_pci_board[i];
- if (brd->board->init_fn)
- (brd->board->init_fn)(brd->dev, brd->board, 0);
+ 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) {
@@ -4612,10 +4831,8 @@ static int __init serial_console_setup(struct console *co, char *options)
info->hub6 = state->hub6;
#endif
info->io_type = state->io_type;
-#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
info->iomem_base = state->iomem_base;
info->iomem_reg_shift = state->iomem_reg_shift;
-#endif
quot = state->baud_base / baud;
cval = cflag & (CSIZE | CSTOPB);
#if defined(__powerpc__) || defined(__alpha__)
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index eacde318e..ae2fb2d70 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -2457,20 +2457,20 @@ void fix_sx_pci (PDEV, struct sx_board *board)
{
unsigned int hwbase;
unsigned long rebase;
- int t;
+ unsigned int t;
-#define CNTRL_REG_OFFSET 0x14
+#define CNTRL_REG_OFFSET 0x50
+#define CNTRL_REG_GOODVALUE 0x00260000
pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase);
hwbase &= PCI_BASE_ADDRESS_MEM_MASK;
rebase = (ulong) ioremap(hwbase, 0x80);
- t = readb (rebase + CNTRL_REG_OFFSET*4 + 2);
- if (t != 0x06) {
- printk (KERN_DEBUG "sx: performing cntrl reg fix: %02x -> 06\n", t);
- writeb (0x06, rebase + CNTRL_REG_OFFSET*4+2);
+ t = readl (rebase + CNTRL_REG_OFFSET);
+ if (t != CNTRL_REG_GOODVALUE) {
+ printk (KERN_DEBUG "sx: performing cntrl reg fix: %08x -> %08x\n", t, CNTRL_REG_GOODVALUE);
+ writel (CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET);
}
my_iounmap (hwbase, rebase);
-
}
#endif
diff --git a/drivers/char/wdt.c b/drivers/char/wdt.c
index 1792bbac4..3aceec969 100644
--- a/drivers/char/wdt.c
+++ b/drivers/char/wdt.c
@@ -60,19 +60,31 @@ static int irq=11;
#define WD_TIMO (100*60) /* 1 minute */
+#ifndef MODULE
+
/*
* Setup options
*/
-void __init wdt_setup(char *str, int *ints)
+static int __init wdt_setup(char *str)
{
- if(ints[0]>0)
+ int ints[4];
+
+ str = get_options (str, ARRAY_SIZE(ints), ints);
+
+ if (ints[0] > 0)
{
- io=ints[1];
- if(ints[0]>1)
- irq=ints[2];
+ io = ints[1];
+ if(ints[0] > 1)
+ irq = ints[2];
}
+
+ return 1;
}
+
+__setup("wdt=", wdt_setup);
+
+#endif /* !MODULE */
/*
* Programming support
@@ -367,10 +379,10 @@ void cleanup_module(void)
int __init wdt_init(void)
{
- printk("WDT500/501-P driver 0.07 at %X (Interrupt %d)\n", io,irq);
+ printk(KERN_INFO "WDT500/501-P driver 0.07 at %X (Interrupt %d)\n", io,irq);
if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL))
{
- printk("IRQ %d is not free.\n", irq);
+ printk(KERN_ERR "IRQ %d is not free.\n", irq);
return -EIO;
}
misc_register(&wdt_miscdev);
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c
index 792db2fd8..4b96ae1d3 100644
--- a/drivers/fc4/fc.c
+++ b/drivers/fc4/fc.c
@@ -54,32 +54,19 @@
#endif
#ifdef __sparc__
-static inline void *fc_dma_alloc(long size, dma_handle *dma, fc_channel *fc)
-{
- return sbus_alloc_consistant(fc->dev, size, dma);
-}
-
-static inline dma_handle fc_sync_dma_entry(void *buf, long len, fc_channel *fc)
-{
- return sbus_map_single(fc->dev, buf, len);
-}
-
-static inline void fc_sync_dma_exit(dma_handle dmh, long size, fc_channel *fc)
-{
- sbus_unmap_single(fc->dev, dmh, size);
-}
-
-static inline void fc_sync_dma_entry_sg(struct scatterlist *list, int count, fc_channel *fc)
-{
- sbus_map_sg(fc->dev, list, count);
-}
-
-static inline void fc_sync_dma_exit_sg(struct scatterlist *list, int count, fc_channel *fc)
-{
- sbus_unmap_sg(fc->dev, list, count);
-}
+#define dma_alloc_consistent(d,s,p) sbus_alloc_consistent(d,s,p)
+#define dma_free_consistent(d,s,v,h) sbus_free_consistent(d,s,v,h)
+#define dma_map_single(d,v,s) sbus_map_single(d,v,s)
+#define dma_unmap_single(d,h,s) sbus_unmap_single(d,h,s)
+#define dma_map_sg(d,s,n) sbus_map_sg(d,s,n)
+#define dma_unmap_sg(d,s,n) sbus_unmap_sg(d,s,n)
#else
-#error Port this
+#define dma_alloc_consistent(d,s,p) pci_alloc_consistent(d,s,p)
+#define dma_free_consistent(d,s,v,h) pci_free_consistent(d,s,v,h)
+#define dma_map_single(d,v,s) pci_map_single(d,v,s)
+#define dma_unmap_single(d,h,s) pci_unmap_single(d,h,s)
+#define dma_map_sg(d,s,n) pci_map_sg(d,s,n)
+#define dma_unmap_sg(d,s,n) pci_unmap_sg(d,s,n)
#endif
#define FCP_CMND(SCpnt) ((fcp_cmnd *)&(SCpnt->SCp))
@@ -176,7 +163,7 @@ static void fcp_login_done(fc_channel *fc, int i, int status)
fc->state = FC_STATE_FPORT_OK;
fcmd = l->fcmds + i;
plogi = l->logi + 3 * i;
- fc_sync_dma_exit (fcmd->cmd, 3 * sizeof(logi), fc);
+ dma_unmap_single (fc->dev, fcmd->cmd, 3 * sizeof(logi));
plogi->code = LS_PLOGI;
memcpy (&plogi->nport_wwn, &fc->wwn_nport, sizeof(fc_wwn));
memcpy (&plogi->node_wwn, &fc->wwn_node, sizeof(fc_wwn));
@@ -196,7 +183,7 @@ static void fcp_login_done(fc_channel *fc, int i, int status)
printk ("\n");
}
#endif
- fcmd->cmd = fc_sync_dma_entry (plogi, 3 * sizeof(logi), fc);
+ fcmd->cmd = dma_map_single (fc->dev, plogi, 3 * sizeof(logi));
fcmd->rsp = fcmd->cmd + 2 * sizeof(logi);
if (fc->hw_enque (fc, fcmd))
printk ("FC: Cannot enque PLOGI packet on %s\n", fc->name);
@@ -219,7 +206,7 @@ static void fcp_login_done(fc_channel *fc, int i, int status)
switch (status) {
case FC_STATUS_OK:
plogi = l->logi + 3 * i;
- fc_sync_dma_exit (l->fcmds[i].cmd, 3 * sizeof(logi), fc);
+ dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi));
if (!fc->wwn_dest.lo && !fc->wwn_dest.hi) {
memcpy (&fc->wwn_dest, &plogi[1].node_wwn, sizeof(fc_wwn));
FCD(("Dest WWN %08x%08x\n", *(u32 *)&fc->wwn_dest, fc->wwn_dest.lo))
@@ -237,7 +224,7 @@ static void fcp_login_done(fc_channel *fc, int i, int status)
break;
case FC_STATUS_ERR_OFFLINE:
fc->state = FC_STATE_OFFLINE;
- fc_sync_dma_exit (l->fcmds[i].cmd, 3 * sizeof(logi), fc);
+ dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi));
printk ("%s: FC is offline\n", fc->name);
if (atomic_dec_and_test (&l->todo))
up(&l->sem);
@@ -261,7 +248,7 @@ static void fcp_report_map_done(fc_channel *fc, int i, int status)
FCD(("Report map done %d %d\n", i, status))
switch (status) {
case FC_STATUS_OK: /* Ok, let's have a fun on a loop */
- fc_sync_dma_exit (l->fcmds[i].cmd, 3 * sizeof(logi), fc);
+ dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi));
p = (fc_al_posmap *)(l->logi + 3 * i);
#ifdef FCDEBUG
{
@@ -310,7 +297,7 @@ static void fcp_report_map_done(fc_channel *fc, int i, int status)
case FC_STATUS_POINTTOPOINT: /* We're Point-to-Point, no AL... */
FCD(("SID %d DID %d\n", fc->sid, fc->did))
fcmd = l->fcmds + i;
- fc_sync_dma_exit(fcmd->cmd, 3 * sizeof(logi), fc);
+ dma_unmap_single(fc->dev, fcmd->cmd, 3 * sizeof(logi));
fch = &fcmd->fch;
memset(l->logi + 3 * i, 0, 3 * sizeof(logi));
FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, FS_FABRIC_F_PORT);
@@ -320,11 +307,11 @@ static void fcp_report_map_done(fc_channel *fc, int i, int status)
FILL_FCHDR_OXRX(fch, 0xffff, 0xffff);
fch->param = 0;
l->logi [3 * i].code = LS_FLOGI;
- fcmd->cmd = fc_sync_dma_entry (l->logi + 3 * i, 3 * sizeof(logi), fc);
+ fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi));
fcmd->rsp = fcmd->cmd + sizeof(logi);
fcmd->cmdlen = sizeof(logi);
fcmd->rsplen = sizeof(logi);
- fcmd->data = (dma_handle)NULL;
+ fcmd->data = (dma_addr_t)NULL;
fcmd->class = FC_CLASS_SIMPLE;
fcmd->proto = TYPE_EXTENDED_LS;
if (fc->hw_enque (fc, fcmd))
@@ -350,9 +337,10 @@ void fcp_register(fc_channel *fc, u8 type, int unregister)
if (type == TYPE_SCSI_FCP) {
if (!unregister) {
- fc->scsi_cmd_pool =
- (fcp_cmd *) fc_dma_alloc (slots * (sizeof (fcp_cmd) + fc->rsp_size),
- &fc->dma_scsi_cmd, fc);
+ fc->scsi_cmd_pool = (fcp_cmd *)
+ dma_alloc_consistent (fc->dev,
+ slots * (sizeof (fcp_cmd) + fc->rsp_size),
+ &fc->dma_scsi_cmd);
fc->scsi_rsp_pool = (char *)(fc->scsi_cmd_pool + slots);
fc->dma_scsi_rsp = fc->dma_scsi_cmd + slots * sizeof (fcp_cmd);
fc->scsi_bitmap_end = (slots + 63) & ~63;
@@ -436,9 +424,9 @@ static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hd
if (fcmd->data) {
if (SCpnt->use_sg)
- fc_sync_dma_exit_sg((struct scatterlist *)SCpnt->buffer, SCpnt->use_sg, fc);
+ dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->buffer, SCpnt->use_sg);
else
- fc_sync_dma_exit(fcmd->data, SCpnt->request_bufflen, fc);
+ dma_unmap_single(fc->dev, fcmd->data, SCpnt->request_bufflen);
}
break;
default:
@@ -577,7 +565,7 @@ int fcp_initialize(fc_channel *fcchain, int count)
fc->login = fcmd;
fc->ls = (void *)l;
/* Assumes sizeof(fc_al_posmap) < 3 * sizeof(logi), which is true */
- fcmd->cmd = fc_sync_dma_entry (l->logi + 3 * i, 3 * sizeof(logi), fc);
+ fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi));
fcmd->proto = PROTO_REPORT_AL_MAP;
fcmd->token = i;
fcmd->fc = fc;
@@ -596,7 +584,7 @@ int fcp_initialize(fc_channel *fcchain, int count)
} else {
fc->state = FC_STATE_OFFLINE;
enable_irq(fc->irq);
- fc_sync_dma_exit (l->fcmds[i].cmd, 3 * sizeof(logi), fc);
+ dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi));
if (atomic_dec_and_test (&l->todo))
goto all_done;
}
@@ -613,7 +601,7 @@ int fcp_initialize(fc_channel *fcchain, int count)
FCD(("SID %d DID %d\n", fc->sid, fc->did))
fcmd = l->fcmds + i;
- fc_sync_dma_exit(fcmd->cmd, 3 * sizeof(logi), fc);
+ dma_unmap_single(fc->dev, fcmd->cmd, 3 * sizeof(logi));
fch = &fcmd->fch;
FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, FS_FABRIC_F_PORT);
FILL_FCHDR_SID(fch, 0);
@@ -622,11 +610,11 @@ int fcp_initialize(fc_channel *fcchain, int count)
FILL_FCHDR_OXRX(fch, 0xffff, 0xffff);
fch->param = 0;
l->logi [3 * i].code = LS_FLOGI;
- fcmd->cmd = fc_sync_dma_entry (l->logi + 3 * i, 3 * sizeof(logi), fc);
+ fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi));
fcmd->rsp = fcmd->cmd + sizeof(logi);
fcmd->cmdlen = sizeof(logi);
fcmd->rsplen = sizeof(logi);
- fcmd->data = (dma_handle)NULL;
+ fcmd->data = (dma_addr_t)NULL;
fcmd->class = FC_CLASS_SIMPLE;
fcmd->proto = TYPE_EXTENDED_LS;
} else
@@ -650,7 +638,7 @@ all_done:
switch (fc->state) {
case FC_STATE_ONLINE: break;
case FC_STATE_OFFLINE: break;
- default: fc_sync_dma_exit (l->fcmds[i].cmd, 3 * sizeof(logi), fc);
+ default: dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi));
break;
}
}
@@ -800,7 +788,7 @@ static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, i
fcp_cntl = FCP_CNTL_QTYPE_UNTAGGED;
if (!SCpnt->request_bufflen && !SCpnt->use_sg) {
cmd->fcp_cntl = fcp_cntl;
- fcmd->data = (dma_handle)NULL;
+ fcmd->data = (dma_addr_t)NULL;
} else {
switch (SCpnt->cmnd[0]) {
case WRITE_6:
@@ -812,16 +800,17 @@ static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, i
}
if (!SCpnt->use_sg) {
cmd->fcp_data_len = SCpnt->request_bufflen;
- fcmd->data = fc_sync_dma_entry ((char *)SCpnt->request_buffer,
- SCpnt->request_bufflen, fc);
+ fcmd->data = dma_map_single (fc->dev, (char *)SCpnt->request_buffer,
+ SCpnt->request_bufflen);
} else {
struct scatterlist *sg = (struct scatterlist *)SCpnt->buffer;
+ int nents;
FCD(("XXX: Use_sg %d %d\n", SCpnt->use_sg, sg->length))
- if (SCpnt->use_sg > 1) printk ("%s: SG for use_sg > 1 not handled yet\n", fc->name);
- fc_sync_dma_entry_sg (sg, SCpnt->use_sg, fc);
- fcmd->data = sg->dvma_address;
- cmd->fcp_data_len = sg->dvma_length;
+ nents = dma_map_sg (fc->dev, sg, SCpnt->use_sg);
+ if (nents > 1) printk ("%s: SG for nents %d (use_sg %d) not handled yet\n", fc->name, nents, SCpnt->use_sg);
+ fcmd->data = sg_dma_address(sg);
+ cmd->fcp_data_len = sg_dma_len(sg);
}
}
memcpy (cmd->fcp_cdb, SCpnt->cmnd, SCpnt->cmd_len);
@@ -954,7 +943,7 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
fc->cmd_slots[0] = fcmd;
cmd->fcp_cntl = FCP_CNTL_QTYPE_ORDERED | FCP_CNTL_RESET;
- fcmd->data = (dma_handle)NULL;
+ fcmd->data = (dma_addr_t)NULL;
fcmd->proto = TYPE_SCSI_FCP;
memcpy (cmd->fcp_cdb, SCpnt->cmnd, SCpnt->cmd_len);
@@ -1059,11 +1048,11 @@ static int fc_do_els(fc_channel *fc, unsigned int alpa, void *data, int len)
FILL_FCHDR_SEQ_DF_SEQ(fch, 0, 0, 0);
FILL_FCHDR_OXRX(fch, 0xffff, 0xffff);
fch->param = 0;
- fcmd->cmd = fc_sync_dma_entry (data, 2 * len, fc);
+ fcmd->cmd = dma_map_single (fc->dev, data, 2 * len);
fcmd->rsp = fcmd->cmd + len;
fcmd->cmdlen = len;
fcmd->rsplen = len;
- fcmd->data = (dma_handle)NULL;
+ fcmd->data = (dma_addr_t)NULL;
fcmd->fc = fc;
fcmd->class = FC_CLASS_SIMPLE;
fcmd->proto = TYPE_EXTENDED_LS;
@@ -1094,7 +1083,7 @@ static int fc_do_els(fc_channel *fc, unsigned int alpa, void *data, int len)
clear_bit(fcmd->token, fc->scsi_bitmap);
fc->scsi_free++;
- fc_sync_dma_exit (fcmd->cmd, 2 * len, fc);
+ dma_unmap_single (fc->dev, fcmd->cmd, 2 * len);
return l.status;
}
diff --git a/drivers/fc4/fcp_impl.h b/drivers/fc4/fcp_impl.h
index c7e0987be..c373a0965 100644
--- a/drivers/fc4/fcp_impl.h
+++ b/drivers/fc4/fcp_impl.h
@@ -15,13 +15,9 @@
#include "fcp.h"
#include "fc-al.h"
+#include <asm/io.h>
#ifdef __sparc__
-
#include <asm/sbus.h>
-typedef u32 dma_handle;
-
-#else
-#error Need to port FC layer to your architecture
#endif
/* 0 or 1 */
@@ -49,11 +45,11 @@ typedef struct fcp_cmnd {
unsigned short token;
unsigned int did;
/* FCP SCSI stuff */
- dma_handle data;
+ dma_addr_t data;
/* From now on this cannot be touched for proto == TYPE_SCSI_FCP */
fc_hdr fch;
- dma_handle cmd;
- dma_handle rsp;
+ dma_addr_t cmd;
+ dma_addr_t rsp;
int cmdlen;
int rsplen;
int class;
@@ -85,6 +81,8 @@ typedef struct _fc_channel {
svc_parm *class_svcs;
#ifdef __sparc__
struct sbus_dev *dev;
+#else
+ struct pci_dev *dev;
#endif
struct module *module;
/* FCP SCSI stuff */
@@ -93,7 +91,7 @@ typedef struct _fc_channel {
int rsp_size;
fcp_cmd *scsi_cmd_pool;
char *scsi_rsp_pool;
- dma_handle dma_scsi_cmd, dma_scsi_rsp;
+ dma_addr_t dma_scsi_cmd, dma_scsi_rsp;
long *scsi_bitmap;
long scsi_bitmap_end;
int scsi_free;
diff --git a/drivers/fc4/soc.c b/drivers/fc4/soc.c
index c44c3fc8c..329c2ae45 100644
--- a/drivers/fc4/soc.c
+++ b/drivers/fc4/soc.c
@@ -668,7 +668,7 @@ static inline void soc_init(struct sbus_dev *sdev, int no)
memset (cq, 0, sizeof(cq));
size = (SOC_CQ_REQ0_SIZE + SOC_CQ_REQ1_SIZE) * sizeof(soc_req);
- s->req_cpu = sbus_alloc_consistant(sdev, size, &s->req_dvma);
+ s->req_cpu = sbus_alloc_consistent(sdev, size, &s->req_dvma);
s->req[0].pool = s->req_cpu;
cq[0].address = s->req_dvma;
s->req[1].pool = s->req[0].pool + SOC_CQ_REQ0_SIZE;
@@ -765,7 +765,7 @@ void cleanup_module(void)
sbus_iounmap(s->xram, sdev->reg_addrs[1].reg_size);
sbus_iounmap(s->regs, sdev->reg_addrs[2].reg_size);
}
- sbus_free_consistant(sdev,
+ sbus_free_consistent(sdev,
(SOC_CQ_REQ0_SIZE+SOC_CQ_REQ1_SIZE)*sizeof(soc_req),
s->req_cpu, s->req_dvma);
}
diff --git a/drivers/fc4/socal.c b/drivers/fc4/socal.c
index c63aaa6b8..51f7b095d 100644
--- a/drivers/fc4/socal.c
+++ b/drivers/fc4/socal.c
@@ -794,7 +794,7 @@ static inline void socal_init(struct sbus_dev *sdev, int no)
size = (SOCAL_CQ_REQ0_SIZE + SOCAL_CQ_REQ1_SIZE +
SOCAL_CQ_RSP0_SIZE + SOCAL_CQ_RSP1_SIZE +
SOCAL_CQ_RSP2_SIZE) * sizeof(socal_req);
- s->req_cpu = sbus_alloc_consistant(sdev, size, &s->req_dvma);
+ s->req_cpu = sbus_alloc_consistent(sdev, size, &s->req_dvma);
s->req[0].pool = s->req_cpu;
cq[0].address = s->req_dvma;
s->req[1].pool = s->req[0].pool + SOCAL_CQ_REQ0_SIZE;
@@ -903,7 +903,7 @@ void cleanup_module(void)
sbus_iounmap(s->xram, sdev->reg_addrs[1].reg_size);
sbus_iounmap(s->regs, sdev->reg_addrs[2].reg_size);
}
- sbus_free_consistant(sdev,
+ sbus_free_consistent(sdev,
(SOCAL_CQ_REQ0_SIZE + SOCAL_CQ_REQ1_SIZE +
SOCAL_CQ_RSP0_SIZE + SOCAL_CQ_RSP1_SIZE +
SOCAL_CQ_RSP2_SIZE) * sizeof(socal_req),
diff --git a/drivers/i2o/i2o_core.c b/drivers/i2o/i2o_core.c
index 6428af9fc..30aecaec5 100644
--- a/drivers/i2o/i2o_core.c
+++ b/drivers/i2o/i2o_core.c
@@ -1411,24 +1411,30 @@ int i2o_init_outbound_q(struct i2o_controller *c)
}
memset(status, 0, 4);
- msg[0]= EIGHT_WORD_MSG_SIZE| TRL_OFFSET_6;
+ msg[0]= EIGHT_WORD_MSG_SIZE| SGL_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 */
- msg[5]= MSG_FRAME_SIZE<<16|0x80; /* Outbound msg frame size and Initcode */
+ /* Frame size is in words. Pick 128, its what everyone elses uses and
+ other sizes break some adapters. */
+ msg[5]= (MSG_FRAME_SIZE>>2)<<16|0x80; /* Outbound msg frame size and Initcode */
msg[6]= 0xD0000004; /* Simple SG LE, EOB */
- msg[7]= virt_to_phys(status);
+ msg[7]= virt_to_bus(status);
i2o_post_message(c,m);
barrier();
time=jiffies;
- while(status[0]!=I2O_CMD_OUTBOUND_INIT_COMPLETE)
+ while(status[0]<0x02)
{
if((jiffies-time)>=5*HZ)
{
- printk(KERN_ERR "%s: Outbound Q initialize timeout.\n",
+ if(status[0]==0x00)
+ printk(KERN_ERR "%s: Ignored queue initialize request.\n",
+ c->name);
+ else
+ printk(KERN_ERR "%s: Outbound queue initialize timeout.\n",
c->name);
kfree(status);
return -ETIMEDOUT;
@@ -1437,6 +1443,13 @@ int i2o_init_outbound_q(struct i2o_controller *c)
barrier();
}
+ if(status[0] != I2O_CMD_OUTBOUND_INIT_COMPLETE)
+ {
+ printk(KERN_ERR "%s: Outbound queue initialize rejected (%d).\n",
+ c->name, status[0]);
+ kfree(status);
+ return -EINVAL;
+ }
/* Alloc space for IOP's outbound queue message frames */
c->page_frame = kmalloc(MSG_POOL_SIZE, GFP_KERNEL);
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 5425541ca..dc18256ce 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -573,7 +573,6 @@ static struct net_device eth0_dev = {
/* Token-ring device probe */
extern int ibmtr_probe(struct net_device *);
extern int olympic_probe(struct net_device *);
-extern int tms380tr_probe(struct net_device *);
extern int smctr_probe(struct net_device *);
static int
@@ -586,9 +585,6 @@ trif_probe(struct net_device *dev)
#ifdef CONFIG_IBMOL
&& olympic_probe(dev)
#endif
-#ifdef CONFIG_SKTR
- && tms380tr_probe(dev)
-#endif
#ifdef CONFIG_SMCTR
&& smctr_probe(dev)
#endif
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c
index ead77eb9e..f15e31ae4 100644
--- a/drivers/net/a2065.c
+++ b/drivers/net/a2065.c
@@ -127,9 +127,6 @@ struct lance_private {
int auto_select; /* cable-selection by carrier */
unsigned short busmaster_regval;
-#ifdef CONFIG_AMIGA
- unsigned int key;
-#endif
#ifdef CONFIG_SUNLANCE
struct Linux_SBus_DMA *ledma; /* if set this points to ledma and arch=4m */
int burst_sizes; /* ledma SBus burst sizes */
@@ -740,78 +737,92 @@ static void lance_set_multicast (struct net_device *dev)
int __init a2065_probe(struct net_device *dev)
{
- unsigned int key, is_cbm;
- const struct ConfigDev *cd;
- u_long board;
- u_long sn;
- struct lance_private *priv;
- struct A2065Board *a2065;
-
- if ((key = is_cbm = zorro_find(ZORRO_PROD_CBM_A2065_1, 0, 0)) ||
- (key = is_cbm = zorro_find(ZORRO_PROD_CBM_A2065_2, 0, 0)) ||
- (key = zorro_find(ZORRO_PROD_AMERISTAR_A2065, 0, 0))) {
- cd = zorro_get_board(key);
- if ((board = (u_long)cd->cd_BoardAddr)) {
- sn = cd->cd_Rom.er_SerialNumber;
- if (is_cbm) { /* Commodore */
- dev->dev_addr[0] = 0x00;
- dev->dev_addr[1] = 0x80;
- dev->dev_addr[2] = 0x10;
- } else { /* Ameristar */
- dev->dev_addr[0] = 0x00;
- dev->dev_addr[1] = 0x00;
- dev->dev_addr[2] = 0x9f;
- }
- dev->dev_addr[3] = (sn>>16) & 0xff;
- dev->dev_addr[4] = (sn>>8) & 0xff;
- dev->dev_addr[5] = sn & 0xff;
- printk("%s: A2065 at 0x%08lx, Ethernet Address %02x:%02x:%02x:%02x:%02x:%02x\n",
- dev->name, board, dev->dev_addr[0],
- dev->dev_addr[1], dev->dev_addr[2],
- dev->dev_addr[3], dev->dev_addr[4],
- dev->dev_addr[5]);
-
- init_etherdev(dev, 0);
-
- dev->priv = kmalloc(sizeof(struct
- lance_private),
- GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- priv = (struct lance_private *)dev->priv;
- memset(priv, 0, sizeof(struct lance_private));
-
- a2065 = (struct A2065Board *)ZTWO_VADDR(board);
- priv->ll = &a2065->Lance;
- priv->init_block =
- (struct lance_init_block *)&a2065->RAM;
- priv->lance_init_block = (struct lance_init_block *)
- offsetof(struct A2065Board, RAM);
- priv->auto_select = 0;
- priv->key = key;
- priv->busmaster_regval = LE_C3_BSWP;
-
- priv->lance_log_rx_bufs = LANCE_LOG_RX_BUFFERS;
- priv->lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS;
- priv->rx_ring_mod_mask = RX_RING_MOD_MASK;
- priv->tx_ring_mod_mask = TX_RING_MOD_MASK;
-
- dev->open = &lance_open;
- dev->stop = &lance_close;
- dev->hard_start_xmit = &lance_start_xmit;
- dev->get_stats = &lance_get_stats;
- dev->set_multicast_list = &lance_set_multicast;
- dev->dma = 0;
-
- ether_setup(dev);
- init_timer(&priv->multicast_timer);
- priv->multicast_timer.data = (unsigned long) dev;
- priv->multicast_timer.function =
- (void (*)(unsigned long)) &lance_set_multicast;
-
- zorro_config_board(key, 0);
- return(0);
+ struct zorro_dev *z = NULL;
+
+ while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
+ unsigned long board, base_addr, ram_start;
+ int is_cbm;
+ struct lance_private *priv;
+
+ if (z->id == ZORRO_PROD_CBM_A2065_1 ||
+ z->id == ZORRO_PROD_CBM_A2065_2)
+ is_cbm = 1;
+ else if (z->id == ZORRO_PROD_AMERISTAR_A2065)
+ is_cbm = 0;
+ else
+ continue;
+
+ board = z->resource.start;
+ base_addr = board+A2065_LANCE;
+ ram_start = board+A2065_RAM;
+
+ if (!request_mem_region(base_addr, sizeof(struct lance_regs),
+ "Am7990"))
+ continue;
+ if (!request_mem_region(ram_start, A2065_RAM_SIZE, "RAM")) {
+ release_mem_region(base_addr,
+ sizeof(struct lance_regs));
+ continue;
+ }
+ strcpy(z->name, "A2065 Ethernet Card");
+ if (is_cbm) { /* Commodore */
+ dev->dev_addr[0] = 0x00;
+ dev->dev_addr[1] = 0x80;
+ dev->dev_addr[2] = 0x10;
+ } else { /* Ameristar */
+ dev->dev_addr[0] = 0x00;
+ dev->dev_addr[1] = 0x00;
+ dev->dev_addr[2] = 0x9f;
+ }
+ dev->dev_addr[3] = (z->rom.er_SerialNumber>>16) & 0xff;
+ dev->dev_addr[4] = (z->rom.er_SerialNumber>>8) & 0xff;
+ dev->dev_addr[5] = z->rom.er_SerialNumber & 0xff;
+ printk("%s: A2065 at 0x%08lx, Ethernet Address "
+ "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, board,
+ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+ dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+
+ init_etherdev(dev, 0);
+
+ dev->priv = kmalloc(sizeof(struct lance_private), GFP_KERNEL);
+ if (dev->priv == NULL) {
+ release_mem_region(base_addr,
+ sizeof(struct lance_regs));
+ release_mem_region(ram_start, A2065_RAM_SIZE);
+ return -ENOMEM;
}
+ priv = (struct lance_private *)dev->priv;
+ memset(priv, 0, sizeof(struct lance_private));
+
+ dev->base_addr = ZTWO_VADDR(base_addr);
+ dev->mem_start = ZTWO_VADDR(ram_start);
+ dev->mem_end = dev->mem_start+A2065_RAM_SIZE;
+
+ priv->ll = (volatile struct lance_regs *)dev->base_addr;
+ priv->init_block = (struct lance_init_block *)dev->mem_start;
+ priv->lance_init_block = (struct lance_init_block *)A2065_RAM;
+ priv->auto_select = 0;
+ priv->busmaster_regval = LE_C3_BSWP;
+
+ priv->lance_log_rx_bufs = LANCE_LOG_RX_BUFFERS;
+ priv->lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS;
+ priv->rx_ring_mod_mask = RX_RING_MOD_MASK;
+ priv->tx_ring_mod_mask = TX_RING_MOD_MASK;
+
+ dev->open = &lance_open;
+ dev->stop = &lance_close;
+ dev->hard_start_xmit = &lance_start_xmit;
+ dev->get_stats = &lance_get_stats;
+ dev->set_multicast_list = &lance_set_multicast;
+ dev->dma = 0;
+
+ ether_setup(dev);
+ init_timer(&priv->multicast_timer);
+ priv->multicast_timer.data = (unsigned long) dev;
+ priv->multicast_timer.function =
+ (void (*)(unsigned long)) &lance_set_multicast;
+
+ return(0);
}
return(-ENODEV);
}
@@ -845,7 +856,9 @@ void cleanup_module(void)
struct lance_private *priv = (struct lance_private *)a2065_dev.priv;
unregister_netdev(&a2065_dev);
- zorro_unconfig_board(priv->key, 0);
+ release_mem_region(ZTWO_PADDR(a2065_dev.base_addr),
+ sizeof(struct lance_regs));
+ release_mem_region(ZTWO_PADDR(a2065_dev.mem_start), A2065_RAM_SIZE);
kfree(priv);
}
diff --git a/drivers/net/a2065.h b/drivers/net/a2065.h
index db6e9e65d..f6e4d255f 100644
--- a/drivers/net/a2065.h
+++ b/drivers/net/a2065.h
@@ -169,9 +169,8 @@ struct lance_tx_desc {
* A2065 Expansion Board Structure
*/
-struct A2065Board {
- u_char Pad1[0x4000];
- volatile struct lance_regs Lance;
- u_char Pad2[0x3ffc];
- volatile u_char RAM[0x8000];
-};
+#define A2065_LANCE 0x4000
+
+#define A2065_RAM 0x8000
+#define A2065_RAM_SIZE 0x8000
+
diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c
index 75bff9f36..099bd1300 100644
--- a/drivers/net/ariadne.c
+++ b/drivers/net/ariadne.c
@@ -96,17 +96,15 @@ int ariadne_debug = 1;
*/
struct ariadne_private {
- struct AriadneBoard *board;
- struct TDRE *tx_ring[TX_RING_SIZE];
- struct RDRE *rx_ring[RX_RING_SIZE];
- u_short *tx_buff[TX_RING_SIZE];
- u_short *rx_buff[RX_RING_SIZE];
+ volatile struct TDRE *tx_ring[TX_RING_SIZE];
+ volatile struct RDRE *rx_ring[RX_RING_SIZE];
+ volatile u_short *tx_buff[TX_RING_SIZE];
+ volatile u_short *rx_buff[RX_RING_SIZE];
int cur_tx, cur_rx; /* The next free ring entry */
int dirty_tx; /* The ring entries to be free()ed. */
struct net_device_stats stats;
char tx_full;
unsigned long lock;
- unsigned int key;
};
@@ -134,7 +132,7 @@ static void set_multicast_list(struct net_device *dev);
#endif
-static void memcpyw(u_short *dest, u_short *src, int len)
+static void memcpyw(volatile u_short *dest, u_short *src, int len)
{
while (len >= 2) {
*(dest++) = *(src++);
@@ -147,71 +145,76 @@ static void memcpyw(u_short *dest, u_short *src, int len)
int __init ariadne_probe(struct net_device *dev)
{
- unsigned int key;
- const struct ConfigDev *cd;
- u_long board;
- struct ariadne_private *priv;
-
- /* Ethernet is part 0, Parallel is part 1 */
- if ((key = zorro_find(ZORRO_PROD_VILLAGE_TRONIC_ARIADNE, 0, 0))) {
- cd = zorro_get_board(key);
- if ((board = (u_long)cd->cd_BoardAddr)) {
- dev->dev_addr[0] = 0x00;
- dev->dev_addr[1] = 0x60;
- dev->dev_addr[2] = 0x30;
- dev->dev_addr[3] = (cd->cd_Rom.er_SerialNumber>>16)&0xff;
- dev->dev_addr[4] = (cd->cd_Rom.er_SerialNumber>>8)&0xff;
- dev->dev_addr[5] = cd->cd_Rom.er_SerialNumber&0xff;
- printk("%s: Ariadne at 0x%08lx, Ethernet Address "
- "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, board,
- dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
- dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
-
- init_etherdev(dev, 0);
-
- dev->priv = kmalloc(sizeof(struct ariadne_private), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- priv = (struct ariadne_private *)dev->priv;
- memset(priv, 0, sizeof(struct ariadne_private));
-
- priv->board = (struct AriadneBoard *)ZTWO_VADDR(board);
- priv->key = key;
-
- dev->open = &ariadne_open;
- dev->stop = &ariadne_close;
- dev->hard_start_xmit = &ariadne_start_xmit;
- dev->get_stats = &ariadne_get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- zorro_config_board(key, 0);
- return(0);
+ struct zorro_dev *z = NULL;
+
+ while ((z = zorro_find_device(ZORRO_PROD_VILLAGE_TRONIC_ARIADNE, z))) {
+ unsigned long board = z->resource.start;
+ unsigned long base_addr = board+ARIADNE_LANCE;
+ unsigned long ram_start = board+ARIADNE_RAM;
+
+ if (!request_mem_region(base_addr, sizeof(struct Am79C960),
+ "Am79C960"))
+ continue;
+ if (!request_mem_region(ram_start, ARIADNE_RAM_SIZE, "RAM")) {
+ release_mem_region(base_addr, sizeof(struct Am79C960));
+ continue;
}
+ strcpy(z->name, "Ariadne Ethernet Card and Parallel Ports");
+ dev->dev_addr[0] = 0x00;
+ dev->dev_addr[1] = 0x60;
+ dev->dev_addr[2] = 0x30;
+ dev->dev_addr[3] = (z->rom.er_SerialNumber>>16)&0xff;
+ dev->dev_addr[4] = (z->rom.er_SerialNumber>>8)&0xff;
+ dev->dev_addr[5] = z->rom.er_SerialNumber&0xff;
+ printk("%s: Ariadne at 0x%08lx, Ethernet Address "
+ "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, board,
+ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+ dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+
+ init_etherdev(dev, 0);
+
+ dev->priv = kmalloc(sizeof(struct ariadne_private), GFP_KERNEL);
+ if (dev->priv == NULL) {
+ release_mem_region(base_addr, sizeof(struct Am79C960));
+ release_mem_region(ram_start, ARIADNE_RAM_SIZE);
+ return -ENOMEM;
+ }
+ memset(dev->priv, 0, sizeof(struct ariadne_private));
+
+ dev->base_addr = ZTWO_VADDR(base_addr);
+ dev->mem_start = ZTWO_VADDR(ram_start);
+ dev->mem_end = dev->mem_start+ARIADNE_RAM_SIZE;
+
+ dev->open = &ariadne_open;
+ dev->stop = &ariadne_close;
+ dev->hard_start_xmit = &ariadne_start_xmit;
+ dev->get_stats = &ariadne_get_stats;
+ dev->set_multicast_list = &set_multicast_list;
+
+ return 0;
}
- return(ENODEV);
+ return -ENODEV;
}
static int ariadne_open(struct net_device *dev)
{
- struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
- struct AriadneBoard *board = priv->board;
- struct lancedata *lancedata;
+ volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
u_short in;
u_long version;
/* Reset the LANCE */
- in = board->Lance.Reset;
+ in = lance->Reset;
/* Stop the LANCE */
- board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */
- board->Lance.RDP = STOP;
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RDP = STOP;
/* Check the LANCE version */
- board->Lance.RAP = CSR88; /* Chip ID */
- version = swapw(board->Lance.RDP);
- board->Lance.RAP = CSR89; /* Chip ID */
- version |= swapw(board->Lance.RDP)<<16;
+ lance->RAP = CSR88; /* Chip ID */
+ version = swapw(lance->RDP);
+ lance->RAP = CSR89; /* Chip ID */
+ version |= swapw(lance->RDP)<<16;
if ((version & 0x00000fff) != 0x00000003) {
printk("ariadne_open: Couldn't find AMD Ethernet Chip\n");
return(-EAGAIN);
@@ -229,64 +232,62 @@ static int ariadne_open(struct net_device *dev)
ariadne_init_ring(dev);
/* Miscellaneous Stuff */
- board->Lance.RAP = CSR3; /* Interrupt Masks and Deferral Control */
- board->Lance.RDP = 0x0000;
- board->Lance.RAP = CSR4; /* Test and Features Control */
- board->Lance.RDP = DPOLL|APAD_XMT|MFCOM|RCVCCOM|TXSTRTM|JABM;
+ lance->RAP = CSR3; /* Interrupt Masks and Deferral Control */
+ lance->RDP = 0x0000;
+ lance->RAP = CSR4; /* Test and Features Control */
+ lance->RDP = DPOLL|APAD_XMT|MFCOM|RCVCCOM|TXSTRTM|JABM;
/* Set the Multicast Table */
- board->Lance.RAP = CSR8; /* Logical Address Filter, LADRF[15:0] */
- board->Lance.RDP = 0x0000;
- board->Lance.RAP = CSR9; /* Logical Address Filter, LADRF[31:16] */
- board->Lance.RDP = 0x0000;
- board->Lance.RAP = CSR10; /* Logical Address Filter, LADRF[47:32] */
- board->Lance.RDP = 0x0000;
- board->Lance.RAP = CSR11; /* Logical Address Filter, LADRF[63:48] */
- board->Lance.RDP = 0x0000;
+ lance->RAP = CSR8; /* Logical Address Filter, LADRF[15:0] */
+ lance->RDP = 0x0000;
+ lance->RAP = CSR9; /* Logical Address Filter, LADRF[31:16] */
+ lance->RDP = 0x0000;
+ lance->RAP = CSR10; /* Logical Address Filter, LADRF[47:32] */
+ lance->RDP = 0x0000;
+ lance->RAP = CSR11; /* Logical Address Filter, LADRF[63:48] */
+ lance->RDP = 0x0000;
/* Set the Ethernet Hardware Address */
- board->Lance.RAP = CSR12; /* Physical Address Register, PADR[15:0] */
- board->Lance.RDP = ((u_short *)&dev->dev_addr[0])[0];
- board->Lance.RAP = CSR13; /* Physical Address Register, PADR[31:16] */
- board->Lance.RDP = ((u_short *)&dev->dev_addr[0])[1];
- board->Lance.RAP = CSR14; /* Physical Address Register, PADR[47:32] */
- board->Lance.RDP = ((u_short *)&dev->dev_addr[0])[2];
+ lance->RAP = CSR12; /* Physical Address Register, PADR[15:0] */
+ lance->RDP = ((u_short *)&dev->dev_addr[0])[0];
+ lance->RAP = CSR13; /* Physical Address Register, PADR[31:16] */
+ lance->RDP = ((u_short *)&dev->dev_addr[0])[1];
+ lance->RAP = CSR14; /* Physical Address Register, PADR[47:32] */
+ lance->RDP = ((u_short *)&dev->dev_addr[0])[2];
/* Set the Init Block Mode */
- board->Lance.RAP = CSR15; /* Mode Register */
- board->Lance.RDP = 0x0000;
-
- lancedata = (struct lancedata *)offsetof(struct AriadneBoard, RAM);
+ lance->RAP = CSR15; /* Mode Register */
+ lance->RDP = 0x0000;
/* Set the Transmit Descriptor Ring Pointer */
- board->Lance.RAP = CSR30; /* Base Address of Transmit Ring */
- board->Lance.RDP = swloww((u_long)&lancedata->tx_ring);
- board->Lance.RAP = CSR31; /* Base Address of transmit Ring */
- board->Lance.RDP = swhighw((u_long)&lancedata->tx_ring);
+ lance->RAP = CSR30; /* Base Address of Transmit Ring */
+ lance->RDP = swloww(ARIADNE_RAM+offsetof(struct lancedata, tx_ring));
+ lance->RAP = CSR31; /* Base Address of transmit Ring */
+ lance->RDP = swhighw(ARIADNE_RAM+offsetof(struct lancedata, tx_ring));
/* Set the Receive Descriptor Ring Pointer */
- board->Lance.RAP = CSR24; /* Base Address of Receive Ring */
- board->Lance.RDP = swloww((u_long)&lancedata->rx_ring);
- board->Lance.RAP = CSR25; /* Base Address of Receive Ring */
- board->Lance.RDP = swhighw((u_long)&lancedata->rx_ring);
+ lance->RAP = CSR24; /* Base Address of Receive Ring */
+ lance->RDP = swloww(ARIADNE_RAM+offsetof(struct lancedata, rx_ring));
+ lance->RAP = CSR25; /* Base Address of Receive Ring */
+ lance->RDP = swhighw(ARIADNE_RAM+offsetof(struct lancedata, rx_ring));
/* Set the Number of RX and TX Ring Entries */
- board->Lance.RAP = CSR76; /* Receive Ring Length */
- board->Lance.RDP = swapw(((u_short)-RX_RING_SIZE));
- board->Lance.RAP = CSR78; /* Transmit Ring Length */
- board->Lance.RDP = swapw(((u_short)-TX_RING_SIZE));
+ lance->RAP = CSR76; /* Receive Ring Length */
+ lance->RDP = swapw(((u_short)-RX_RING_SIZE));
+ lance->RAP = CSR78; /* Transmit Ring Length */
+ lance->RDP = swapw(((u_short)-TX_RING_SIZE));
/* Enable Media Interface Port Auto Select (10BASE-2/10BASE-T) */
- board->Lance.RAP = ISACSR2; /* Miscellaneous Configuration */
- board->Lance.IDP = ASEL;
+ lance->RAP = ISACSR2; /* Miscellaneous Configuration */
+ lance->IDP = ASEL;
/* LED Control */
- board->Lance.RAP = ISACSR5; /* LED1 Status */
- board->Lance.IDP = PSE|XMTE;
- board->Lance.RAP = ISACSR6; /* LED2 Status */
- board->Lance.IDP = PSE|COLE;
- board->Lance.RAP = ISACSR7; /* LED3 Status */
- board->Lance.IDP = PSE|RCVE;
+ lance->RAP = ISACSR5; /* LED1 Status */
+ lance->IDP = PSE|XMTE;
+ lance->RAP = ISACSR6; /* LED2 Status */
+ lance->IDP = PSE|COLE;
+ lance->RAP = ISACSR7; /* LED3 Status */
+ lance->IDP = PSE|RCVE;
dev->tbusy = 0;
dev->interrupt = 0;
@@ -296,8 +297,8 @@ static int ariadne_open(struct net_device *dev)
"Ariadne Ethernet", dev))
return(-EAGAIN);
- board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */
- board->Lance.RDP = INEA|STRT;
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RDP = INEA|STRT;
MOD_INC_USE_COUNT;
@@ -308,45 +309,42 @@ static int ariadne_open(struct net_device *dev)
static void ariadne_init_ring(struct net_device *dev)
{
struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
- struct AriadneBoard *board = priv->board;
- struct lancedata *lancedata; /* LANCE point of view */
- struct lancedata *alancedata; /* Amiga point of view */
+ volatile struct lancedata *lancedata = (struct lancedata *)dev->mem_start;
int i;
priv->lock = 0, priv->tx_full = 0;
priv->cur_rx = priv->cur_tx = 0;
priv->dirty_tx = 0;
- lancedata = (struct lancedata *)offsetof(struct AriadneBoard, RAM);
- alancedata = (struct lancedata *)board->RAM;
-
/* Set up TX Ring */
for (i = 0; i < TX_RING_SIZE; i++) {
- alancedata->tx_ring[i].TMD0 = swloww((u_long)lancedata->tx_buff[i]);
- alancedata->tx_ring[i].TMD1 = swhighw((u_long)lancedata->tx_buff[i])|TF_STP|TF_ENP;
- alancedata->tx_ring[i].TMD2 = swapw((u_short)-PKT_BUF_SIZE);
- alancedata->tx_ring[i].TMD3 = 0;
- priv->tx_ring[i] = &alancedata->tx_ring[i];
- priv->tx_buff[i] = alancedata->tx_buff[i];
+ volatile struct TDRE *t = &lancedata->tx_ring[i];
+ t->TMD0 = swloww(ARIADNE_RAM+offsetof(struct lancedata, tx_buff[i]));
+ t->TMD1 = swhighw(ARIADNE_RAM+offsetof(struct lancedata, tx_buff[i])) |
+ TF_STP | TF_ENP;
+ t->TMD2 = swapw((u_short)-PKT_BUF_SIZE);
+ t->TMD3 = 0;
+ priv->tx_ring[i] = &lancedata->tx_ring[i];
+ priv->tx_buff[i] = lancedata->tx_buff[i];
#if 0
- printk("TX Entry %2d @ 0x%08x (LANCE 0x%08x), Buf @ 0x%08x (LANCE 0x%08x)\n",
- i, (int)&alancedata->tx_ring[i], (int)&lancedata->tx_ring[i],
- (int)alancedata->tx_buff[i], (int)lancedata->tx_buff[i]);
+ printk("TX Entry %2d at %p, Buf at %p\n", i, &lancedata->tx_ring[i],
+ lancedata->tx_buff[i]);
#endif
}
/* Set up RX Ring */
for (i = 0; i < RX_RING_SIZE; i++) {
- alancedata->rx_ring[i].RMD0 = swloww((u_long)lancedata->rx_buff[i]);
- alancedata->rx_ring[i].RMD1 = swhighw((u_long)lancedata->rx_buff[i])|RF_OWN;
- alancedata->rx_ring[i].RMD2 = swapw((u_short)-PKT_BUF_SIZE);
- alancedata->rx_ring[i].RMD3 = 0x0000;
- priv->rx_ring[i] = &alancedata->rx_ring[i];
- priv->rx_buff[i] = alancedata->rx_buff[i];
+ volatile struct RDRE *r = &lancedata->rx_ring[i];
+ r->RMD0 = swloww(ARIADNE_RAM+offsetof(struct lancedata, rx_buff[i]));
+ r->RMD1 = swhighw(ARIADNE_RAM+offsetof(struct lancedata, rx_buff[i])) |
+ RF_OWN;
+ r->RMD2 = swapw((u_short)-PKT_BUF_SIZE);
+ r->RMD3 = 0x0000;
+ priv->rx_ring[i] = &lancedata->rx_ring[i];
+ priv->rx_buff[i] = lancedata->rx_buff[i];
#if 0
- printk("RX Entry %2d @ 0x%08x (LANCE 0x%08x), Buf @ 0x%08x (LANCE 0x%08x)\n",
- i, (int)&alancedata->rx_ring[i], (int)&lancedata->rx_ring[i],
- (int)alancedata->rx_buff[i], (int)lancedata->rx_buff[i]);
+ printk("RX Entry %2d at %p, Buf at %p\n", i, &lancedata->rx_ring[i],
+ lancedata->rx_buff[i]);
#endif
}
}
@@ -355,24 +353,24 @@ static void ariadne_init_ring(struct net_device *dev)
static int ariadne_close(struct net_device *dev)
{
struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
- struct AriadneBoard *board = priv->board;
+ volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
dev->start = 0;
dev->tbusy = 1;
- board->Lance.RAP = CSR112; /* Missed Frame Count */
- priv->stats.rx_missed_errors = swapw(board->Lance.RDP);
- board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RAP = CSR112; /* Missed Frame Count */
+ priv->stats.rx_missed_errors = swapw(lance->RDP);
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
if (ariadne_debug > 1) {
printk("%s: Shutting down ethercard, status was %2.2x.\n", dev->name,
- board->Lance.RDP);
+ lance->RDP);
printk("%s: %lu packets missed\n", dev->name,
priv->stats.rx_missed_errors);
}
/* We stop the LANCE here -- it occasionally polls memory if we don't. */
- board->Lance.RDP = STOP;
+ lance->RDP = STOP;
free_irq(IRQ_AMIGA_PORTS, dev);
@@ -385,21 +383,18 @@ static int ariadne_close(struct net_device *dev)
static void ariadne_interrupt(int irq, void *data, struct pt_regs *fp)
{
struct net_device *dev = (struct net_device *)data;
+ volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
struct ariadne_private *priv;
- struct AriadneBoard *board;
- int csr0, boguscnt = 10;
+ int csr0, boguscnt;
if (dev == NULL) {
printk("ariadne_interrupt(): irq for unknown device.\n");
return;
}
- priv = (struct ariadne_private *)dev->priv;
- board = priv->board;
-
- board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
- if (!(board->Lance.RDP & INTR)) /* Check if any interrupt has been */
+ if (!(lance->RDP & INTR)) /* Check if any interrupt has been */
return; /* generated by the board. */
if (dev->interrupt)
@@ -407,14 +402,17 @@ static void ariadne_interrupt(int irq, void *data, struct pt_regs *fp)
dev->interrupt = 1;
- while ((csr0 = board->Lance.RDP) & (ERR|RINT|TINT) && --boguscnt >= 0) {
+ priv = (struct ariadne_private *)dev->priv;
+
+ boguscnt = 10;
+ while ((csr0 = lance->RDP) & (ERR|RINT|TINT) && --boguscnt >= 0) {
/* Acknowledge all of the current interrupt sources ASAP. */
- board->Lance.RDP = csr0 & ~(INEA|TDMD|STOP|STRT|INIT);
+ lance->RDP = csr0 & ~(INEA|TDMD|STOP|STRT|INIT);
#if 0
if (ariadne_debug > 5) {
printk("%s: interrupt csr0=%#2.2x new csr=%#2.2x.", dev->name,
- csr0, board->Lance.RDP);
+ csr0, lance->RDP);
printk("[");
if (csr0 & INTR)
printk(" INTR");
@@ -484,7 +482,7 @@ static void ariadne_interrupt(int irq, void *data, struct pt_regs *fp)
printk("%s: Tx FIFO error! Status %4.4x.\n", dev->name,
csr0);
/* Restart the chip. */
- board->Lance.RDP = STRT;
+ lance->RDP = STRT;
}
} else {
if (status & (TF_MORE|TF_ONE))
@@ -522,18 +520,18 @@ static void ariadne_interrupt(int irq, void *data, struct pt_regs *fp)
printk("%s: Bus master arbitration failure, status %4.4x.\n",
dev->name, csr0);
/* Restart the chip. */
- board->Lance.RDP = STRT;
+ lance->RDP = STRT;
}
}
/* Clear any other interrupt, and set interrupt enable. */
- board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */
- board->Lance.RDP = INEA|BABL|CERR|MISS|MERR|IDON;
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RDP = INEA|BABL|CERR|MISS|MERR|IDON;
#if 0
if (ariadne_debug > 4)
- printk("%s: exiting interrupt, csr%d=%#4.4x.\n", dev->name,
- board->Lance.RAP, board->Lance.RDP);
+ printk("%s: exiting interrupt, csr%d=%#4.4x.\n", dev->name, lance->RAP,
+ lance->RDP);
#endif
dev->interrupt = 0;
@@ -544,7 +542,7 @@ static void ariadne_interrupt(int irq, void *data, struct pt_regs *fp)
static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
- struct AriadneBoard *board = priv->board;
+ volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
int entry;
unsigned long flags;
@@ -553,10 +551,10 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev)
int tickssofar = jiffies - dev->trans_start;
if (tickssofar < 20)
return(1);
- board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
printk("%s: transmit timed out, status %4.4x, resetting.\n", dev->name,
- board->Lance.RDP);
- board->Lance.RDP = STOP;
+ lance->RDP);
+ lance->RDP = STOP;
priv->stats.tx_errors++;
#ifndef final_version
{
@@ -566,17 +564,20 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev)
priv->cur_rx);
for (i = 0 ; i < RX_RING_SIZE; i++)
printk("%s %08x %04x %04x", i & 0x3 ? "" : "\n ",
- (swapw((priv->rx_ring[i]->RMD1))<<16)|swapw(priv->rx_ring[i]->RMD0),
- swapw(-priv->rx_ring[i]->RMD2), swapw(priv->rx_ring[i]->RMD3));
+ (swapw((priv->rx_ring[i]->RMD1))<<16) |
+ swapw(priv->rx_ring[i]->RMD0),
+ swapw(-priv->rx_ring[i]->RMD2),
+ swapw(priv->rx_ring[i]->RMD3));
for (i = 0 ; i < TX_RING_SIZE; i++)
printk("%s %08x %04x %04x", i & 0x3 ? "" : "\n ",
- (swapw((priv->tx_ring[i]->TMD1))<<16)|swapw(priv->tx_ring[i]->TMD0),
+ (swapw((priv->tx_ring[i]->TMD1))<<16) |
+ swapw(priv->tx_ring[i]->TMD0),
swapw(-priv->tx_ring[i]->TMD2), priv->tx_ring[i]->TMD3);
printk("\n");
}
#endif
ariadne_init_ring(dev);
- board->Lance.RDP = INEA|STRT;
+ lance->RDP = INEA|STRT;
dev->tbusy = 0;
dev->trans_start = jiffies;
@@ -586,10 +587,10 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev)
#if 0
if (ariadne_debug > 3) {
- board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
printk("%s: ariadne_start_xmit() called, csr0 %4.4x.\n", dev->name,
- board->Lance.RDP);
- board->Lance.RDP = 0x0000;
+ lance->RDP);
+ lance->RDP = 0x0000;
}
#endif
@@ -675,8 +676,8 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
/* Trigger an immediate send poll. */
- board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */
- board->Lance.RDP = INEA|TDMD;
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RDP = INEA|TDMD;
dev->trans_start = jiffies;
@@ -782,16 +783,16 @@ static int ariadne_rx(struct net_device *dev)
static struct net_device_stats *ariadne_get_stats(struct net_device *dev)
{
struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
- struct AriadneBoard *board = priv->board;
+ volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
short saved_addr;
unsigned long flags;
save_flags(flags);
cli();
- saved_addr = board->Lance.RAP;
- board->Lance.RAP = CSR112; /* Missed Frame Count */
- priv->stats.rx_missed_errors = swapw(board->Lance.RDP);
- board->Lance.RAP = saved_addr;
+ saved_addr = lance->RAP;
+ lance->RAP = CSR112; /* Missed Frame Count */
+ priv->stats.rx_missed_errors = swapw(lance->RDP);
+ lance->RAP = saved_addr;
restore_flags(flags);
return(&priv->stats);
@@ -806,18 +807,18 @@ static struct net_device_stats *ariadne_get_stats(struct net_device *dev)
*/
static void set_multicast_list(struct net_device *dev)
{
- struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
- struct AriadneBoard *board = priv->board;
+ volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
/* We take the simple way out and always enable promiscuous mode. */
- board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */
- board->Lance.RDP = STOP; /* Temporarily stop the lance. */
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RDP = STOP; /* Temporarily stop the lance. */
+ ariadne_init_ring(dev);
if (dev->flags & IFF_PROMISC) {
/* Log any net taps. */
printk("%s: Promiscuous mode enabled.\n", dev->name);
- board->Lance.RAP = CSR15; /* Mode Register */
- board->Lance.RDP = PROM; /* Set promiscuous mode */
+ lance->RAP = CSR15; /* Mode Register */
+ lance->RDP = PROM; /* Set promiscuous mode */
} else {
short multicast_table[4];
int num_addrs = dev->mc_count;
@@ -826,15 +827,15 @@ static void set_multicast_list(struct net_device *dev)
memset(multicast_table, (num_addrs == 0) ? 0 : -1,
sizeof(multicast_table));
for (i = 0; i < 4; i++) {
- board->Lance.RAP = CSR8+(i<<8); /* Logical Address Filter */
- board->Lance.RDP = swapw(multicast_table[i]);
+ lance->RAP = CSR8+(i<<8); /* Logical Address Filter */
+ lance->RDP = swapw(multicast_table[i]);
}
- board->Lance.RAP = CSR15; /* Mode Register */
- board->Lance.RDP = 0x0000; /* Unset promiscuous mode */
+ lance->RAP = CSR15; /* Mode Register */
+ lance->RDP = 0x0000; /* Unset promiscuous mode */
}
- board->Lance.RAP = CSR0; /* PCnet-ISA Controller Status */
- board->Lance.RDP = INEA|STRT|IDON; /* Resume normal operation. */
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RDP = INEA|STRT|IDON; /* Resume normal operation. */
}
@@ -866,7 +867,9 @@ void cleanup_module(void)
struct ariadne_private *priv = (struct ariadne_private *)ariadne_dev.priv;
unregister_netdev(&ariadne_dev);
- zorro_unconfig_board(priv->key, 0);
+ release_mem_region(ZTWO_PADDR(ariadne_dev.base_addr),
+ sizeof(struct Am79C960));
+ release_mem_region(ZTWO_PADDR(ariadne_dev.mem_start), ARIADNE_RAM_SIZE);
kfree(priv);
}
diff --git a/drivers/net/ariadne.h b/drivers/net/ariadne.h
index 2ba188134..f7913d5a3 100644
--- a/drivers/net/ariadne.h
+++ b/drivers/net/ariadne.h
@@ -403,12 +403,13 @@ struct MC68230 {
* Ariadne Expansion Board Structure
*/
-struct AriadneBoard {
- u_char Pad1[0x360];
- struct Am79C960 Lance;
- u_char Pad2[0xc88];
- struct MC68230 PiT;
- u_char Pad3[0x2fc0];
- volatile u_short BootPROM[0x2000]; /* I guess it's here :-) */
- volatile u_short RAM[0x4000]; /* Always access WORDs!! */
-};
+#define ARIADNE_LANCE 0x360
+
+#define ARIADNE_PIT 0x1000
+
+#define ARIADNE_BOOTPROM 0x4000 /* I guess it's here :-) */
+#define ARIADNE_BOOTPROM_SIZE 0x4000
+
+#define ARIADNE_RAM 0x8000 /* Always access WORDs!! */
+#define ARIADNE_RAM_SIZE 0x8000
+
diff --git a/drivers/net/ariadne2.c b/drivers/net/ariadne2.c
index 10edf1e79..14ab3f321 100644
--- a/drivers/net/ariadne2.c
+++ b/drivers/net/ariadne2.c
@@ -66,8 +66,7 @@
#define WORDSWAP(a) ((((a)>>8)&0xff) | ((a)<<8))
int ariadne2_probe(struct net_device *dev);
-static int ariadne2_init(struct net_device *dev, unsigned int key,
- unsigned long board);
+static int ariadne2_init(struct net_device *dev, unsigned long board);
static int ariadne2_open(struct net_device *dev);
static int ariadne2_close(struct net_device *dev);
@@ -83,25 +82,26 @@ static void ariadne2_block_output(struct net_device *dev, const int count,
int __init ariadne2_probe(struct net_device *dev)
{
- unsigned int key;
- const struct ConfigDev *cd;
- u_long board;
+ struct zorro_dev *z = NULL;
+ unsigned long board, ioaddr;
int err;
- if ((key = zorro_find(ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, 0, 0))) {
- cd = zorro_get_board(key);
- if ((board = (u_long)cd->cd_BoardAddr)) {
- if ((err = ariadne2_init(dev, key, ZTWO_VADDR(board))))
- return err;
- zorro_config_board(key, 0);
- return 0;
+ while ((z = zorro_find_device(ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, z))) {
+ board = z->resource.start;
+ ioaddr = board+ARIADNE2_BASE*2;
+ if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, "RTL8019AS"))
+ continue;
+ if ((err = ariadne2_init(dev, ZTWO_VADDR(board)))) {
+ release_mem_region(ioaddr, NE_IO_EXTENT*2);
+ return err;
}
+ strcpy(z->name, "AriadNE2 Ethernet");
+ return 0;
}
return -ENODEV;
}
-static int __init ariadne2_init(struct net_device *dev, unsigned int key,
- unsigned long board)
+static int __init ariadne2_init(struct net_device *dev, unsigned long board)
{
int i;
unsigned char SA_prom[32];
@@ -111,7 +111,7 @@ static int __init ariadne2_init(struct net_device *dev, unsigned int key,
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
};
- int ioaddr = board+ARIADNE2_BASE*2;
+ unsigned long ioaddr = board+ARIADNE2_BASE*2;
if (load_8390_module("ariadne2.c"))
return -ENOSYS;
@@ -189,7 +189,6 @@ static int __init ariadne2_init(struct net_device *dev, unsigned int key,
printk("Unable to get memory for dev->priv.\n");
return -ENOMEM;
}
- ((struct ei_device *)dev->priv)->priv = key;
for(i = 0; i < ETHER_ADDR_LEN; i++) {
#ifdef DEBUG
@@ -417,10 +416,9 @@ int init_module(void)
void cleanup_module(void)
{
- unsigned int key = ((struct ei_device *)ariadne2_dev.priv)->priv;
free_irq(IRQ_AMIGA_PORTS, &ariadne2_dev);
+ release_mem_region(ZTWO_PADDR(ariadne2_dev.base_addr), NE_IO_EXTENT*2);
unregister_netdev(&ariadne2_dev);
- zorro_unconfig_board(key, 0);
unlock_8390_module();
}
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
index e319463be..0b04615ef 100644
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -9,6 +9,7 @@
* Many modifications, and currently maintained, by
* Philip Blundell <Philip.Blundell@pobox.com>
* Added the Compaq LTE Alan Cox <alan@redhat.com>
+ * Added MCA support Adam Fritzler <mid@auk.cx>
*
* Note - this driver is experimental still - it has problems on faster
* machines. Someone needs to sit down and go through it line by line with
@@ -120,6 +121,7 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/malloc.h>
+#include <linux/mca.h>
#include <linux/spinlock.h>
@@ -232,6 +234,16 @@ static unsigned short start_code[] = {
/* maps irq number to EtherExpress magic value */
static char irqrmap[] = { 0,0,1,2,3,4,0,0,0,1,5,6,0,0,0,0 };
+#ifdef CONFIG_MCA
+/* mapping of the first four bits of the second POS register */
+static unsigned short mca_iomap[] = {
+ 0x270, 0x260, 0x250, 0x240, 0x230, 0x220, 0x210, 0x200,
+ 0x370, 0x360, 0x350, 0x340, 0x330, 0x320, 0x310, 0x300
+};
+/* bits 5-7 of the second POS register */
+static char mca_irqmap[] = { 12, 9, 3, 4, 5, 10, 11, 15 };
+#endif
+
/*
* Prototypes for Linux interface
*/
@@ -331,6 +343,55 @@ int __init express_probe(struct net_device *dev)
static unsigned short ports[] = { 0x300,0x310,0x270,0x320,0x340,0 };
unsigned short ioaddr = dev->base_addr;
+ dev->if_port = 0xff; /* not set */
+
+#ifdef CONFIG_MCA
+ if (MCA_bus) {
+ int slot = 0;
+
+ /*
+ * Only find one card at a time. Subsequent calls
+ * will find others, however, proper multicard MCA
+ * probing and setup can't be done with the
+ * old-style Space.c init routines. -- ASF
+ */
+ while (slot != MCA_NOTFOUND) {
+ int pos0, pos1;
+
+ slot = mca_find_unused_adapter(0x628B, slot);
+ if (slot == MCA_NOTFOUND)
+ break;
+
+ pos0 = mca_read_stored_pos(slot, 2);
+ pos1 = mca_read_stored_pos(slot, 3);
+ ioaddr = mca_iomap[pos1&0xf];
+
+ dev->irq = mca_irqmap[(pos1>>4)&0x7];
+
+ /*
+ * XXX: Transciever selection is done
+ * differently on the MCA version.
+ * How to get it to select something
+ * other than external/AUI is currently
+ * unknown. This code is just for looks. -- ASF
+ */
+ if ((pos0 & 0x7) == 0x1)
+ dev->if_port = AUI;
+ else if ((pos0 & 0x7) == 0x5) {
+ if (pos1 & 0x80)
+ dev->if_port = BNC;
+ else
+ dev->if_port = TPE;
+ }
+
+ mca_set_adapter_name(slot, "Intel EtherExpress 16 MCA");
+ mca_set_adapter_procfn(slot, NULL, dev);
+ mca_mark_as_used(slot);
+
+ break;
+ }
+ }
+#endif
if (ioaddr&0xfe00)
return eexp_hw_probe(dev,ioaddr);
else if (ioaddr)
@@ -522,7 +583,9 @@ static void unstick_cu(struct net_device *dev)
static int eexp_xmit(struct sk_buff *buf, struct net_device *dev)
{
struct net_local *lp = (struct net_local *)dev->priv;
+#ifdef CONFIG_SMP
unsigned long flags;
+#endif
#if NET_DEBUG > 6
printk(KERN_DEBUG "%s: eexp_xmit()\n", dev->name);
@@ -1010,8 +1073,10 @@ static int __init eexp_hw_probe(struct net_device *dev, unsigned short ioaddr)
if (!dev->irq)
dev->irq = irqmap[setupval>>13];
- dev->if_port = !(setupval & 0x1000) ? AUI :
- eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TPE : BNC;
+ if (dev->if_port == 0xff) {
+ dev->if_port = !(setupval & 0x1000) ? AUI :
+ eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TPE : BNC;
+ }
buswidth = !((setupval & 0x400) >> 10);
}
diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c
index 483d94e45..922b28437 100644
--- a/drivers/net/hydra.c
+++ b/drivers/net/hydra.c
@@ -80,14 +80,11 @@
*/
struct hydra_private
{
- u8 *hydra_base;
- u8 *hydra_nic_base;
u16 tx_page_start;
u16 rx_page_start;
u16 rx_page_stop;
u16 next_pkt;
struct net_device_stats stats;
- unsigned int key;
};
static int hydra_open(struct net_device *dev);
@@ -159,52 +156,53 @@ static void memcpyw(u16 *dest, u16 *src, int len)
int __init hydra_probe(struct net_device *dev)
{
- struct hydra_private *priv;
- u32 board;
- unsigned int key;
- const struct ConfigDev *cd;
+ struct zorro_dev *z = NULL;
int j;
#ifdef HYDRA_DEBUG
printk("hydra_probe(%x)\n", dev);
#endif
- if ((key = zorro_find(ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET, 0, 0)))
- {
- cd = zorro_get_board(key);
- if((board = (u32) cd->cd_BoardAddr))
- {
- for(j = 0; j < ETHER_ADDR_LEN; j++)
- dev->dev_addr[j] = *((u8 *)ZTWO_VADDR(board + HYDRA_ADDRPROM + 2*j));
-
- printk("%s: hydra at 0x%08x, address %02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n",
- dev->name, (int)board, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
- dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
- init_etherdev(dev, 0);
-
- dev->priv = kmalloc(sizeof(struct hydra_private), GFP_KERNEL);
- priv = (struct hydra_private *)dev->priv;
- memset(priv, 0, sizeof(struct hydra_private));
-
- priv->hydra_base = (u8 *) ZTWO_VADDR(board);
- priv->hydra_nic_base = (u8 *) ZTWO_VADDR(board) + HYDRA_NIC_BASE;
- priv->key = key;
-
- dev->open = &hydra_open;
- dev->stop = &hydra_close;
- dev->hard_start_xmit = &hydra_start_xmit;
- dev->get_stats = &hydra_get_stats;
+ while ((z = zorro_find_device(ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET, z))) {
+ unsigned long board = z->resource.start;
+ unsigned long base_addr = board+HYDRA_NIC_BASE;
+
+ if (!request_mem_region(base_addr, 0x20, "NS8390"))
+ continue;
+ if (!request_mem_region(board, 0x4000, "RAM")) {
+ release_mem_region(base_addr, 0x20);
+ continue;
+ }
+ strcpy(z->name, "Hydra Ethernet Card");
+
+ for(j = 0; j < ETHER_ADDR_LEN; j++)
+ dev->dev_addr[j] = *((u8 *)ZTWO_VADDR(board + HYDRA_ADDRPROM + 2*j));
+
+ printk("%s: hydra at 0x%08x, address %02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n",
+ dev->name, (int)board, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+ dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+ init_etherdev(dev, 0);
+
+ dev->priv = kmalloc(sizeof(struct hydra_private), GFP_KERNEL);
+ memset(dev->priv, 0, sizeof(struct hydra_private));
+
+ dev->base_addr = ZTWO_VADDR(base_addr);
+ dev->mem_start = ZTWO_VADDR(board);
+ dev->mem_end = dev->mem_start+0x4000;
+
+ dev->open = &hydra_open;
+ dev->stop = &hydra_close;
+ dev->hard_start_xmit = &hydra_start_xmit;
+ dev->get_stats = &hydra_get_stats;
#ifdef HAVE_MULTICAST
- dev->set_multicast_list = &set_multicast_list;
+ dev->set_multicast_list = &set_multicast_list;
#endif
-
- /*
- * Cannot yet do multicast
- */
- dev->flags&=~IFF_MULTICAST;
- zorro_config_board(key, 0);
- return(0);
- }
+
+ /*
+ * Cannot yet do multicast
+ */
+ dev->flags&=~IFF_MULTICAST;
+ return(0);
}
return(-ENODEV);
}
@@ -213,7 +211,7 @@ int __init hydra_probe(struct net_device *dev)
static int hydra_open(struct net_device *dev)
{
struct hydra_private *priv = (struct hydra_private *)dev->priv;
- volatile u8 *nicbase = priv->hydra_nic_base;
+ volatile u8 *nicbase = (u8 *)dev->base_addr;
int i;
#ifdef HYDRA_DEBUG
@@ -295,7 +293,7 @@ static int hydra_open(struct net_device *dev)
static int hydra_close(struct net_device *dev)
{
struct hydra_private *priv = (struct hydra_private *)dev->priv;
- volatile u8 *nicbase = priv->hydra_nic_base;
+ volatile u8 *nicbase = (u8 *)dev->base_addr;
int n = 5000;
dev->start = 0;
@@ -340,7 +338,7 @@ static void hydra_interrupt(int irq, void *data, struct pt_regs *fp)
dev->interrupt = 1;
priv = (struct hydra_private *) dev->priv;
- nicbase = (u8 *) priv->hydra_nic_base;
+ nicbase = (u8 *)dev->base_addr;
/* select page 0 */
WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA);
@@ -437,7 +435,7 @@ static void hydra_interrupt(int irq, void *data, struct pt_regs *fp)
static int hydra_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct hydra_private *priv = (struct hydra_private *)dev->priv;
- volatile u8 *nicbase = priv->hydra_nic_base;
+ volatile u8 *nicbase = (u8 *)dev->base_addr;
int len, len1;
/* Transmitter timeout, serious problems. */
@@ -491,16 +489,17 @@ static int hydra_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* make sure we've got an even number of bytes to copy to hydra's mem */
if(len & 1) len++;
- if((u32)(priv->hydra_base + (priv->tx_page_start << 8)) < 0x80000000)
- printk("weirdness: memcpyw(txbuf, skbdata, len): txbuf = 0x%x\n", (u_int)(priv->hydra_base+(priv->tx_page_start<<8)));
+ if((u32)(dev->mem_start + (priv->tx_page_start << 8)) < 0x80000000)
+ printk("weirdness: memcpyw(txbuf, skbdata, len): txbuf = 0x%x\n", (u_int)(dev->mem_start+(priv->tx_page_start<<8)));
/* copy the packet data to the transmit buffer
in the ethernet card RAM */
- memcpyw((u16 *)(priv->hydra_base + (priv->tx_page_start << 8)),
+ memcpyw((u16 *)(dev->mem_start + (priv->tx_page_start << 8)),
(u16 *)skb->data, len);
/* clear the unused space */
for(; len1<len; len1++)
- (u16)*(priv->hydra_base + (priv->tx_page_start<<8) + len1) = 0;
+ (u16)*((u8 *)dev->mem_start + (priv->tx_page_start<<8) + len1)
+ = 0;
dev_kfree_skb(skb);
priv->stats.tx_packets++;
@@ -536,7 +535,7 @@ static void __inline__ hydra_rx(struct net_device *dev, struct hydra_private *pr
WRITE_REG(NIC_CR, CR_PAGE1 | CR_NODMA | CR_START); /* page 1 */
while(priv->next_pkt != READ_REG(NIC_CURR)) /* should read this only once? */
{
- board_ram_ptr = (u16 *)(priv->hydra_base + (priv->next_pkt << 8));
+ board_ram_ptr = (u16 *)(dev->mem_start + (priv->next_pkt << 8));
#ifdef HYDRA_DEBUG
printk("next_pkt = 0x%x, board_ram_ptr = 0x%x\n", priv->next_pkt, board_ram_ptr);
@@ -577,7 +576,7 @@ static void __inline__ hydra_rx(struct net_device *dev, struct hydra_private *pr
len1 = ((priv->rx_page_stop - priv->next_pkt)<<8)-4;
memcpyw((u16 *)skb_put(skb, len1), (u16 *)(board_ram_ptr+2), len1);
- memcpyw((u16 *)skb_put(skb, pkt_len-len1), (u16 *)(priv->hydra_base+(priv->rx_page_start<<8)), pkt_len-len1);
+ memcpyw((u16 *)skb_put(skb, pkt_len-len1), (u16 *)(dev->mem_start+(priv->rx_page_start<<8)), pkt_len-len1);
#ifdef HYDRA_DEBUG
printk("wrapped packet: %d/%d bytes\n", len1, pkt_len-len1);
@@ -638,7 +637,7 @@ static struct net_device_stats *hydra_get_stats(struct net_device *dev)
{
struct hydra_private *priv = (struct hydra_private *)dev->priv;
#if 0
- u8 *board = priv->hydra_base;
+ u8 *board = (u8 *)dev->mem_start;
short saved_addr;
#endif
@@ -651,7 +650,7 @@ static struct net_device_stats *hydra_get_stats(struct net_device *dev)
static void set_multicast_list(struct net_device *dev, int num_addrs, void *addrs)
{
struct hydra_private *priv = (struct hydra_private *)dev->priv;
- u8 *board = priv->hydra_base;
+ u8 *board = (u8 *)dev->mem_start;
/* yes, this code is also waiting for someone to complete.. :) */
/* (personally i don't care about multicasts at all :) */
@@ -688,7 +687,8 @@ void cleanup_module(void)
struct hydra_private *priv = (struct hydra_private *)hydra_dev.priv;
unregister_netdev(&hydra_dev);
- zorro_unconfig_board(priv->key, 0);
+ release_mem_region(ZTWO_PADDR(hydra_dev.base_addr), 0x20);
+ release_mem_region(ZTWO_PADDR(hydra_dev.mem_start), 0x4000);
kfree(priv);
}
diff --git a/drivers/net/pcmcia/Config.in b/drivers/net/pcmcia/Config.in
index be83dc205..243b5c896 100644
--- a/drivers/net/pcmcia/Config.in
+++ b/drivers/net/pcmcia/Config.in
@@ -31,8 +31,6 @@ if [ "$CONFIG_NET_PCMCIA" = "y" ]; then
fi
fi
-endmenu
-
if [ "$CONFIG_PCMCIA_3C589" = "y" -o "$CONFIG_PCMCIA_3C574" = "y" -o \
"$CONFIG_PCMCIA_FMVJ18X" = "y" -o "$CONFIG_PCMCIA_PCNET" = "y" -o \
"$CONFIG_PCMCIA_NMCLAN" = "y" -o "$CONFIG_PCMCIA_SMC91C92" = "y" -o \
@@ -40,3 +38,5 @@ if [ "$CONFIG_PCMCIA_3C589" = "y" -o "$CONFIG_PCMCIA_3C574" = "y" -o \
"$CONFIG_PCMCIA_NETWAVE" = "y" -o "$CONFIG_PCMCIA_WAVELAN" = "y" ]; then
define_bool CONFIG_PCMCIA_NETCARD y
fi
+
+endmenu
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 471afb6d3..9e802387a 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -13,7 +13,7 @@
* This driver is for PCnet32 and PCnetPCI based ethercards
*/
-static const char *version = "pcnet32.c:v1.23ac 21.9.1999 tsbogend@alpha.franken.de\n";
+static const char *version = "pcnet32.c:v1.25kf 26.9.1999 tsbogend@alpha.franken.de\n";
#include <linux/config.h>
#include <linux/module.h>
@@ -46,12 +46,13 @@ static const char *version = "pcnet32.c:v1.23ac 21.9.1999 tsbogend@alpha.franken
static unsigned int pcnet32_portlist[] __initdata = {0x300, 0x320, 0x340, 0x360, 0};
static int pcnet32_debug = 1;
+static int tx_start = 1; /* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chip vers) */
#ifdef MODULE
static struct net_device *pcnet32_dev = NULL;
#endif
-static const int max_interrupt_work = 20;
+static const int max_interrupt_work = 80;
static const int rx_copybreak = 200;
#define PORT_AUI 0x00
@@ -159,7 +160,12 @@ static int full_duplex[MAX_UNITS] = {0, };
* Michael Richard <mcr@solidum.com>)
* added chip id for 79c973/975 (thanks to Zach Brown <zab@zabbo.net>)
* v1.23 fixed small bug, when manual selecting MII speed/duplex
- * v1.23ac Added SMP spinlocking - Alan Cox <alan@redhat.com>
+ * v1.24 Applied Thomas' patch to use TxStartPoint and thus decrease TxFIFO
+ * underflows. Added tx_start_pt module parameter. Increased
+ * TX_RING_SIZE from 16 to 32. Added #ifdef'd code to use DXSUFLO
+ * for FAST[+] chipsets. <kaf@fc.hp.com>
+ * v1.24ac Added SMP spinlocking - Alan Cox <alan@redhat.com>
+ * v1.25kf Added No Interrupt on successful Tx for some Tx's <kaf@fc.hp.com>
*/
@@ -170,7 +176,7 @@ static int full_duplex[MAX_UNITS] = {0, };
*/
#ifndef PCNET32_LOG_TX_BUFFERS
#define PCNET32_LOG_TX_BUFFERS 4
-#define PCNET32_LOG_RX_BUFFERS 4
+#define PCNET32_LOG_RX_BUFFERS 5
#endif
#define TX_RING_SIZE (1 << (PCNET32_LOG_TX_BUFFERS))
@@ -260,12 +266,16 @@ struct pcnet32_private {
struct pcnet32_access a;
void *origmem;
spinlock_t lock; /* Guard lock */
- int cur_rx, cur_tx; /* The next free ring entry */
- int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
+ unsigned int cur_rx, cur_tx; /* The next free ring entry */
+ unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
struct net_device_stats stats;
char tx_full;
int options;
int shared_irq:1, /* shared irq possible */
+ ltint:1,
+#ifdef DO_DXSUFLO
+ dxsuflo:1, /* disable transmit stop on uflo */
+#endif
full_duplex:1, /* full duplex possible */
mii:1; /* mii port available */
#ifdef MODULE
@@ -304,6 +314,10 @@ static struct pcnet32_pci_id_info pcnet32_tbl[] = {
PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, 0, 0,
PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE,
pcnet32_probe1},
+ { "AMD PCnetPCI series (IBM)",
+ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, 0x1014, 0x2000,
+ PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE,
+ pcnet32_probe1},
{ "AMD PCnetHome series",
PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_PCNETHOME, 0, 0,
PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE,
@@ -453,8 +467,8 @@ int __init pcnet32_probe(void)
int chip_idx;
u16 sdid,svid;
- pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &sdid);
- pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &svid);
+ pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &svid);
+ pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &sdid);
for (chip_idx = 0; pcnet32_tbl[chip_idx].vendor_id; chip_idx++)
if ((pdev->vendor == pcnet32_tbl[chip_idx].vendor_id) &&
(pdev->device == pcnet32_tbl[chip_idx].device_id) &&
@@ -520,6 +534,10 @@ pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int car
{
struct pcnet32_private *lp;
int i,media,fdx = 0, mii = 0, fset = 0;
+#ifdef DO_DXSUFLO
+ int dxsuflo = 0;
+#endif
+ int ltint = 0;
int chip_version;
char *chipname;
char *priv;
@@ -562,6 +580,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int car
case 0x2623:
chipname = "PCnet/FAST 79C971";
fdx = 1; mii = 1; fset = 1;
+ ltint = 1;
break;
case 0x2624:
chipname = "PCnet/FAST+ 79C972";
@@ -610,7 +629,11 @@ pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int car
if(fset)
{
a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0800));
- a->write_csr(ioaddr, 80, a->read_csr(ioaddr, 80) | 0x0c00);
+ a->write_csr(ioaddr, 80, (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00);
+#ifdef DO_DXSUFLO
+ dxsuflo = 1;
+#endif
+ ltint = 1;
}
dev = init_etherdev(NULL, 0);
@@ -624,6 +647,29 @@ pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int car
for (i = 0; i < 6; i++)
printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
+ if (((chip_version + 1) & 0xfffe) == 0x2624) { /* Version 0x2623 or 0x2624 */
+ i = a->read_csr(ioaddr, 80) & 0x0C00; /* Check tx_start_pt */
+ printk("\n tx_start_pt(0x%04x):",i);
+ switch(i>>10) {
+ case 0: printk(" 20 bytes,"); break;
+ case 1: printk(" 64 bytes,"); break;
+ case 2: printk(" 128 bytes,"); break;
+ case 3: printk("~220 bytes,"); break;
+ }
+ i = a->read_bcr(ioaddr, 18); /* Check Burst/Bus control */
+ printk(" BCR18(%x):",i&0xffff);
+ if (i & (1<<5)) printk("BurstWrEn ");
+ if (i & (1<<6)) printk("BurstRdEn ");
+ if (i & (1<<7)) printk("DWordIO ");
+ if (i & (1<<11)) printk("NoUFlow ");
+ i = a->read_bcr(ioaddr, 25);
+ printk("\n SRAMSIZE=0x%04x,",i<<8);
+ i = a->read_bcr(ioaddr, 26);
+ printk(" SRAM_BND=0x%04x,",i<<8);
+ i = a->read_bcr(ioaddr, 27);
+ if (i & (1<<14)) printk("LowLatRx,");
+ }
+
dev->base_addr = ioaddr;
request_region(ioaddr, PCNET32_TOTAL_SIZE, chipname);
@@ -654,6 +700,10 @@ pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int car
lp->name = chipname;
lp->shared_irq = shared;
lp->full_duplex = fdx;
+#ifdef DO_DXSUFLO
+ lp->dxsuflo = dxsuflo;
+#endif
+ lp->ltint = ltint;
lp->mii = mii;
if (options[card_idx] > sizeof (options_mapping))
lp->options = PORT_ASEL;
@@ -795,7 +845,20 @@ pcnet32_open(struct net_device *dev)
val |= 0x08;
lp->a.write_bcr (ioaddr, 32, val);
}
-
+
+#ifdef DO_DXSUFLO
+ if (lp->dxsuflo) { /* Disable transmit stop on underflow */
+ val = lp->a.read_csr (ioaddr, 3);
+ val |= 0x40;
+ lp->a.write_csr (ioaddr, 3, val);
+ }
+#endif
+ if (lp->ltint) { /* Enable TxDone-intr inhibitor */
+ val = lp->a.read_csr (ioaddr, 5);
+ val |= (1<<14);
+ lp->a.write_csr (ioaddr, 5, val);
+ }
+
lp->init_block.mode = le16_to_cpu((lp->options & PORT_PORTSEL) << 7);
lp->init_block.filter[0] = 0x00000000;
lp->init_block.filter[1] = 0x00000000;
@@ -925,6 +988,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
unsigned int ioaddr = dev->base_addr;
+ u16 status;
int entry;
unsigned long flags;
@@ -973,11 +1037,28 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
spin_lock_irqsave(&lp->lock, flags);
- /* Fill in a Tx ring entry */
+ /* Default status -- will not enable Successful-TxDone
+ * interrupt when that option is available to us.
+ */
+ status = 0x8300;
+ if ((lp->ltint) &&
+ ((lp->cur_tx - lp->dirty_tx == TX_RING_SIZE/2) ||
+ (lp->cur_tx - lp->dirty_tx >= TX_RING_SIZE-2)))
+ {
+ /* Enable Successful-TxDone interrupt if we have
+ * 1/2 of, or nearly all of, our ring buffer Tx'd
+ * but not yet cleaned up. Thus, most of the time,
+ * we will not enable Successful-TxDone interrupts.
+ */
+ status = 0x9300;
+ }
+
+ /* Fill in a Tx ring entry */
+
/* Mask to ring buffer boundary. */
entry = lp->cur_tx & TX_RING_MOD_MASK;
-
+
/* Caution: the write order is important here, set the base address
with the "ownership" bits last. */
@@ -987,7 +1068,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
lp->tx_skbuff[entry] = skb;
lp->tx_ring[entry].base = (u32)le32_to_cpu(virt_to_bus(skb->data));
- lp->tx_ring[entry].status = le16_to_cpu(0x8300);
+ lp->tx_ring[entry].status = le16_to_cpu(status);
dma_cache_wback_inv((void *)skb->data,
(skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len);
@@ -1049,7 +1130,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
pcnet32_rx(dev);
if (csr0 & 0x0200) { /* Tx-done interrupt */
- int dirty_tx = lp->dirty_tx;
+ unsigned int dirty_tx = lp->dirty_tx;
while (dirty_tx < lp->cur_tx) {
int entry = dirty_tx & TX_RING_MOD_MASK;
@@ -1067,14 +1148,27 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
if (err_status & 0x04000000) lp->stats.tx_aborted_errors++;
if (err_status & 0x08000000) lp->stats.tx_carrier_errors++;
if (err_status & 0x10000000) lp->stats.tx_window_errors++;
- if (err_status & 0x40000000) {
+#ifndef DO_DXSUFLO
+ if (err_status & 0x40000000) {
+ lp->stats.tx_fifo_errors++;
/* Ackk! On FIFO errors the Tx unit is turned off! */
+ /* Remove this verbosity later! */
+ printk("%s: Tx FIFO error! CSR0=%4.4x\n",
+ dev->name, csr0);
+ must_restart = 1;
+ }
+#else
+ if (err_status & 0x40000000) {
lp->stats.tx_fifo_errors++;
- /* Remove this verbosity later! */
- printk("%s: Tx FIFO error! Status %4.4x.\n",
- dev->name, csr0);
- must_restart = 1;
- }
+ if (! lp->dxsuflo) { /* If controller doesn't recover ... */
+ /* Ackk! On FIFO errors the Tx unit is turned off! */
+ /* Remove this verbosity later! */
+ printk("%s: Tx FIFO error! CSR0=%4.4x\n",
+ dev->name, csr0);
+ must_restart = 1;
+ }
+ }
+#endif
} else {
if (status & 0x1800)
lp->stats.collisions++;
@@ -1413,18 +1507,22 @@ static int pcnet32_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
MODULE_PARM(debug, "i");
MODULE_PARM(max_interrupt_work, "i");
MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM(tx_start_pt, "i");
MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
/* An additional parameter that may be passed in... */
static int debug = -1;
+static int tx_start_pt = -1;
int
init_module(void)
{
if (debug > 0)
pcnet32_debug = debug;
+ if ((tx_start_pt >= 0) && (tx_start_pt <= 3))
+ tx_start = tx_start_pt;
pcnet32_dev = NULL;
return pcnet32_probe();
diff --git a/drivers/net/setup.c b/drivers/net/setup.c
index 601617f79..2eab3d4b7 100644
--- a/drivers/net/setup.c
+++ b/drivers/net/setup.c
@@ -48,6 +48,7 @@ extern int rcpci_probe(void);
extern int rr_hippi_probe(void);
extern int rtl8139_probe(void);
extern int sdla_setup(void);
+extern int sdla_c_setup(void);
extern int sis900_probe(void);
extern int skge_probe(void);
extern int sparc_lance_probe(void);
@@ -57,6 +58,10 @@ extern int tulip_probe(void);
extern int via_rhine_probe(void);
extern int yellowfin_probe(void);
+extern int abyss_probe(void);
+extern int madgemc_probe(void);
+extern int tms_pci_probe(void);
+
/* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is tring of 9 zeros. */
#define __PAD6 "\0\0\0\0\0\0\0\0\0"
#define __PAD5 __PAD6 "\0"
@@ -94,7 +99,7 @@ struct net_probe pci_probes[] __initdata = {
{dlci_setup, 0},
#endif
#if defined(CONFIG_SDLA)
- {sdla_setup, 0},
+ {sdla_c_setup, 0},
#endif
#if defined(CONFIG_LAPBETHER)
{lapbeth_init, 0},
@@ -249,7 +254,19 @@ struct net_probe pci_probes[] __initdata = {
#ifdef CONFIG_YAM
{yam_init, 0},
#endif /* CONFIG_YAM */
-
+
+/*
+ * Token Ring Drivers
+ */
+#ifdef CONFIG_ABYSS
+ {abyss_probe, 0},
+#endif
+#ifdef CONFIG_MADGEMC
+ {madgemc_probe, 0},
+#endif
+#ifdef CONFIG_TMSPCI
+ {tms_pci_probe, 0},
+#endif
{NULL, 0},
};
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index 5c5b13c06..10e466a5d 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -1165,11 +1165,11 @@ static int __init bigmac_ether_init(struct net_device *dev, struct sbus_dev *qec
bigmac_stop(bp);
/* Allocate transmit/receive descriptor DVMA block. */
- bp->bmac_block = sbus_alloc_consistant(bp->bigmac_sdev,
+ bp->bmac_block = sbus_alloc_consistent(bp->bigmac_sdev,
PAGE_SIZE,
&bp->bblock_dvma);
if (bp->bmac_block == NULL || bp->bblock_dvma == 0) {
- printk(KERN_ERR "BIGMAC: Cannot allocate consistant DMA.\n");
+ printk(KERN_ERR "BIGMAC: Cannot allocate consistent DMA.\n");
goto fail_and_cleanup;
}
@@ -1220,7 +1220,7 @@ fail_and_cleanup:
sbus_iounmap(bp->tregs, TCVR_REG_SIZE);
if (bp->bmac_block)
- sbus_free_consistant(bp->bigmac_sdev,
+ sbus_free_consistent(bp->bigmac_sdev,
PAGE_SIZE,
bp->bmac_block,
bp->bblock_dvma);
@@ -1301,7 +1301,7 @@ cleanup_module(void)
sbus_iounmap(bp->creg, CREG_REG_SIZE);
sbus_iounmap(bp->bregs, BMAC_REG_SIZE);
sbus_iounmap(bp->tregs, TCVR_REG_SIZE);
- sbus_free_consistant(bp->bigmac_sdev,
+ sbus_free_consistent(bp->bigmac_sdev,
PAGE_SIZE,
bp->bmac_block,
bp->bblock_dvma);
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index e18ce36a3..eb76a9fee 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -207,42 +207,6 @@ static u32 pci_hme_read_desc32(u32 *p)
return cpu_to_le32(*p);
}
-/* XXX Convert these to direct function hookup once new
- * XXX PCI dvma interfaces are propagated and in use everywhere.
- */
-static u32 pci_hme_dma_map(void *device, void *ptr, long size)
-{
-#if 1
- return virt_to_bus(ptr);
-#else
- struct pci_dev *pdev = device;
-
- return pci_map_single(pdev, ptr, size);
-#endif
-}
-
-static void pci_hme_dma_unmap(void *device, u32 dma_addr, long size)
-{
-#if 1
- return;
-#else
- struct pci_dev *pdev = device;
-
- pci_unmap_single(pdev, dma_addr, size);
-#endif
-}
-
-static void pci_hme_dma_sync(void *device, u32 dma_addr, long size)
-{
-#if 1
- return;
-#else
- struct pci_dev *pdev = device;
-
- pci_dma_sync_single(pdev, dma_addr, size);
-#endif
-}
-
#define hme_write32(__hp, __reg, __val) \
((__hp)->write32((__reg), (__val)))
#define hme_read32(__hp, __reg) \
@@ -296,21 +260,12 @@ do { (__txd)->tx_addr = cpu_to_le32(__addr); \
(__txd)->tx_flags = cpu_to_le32(__flags); \
} while(0)
#define hme_read_desc32(__hp, __p) cpu_to_le32(*(__p))
-#if 0 /* XXX Once new PCI interfaces are in place... XXX */
#define hme_dma_map(__hp, __ptr, __size) \
pci_map_single((__hp)->happy_dev, (__ptr), (__size))
#define hme_dma_unmap(__hp, __addr, __size) \
pci_unmap_single((__hp)->happy_dev, (__addr), (__size))
#define hme_dma_sync(__hp, __addr, __size) \
pci_dma_sync_single((__hp)->happy_dev, (__addr), (__size))
-#else
-#define hme_dma_map(__hp, __ptr, __size) \
- (virt_to_bus(__ptr))
-#define hme_dma_unmap(__hp, __addr, __size) \
- do { } while(0)
-#define hme_dma_sync(__hp, __addr, __size) \
- do { } while(0)
-#endif
#endif
#endif
@@ -2663,7 +2618,7 @@ static int __init happy_meal_sbus_init(struct net_device *dev,
hp->happy_bursts = prom_getintdefault(sdev->bus->prom_node,
"burst-sizes", 0x00);
- hp->happy_block = sbus_alloc_consistant(hp->happy_dev,
+ hp->happy_block = sbus_alloc_consistent(hp->happy_dev,
PAGE_SIZE,
&hp->hblock_dvma);
@@ -2835,20 +2790,14 @@ static int __init happy_meal_pci_init(struct net_device *dev, struct pci_dev *pd
/* Assume PCI happy meals can handle all burst sizes. */
hp->happy_bursts = DMA_BURSTBITS;
- hp->happy_block = (struct hmeal_init_block *) get_free_page(GFP_ATOMIC);
+ hp->happy_block = (struct hmeal_init_block *)
+ pci_alloc_consistent(pdev, PAGE_SIZE, &hp->hblock_dvma);
+
if (!hp->happy_block) {
printk(KERN_ERR "happymeal(PCI): Cannot get hme init block.\n");
return ENODEV;
}
- hp->hblock_dvma = (u32) virt_to_bus(hp->happy_block);
-#ifndef __sparc_v9__
- /*
- * P3: Dirty trick to get uncacheable memory as we have no dma_sync.
- */
- hp->happy_block = ioremap(virt_to_phys(hp->happy_block), PAGE_SIZE);
-#endif
-
hp->linkcheck = 0;
hp->timer_state = asleep;
hp->timer_ticks = 0;
@@ -2870,9 +2819,9 @@ static int __init happy_meal_pci_init(struct net_device *dev, struct pci_dev *pd
hp->read_desc32 = pci_hme_read_desc32;
hp->write_txd = pci_hme_write_txd;
hp->write_rxd = pci_hme_write_rxd;
- hp->dma_map = pci_hme_dma_map;
- hp->dma_unmap = pci_hme_dma_unmap;
- hp->dma_sync = pci_hme_dma_sync;
+ hp->dma_map = (u32 (*)(void *, void *, long))pci_map_single;
+ hp->dma_unmap = (void (*)(void *, u32, long))pci_unmap_single;
+ hp->dma_sync = (void (*)(void *, u32, long))pci_dma_sync_single;
hp->read32 = pci_hme_read32;
hp->write32 = pci_hme_write32;
#endif
@@ -3011,12 +2960,20 @@ cleanup_module(void)
sbus_iounmap(hp->erxregs, ERX_REG_SIZE);
sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE);
sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
- sbus_free_consistant(hp->happy_dev,
+ sbus_free_consistent(hp->happy_dev,
PAGE_SIZE,
hp->happy_block,
hp->hblock_dvma);
}
#endif
+#ifdef CONFIG_PCI
+ if ((hp->happy_flags & HFLAG_PCI)) {
+ pci_free_consistent(hp->happy_dev,
+ PAGE_SIZE,
+ hp->happy_block,
+ hp->hblock_dvma);
+ }
+#endif
unregister_netdev(hp->dev);
kfree(hp->dev);
root_happy_dev = next;
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 44548e437..3c499ba38 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -1305,7 +1305,7 @@ static void lance_free_hwresources(struct lance_private *lp)
sbus_iounmap((unsigned long)lp->init_block,
sizeof(struct lance_init_block));
} else {
- sbus_free_consistant(lp->sdev,
+ sbus_free_consistent(lp->sdev,
sizeof(struct lance_init_block),
(void *)lp->init_block,
lp->init_block_dvma);
@@ -1375,11 +1375,11 @@ static int __init sparc_lance_init(struct net_device *dev,
lp->tx = lance_tx_pio;
} else {
lp->init_block = (volatile struct lance_init_block *)
- sbus_alloc_consistant(sdev, sizeof(struct lance_init_block),
+ sbus_alloc_consistent(sdev, sizeof(struct lance_init_block),
&lp->init_block_dvma);
if (lp->init_block == NULL ||
lp->init_block_dvma == 0) {
- printk(KERN_ERR "%s: Cannot allocate consistant DMA memory.\n",
+ printk(KERN_ERR "%s: Cannot allocate consistent DMA memory.\n",
dev->name);
goto fail;
}
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index 63208eb47..2a170a0a6 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -833,10 +833,10 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev)
goto qec_free_devs;
}
- qeps[i]->qe_block = sbus_alloc_consistant(qesdevs[i],
+ qeps[i]->qe_block = sbus_alloc_consistent(qesdevs[i],
PAGE_SIZE,
&qeps[i]->qblock_dvma);
- qeps[i]->buffers = sbus_alloc_consistant(qesdevs[i],
+ qeps[i]->buffers = sbus_alloc_consistent(qesdevs[i],
sizeof(struct sunqe_buffers),
&qeps[i]->buffers_dvma);
if (qeps[i]->qe_block == NULL ||
@@ -907,12 +907,12 @@ qec_free_devs:
if (qe->mregs)
sbus_iounmap(qe->mregs, MREGS_REG_SIZE);
if (qe->qe_block != NULL)
- sbus_free_consistant(qe->qe_sdev,
+ sbus_free_consistent(qe->qe_sdev,
PAGE_SIZE,
qe->qe_block,
qe->qblock_dvma);
if (qe->buffers != NULL)
- sbus_free_consistant(qe->qe_sdev,
+ sbus_free_consistent(qe->qe_sdev,
sizeof(struct sunqe_buffers),
qe->buffers,
qe->buffers_dvma);
@@ -1006,11 +1006,11 @@ cleanup_module(void)
unregister_netdev(root_qec_dev->qes[i]->dev);
sbus_iounmap(root_qec_dev->qes[i]->qcregs, CREG_REG_SIZE);
sbus_iounmap(root_qec_dev->qes[i]->mregs, MREGS_REG_SIZE);
- sbus_free_consistant(root_qec_dev->qes[i]->qe_sdev,
+ sbus_free_consistent(root_qec_dev->qes[i]->qe_sdev,
PAGE_SIZE,
root_qec_dev->qes[i]->qe_block,
root_qec_dev->qes[i]->qblock_dvma);
- sbus_free_consistant(root_qec_dev->qes[i]->qe_sdev,
+ sbus_free_consistent(root_qec_dev->qes[i]->qe_sdev,
sizeof(struct sunqe_buffers),
root_qec_dev->qes[i]->buffers,
root_qec_dev->qes[i]->buffers_dvma);
diff --git a/drivers/net/tokenring/Config.in b/drivers/net/tokenring/Config.in
index a862c247b..b7e67fbad 100644
--- a/drivers/net/tokenring/Config.in
+++ b/drivers/net/tokenring/Config.in
@@ -6,11 +6,16 @@ mainmenu_option next_comment
comment 'Token Ring driver support'
bool 'Token Ring driver support' CONFIG_TR
-if [ "$CONFIG_TR" = "y" ]; then
- tristate ' IBM Tropic chipset based adapter support' CONFIG_IBMTR
- tristate ' IBM Olympic chipset PCI adapter support' CONFIG_IBMOL
- tristate ' Generic TMS380 Token Ring ISA/PCI adapter support' CONFIG_TMS380TR
- tristate ' SMC ISA adapter support' CONFIG_SMCTR
+if [ "$CONFIG_TR" != "n" ]; then
+ dep_tristate ' IBM Tropic chipset based adapter support' CONFIG_IBMTR $CONFIG_TR
+ dep_tristate ' IBM Olympic chipset PCI adapter support' CONFIG_IBMOL $CONFIG_TR
+ dep_tristate ' Generic TMS380 Token Ring ISA/PCI adapter support' CONFIG_TMS380TR $CONFIG_TR
+ if [ "$CONFIG_TMS380TR" != "n" ]; then
+ dep_tristate ' Generic TMS380 PCI support' CONFIG_TMSPCI $CONFIG_TMS380TR
+ dep_tristate ' Madge Smart 16/4 PCI Mk2 support' CONFIG_ABYSS $CONFIG_TMS380TR
+ dep_tristate ' Madge Smart 16/4 Ringnode MicroChannel' CONFIG_MADGEMC $CONFIG_TMS380TR
+ fi
+ dep_tristate ' SMC ISA/MCA adapter support' CONFIG_SMCTR $CONFIG_TR
fi
endmenu
diff --git a/drivers/net/tokenring/Makefile b/drivers/net/tokenring/Makefile
index 72629233b..65dfefc70 100644
--- a/drivers/net/tokenring/Makefile
+++ b/drivers/net/tokenring/Makefile
@@ -41,9 +41,27 @@ endif
ifeq ($(CONFIG_TMS380TR),y)
L_OBJS += tms380tr.o
+ ifeq ($(CONFIG_ABYSS),y)
+ L_OBJS += abyss.o
+ endif
+ ifeq ($(CONFIG_MADGEMC),y)
+ L_OBJS += madgemc.o
+ endif
+ ifeq ($(CONFIG_TMSPCI),y)
+ L_OBJS += tmspci.o
+ endif
else
ifeq ($(CONFIG_TMS380TR),m)
M_OBJS += tms380tr.o
+ ifeq ($(CONFIG_ABYSS),m)
+ M_OBJS += abyss.o
+ endif
+ ifeq ($(CONFIG_MADGEMC),m)
+ M_OBJS += madgemc.o
+ endif
+ ifeq ($(CONFIG_TMSPCI),m)
+ M_OBJS += tmspci.o
+ endif
endif
endif
diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c
new file mode 100644
index 000000000..724847af2
--- /dev/null
+++ b/drivers/net/tokenring/abyss.c
@@ -0,0 +1,512 @@
+/*
+ * abyss.c: Network driver for the Madge Smart 16/4 PCI Mk2 token ring card.
+ *
+ * Written 1999-2000 by Adam Fritzler
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License, incorporated herein by reference.
+ *
+ * This driver module supports the following cards:
+ * - Madge Smart 16/4 PCI Mk2
+ *
+ * Maintainer(s):
+ * AF Adam Fritzler mid@auk.cx
+ *
+ * Modification History:
+ * 30-Dec-99 AF Split off from the tms380tr driver.
+ * 22-Jan-00 AF Updated to use indirect read/writes
+ *
+ *
+ * TODO:
+ * 1. See if we can use MMIO instead of inb/outb/inw/outw
+ * 2. Add support for Mk1 (has AT24 attached to the PCI
+ * config registers)
+ *
+ */
+static const char *version = "abyss.c: v1.01 22/01/2000 by Adam Fritzler\n";
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/netdevice.h>
+#include <linux/trdevice.h>
+#include "tms380tr.h"
+#include "abyss.h" /* Madge-specific constants */
+
+#define ABYSS_IO_EXTENT 64
+
+int abyss_probe(void);
+static int abyss_open(struct net_device *dev);
+static int abyss_close(struct net_device *dev);
+static void abyss_enable(struct net_device *dev);
+static int abyss_chipset_init(struct net_device *dev);
+static void abyss_read_eeprom(struct net_device *dev);
+static unsigned short abyss_setnselout_pins(struct net_device *dev);
+
+void at24_writedatabyte(unsigned long regaddr, unsigned char byte);
+int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr);
+int at24_sendcmd(unsigned long regaddr, unsigned char cmd);
+unsigned char at24_readdatabit(unsigned long regaddr);
+unsigned char at24_readdatabyte(unsigned long regaddr);
+int at24_waitforack(unsigned long regaddr);
+int at24_waitfornack(unsigned long regaddr);
+void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data);
+void at24_start(unsigned long regaddr);
+void at24_stop(unsigned long regaddr);
+unsigned char at24_readb(unsigned long regaddr, unsigned char addr);
+
+static unsigned short abyss_sifreadb(struct net_device *dev, unsigned short reg)
+{
+ return inb(dev->base_addr + reg);
+}
+
+static unsigned short abyss_sifreadw(struct net_device *dev, unsigned short reg)
+{
+ return inw(dev->base_addr + reg);
+}
+
+static void abyss_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
+{
+ outb(val, dev->base_addr + reg);
+}
+
+static void abyss_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
+{
+ outw(val, dev->base_addr + reg);
+}
+
+struct tms_abyss_card {
+ struct net_device *dev;
+ struct pci_dev *pci_dev;
+ struct tms_abyss_card *next;
+};
+static struct tms_abyss_card *abyss_card_list = NULL;
+
+int __init abyss_probe(void)
+{
+ static int versionprinted = 0;
+ struct pci_dev *pdev = NULL ;
+ struct net_device *dev;
+ struct net_local *tp;
+ int i;
+
+ if (!pci_present())
+ return (-1); /* No PCI present. */
+
+ while ( (pdev=pci_find_class(PCI_CLASS_NETWORK_TOKEN_RING<<8, pdev))) {
+ unsigned int pci_irq_line;
+ unsigned long pci_ioaddr;
+ struct tms_abyss_card *card;
+
+ /* We only support Madge Smart 16/4 PCI Mk2 (Abyss) cards */
+ if ( (pdev->vendor != PCI_VENDOR_ID_MADGE) ||
+ (pdev->device != PCI_DEVICE_ID_MADGE_MK2) )
+ continue;
+
+ if (versionprinted++ == 0)
+ printk("%s", version);
+
+ pci_enable_device(pdev);
+
+ /* Remove I/O space marker in bit 0. */
+ pci_irq_line = pdev->irq;
+ pci_ioaddr = pdev->resource[0].start ;
+
+ if(check_region(pci_ioaddr, ABYSS_IO_EXTENT))
+ continue;
+
+ /* At this point we have found a valid card. */
+
+ dev = init_trdev(NULL, 0);
+
+ request_region(pci_ioaddr, ABYSS_IO_EXTENT, "abyss");
+ if(request_irq(pdev->irq, tms380tr_interrupt, SA_SHIRQ,
+ "abyss", dev)) {
+ release_region(pci_ioaddr, ABYSS_IO_EXTENT) ;
+ continue; /*return (-ENODEV);*/ /* continue; ?? */
+ }
+
+ /*
+ if (load_tms380_module("abyss.c")) {
+ return 0;
+ }
+ */
+
+ pci_ioaddr &= ~3 ;
+ dev->base_addr = pci_ioaddr;
+ dev->irq = pci_irq_line;
+ dev->dma = 0;
+
+ printk("%s: Madge Smart 16/4 PCI Mk2 (Abyss)\n", dev->name);
+ printk("%s: IO: %#4lx IRQ: %d\n",
+ dev->name, pci_ioaddr, dev->irq);
+ /*
+ * The TMS SIF registers lay 0x10 above the card base address.
+ */
+ dev->base_addr += 0x10;
+
+ if (tmsdev_init(dev)) {
+ printk("%s: unable to get memory for dev->priv.\n",
+ dev->name);
+ return 0;
+ }
+
+ abyss_read_eeprom(dev);
+
+ printk("%s: Ring Station Address: ", dev->name);
+ printk("%2.2x", dev->dev_addr[0]);
+ for (i = 1; i < 6; i++)
+ printk(":%2.2x", dev->dev_addr[i]);
+ printk("\n");
+
+ tp = (struct net_local *)dev->priv;
+ tp->dmalimit = 0; /* XXX: should be the max PCI32 DMA max */
+ tp->setnselout = abyss_setnselout_pins;
+ tp->sifreadb = abyss_sifreadb;
+ tp->sifreadw = abyss_sifreadw;
+ tp->sifwriteb = abyss_sifwriteb;
+ tp->sifwritew = abyss_sifwritew;
+
+ memcpy(tp->ProductID, "Madge PCI 16/4 Mk2", PROD_ID_SIZE + 1);
+
+ dev->open = abyss_open;
+ dev->stop = abyss_close;
+
+ if (register_trdev(dev) == 0) {
+ /* Enlist in the card list */
+ card = kmalloc(sizeof(struct tms_abyss_card),
+ GFP_KERNEL);
+ card->next = abyss_card_list;
+ abyss_card_list = card;
+ card->dev = dev;
+ card->pci_dev = pdev;
+ } else {
+ printk("abyss: register_trdev() returned non-zero.\n");
+ kfree(dev->priv);
+ kfree(dev);
+ return -1;
+ }
+ }
+
+ if (abyss_card_list)
+ return 0;
+ return (-1);
+}
+
+unsigned short abyss_setnselout_pins(struct net_device *dev)
+{
+ unsigned short val = 0;
+ struct net_local *tp = (struct net_local *)dev->priv;
+
+ if(tp->DataRate == SPEED_4)
+ val |= 0x01; /* Set 4Mbps */
+ else
+ val |= 0x00; /* Set 16Mbps */
+
+ return val;
+}
+
+/*
+ * The following Madge boards should use this code:
+ * - Smart 16/4 PCI Mk2 (Abyss)
+ * - Smart 16/4 PCI Mk1 (PCI T)
+ * - Smart 16/4 Client Plus PnP (Big Apple)
+ * - Smart 16/4 Cardbus Mk2
+ *
+ * These access an Atmel AT24 SEEPROM using their glue chip registers.
+ *
+ */
+void at24_writedatabyte(unsigned long regaddr, unsigned char byte)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ at24_setlines(regaddr, 0, (byte >> (7-i))&0x01);
+ at24_setlines(regaddr, 1, (byte >> (7-i))&0x01);
+ at24_setlines(regaddr, 0, (byte >> (7-i))&0x01);
+ }
+}
+
+int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr)
+{
+ if (at24_sendcmd(regaddr, cmd)) {
+ at24_writedatabyte(regaddr, addr);
+ return at24_waitforack(regaddr);
+ }
+ return 0;
+}
+
+int at24_sendcmd(unsigned long regaddr, unsigned char cmd)
+{
+ int i;
+
+ for (i = 0; i < 10; i++) {
+ at24_start(regaddr);
+ at24_writedatabyte(regaddr, cmd);
+ if (at24_waitforack(regaddr))
+ return 1;
+ }
+ return 0;
+}
+
+unsigned char at24_readdatabit(unsigned long regaddr)
+{
+ unsigned char val;
+
+ at24_setlines(regaddr, 0, 1);
+ at24_setlines(regaddr, 1, 1);
+ val = (inb(regaddr) & AT24_DATA)?1:0;
+ at24_setlines(regaddr, 1, 1);
+ at24_setlines(regaddr, 0, 1);
+ return val;
+}
+
+unsigned char at24_readdatabyte(unsigned long regaddr)
+{
+ unsigned char data = 0;
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ data <<= 1;
+ data |= at24_readdatabit(regaddr);
+ }
+
+ return data;
+}
+
+int at24_waitforack(unsigned long regaddr)
+{
+ int i;
+
+ for (i = 0; i < 10; i++) {
+ if ((at24_readdatabit(regaddr) & 0x01) == 0x00)
+ return 1;
+ }
+ return 0;
+}
+
+int at24_waitfornack(unsigned long regaddr)
+{
+ int i;
+ for (i = 0; i < 10; i++) {
+ if ((at24_readdatabit(regaddr) & 0x01) == 0x01)
+ return 1;
+ }
+ return 0;
+}
+
+void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data)
+{
+ unsigned char val;
+ val = AT24_ENABLE;
+ if (clock)
+ val |= AT24_CLOCK;
+ if (data)
+ val |= AT24_DATA;
+
+ outb(val, regaddr);
+ tms380tr_wait(20); /* Very necessary. */
+}
+
+void at24_start(unsigned long regaddr)
+{
+ at24_setlines(regaddr, 0, 1);
+ at24_setlines(regaddr, 1, 1);
+ at24_setlines(regaddr, 1, 0);
+ at24_setlines(regaddr, 0, 1);
+ return;
+}
+
+void at24_stop(unsigned long regaddr)
+{
+ at24_setlines(regaddr, 0, 0);
+ at24_setlines(regaddr, 1, 0);
+ at24_setlines(regaddr, 1, 1);
+ at24_setlines(regaddr, 0, 1);
+ return;
+}
+
+unsigned char at24_readb(unsigned long regaddr, unsigned char addr)
+{
+ unsigned char data = 0xff;
+
+ if (at24_sendfullcmd(regaddr, AT24_WRITE, addr)) {
+ if (at24_sendcmd(regaddr, AT24_READ)) {
+ data = at24_readdatabyte(regaddr);
+ if (!at24_waitfornack(regaddr))
+ data = 0xff;
+ }
+ }
+ return data;
+}
+
+
+/*
+ * Enable basic functions of the Madge chipset needed
+ * for initialization.
+ */
+static void abyss_enable(struct net_device *dev)
+{
+ unsigned char reset_reg;
+ unsigned long ioaddr;
+
+ ioaddr = dev->base_addr;
+ reset_reg = inb(ioaddr + PCIBM2_RESET_REG);
+ reset_reg |= PCIBM2_RESET_REG_CHIP_NRES;
+ outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
+ tms380tr_wait(100);
+ return;
+}
+
+/*
+ * Enable the functions of the Madge chipset needed for
+ * full working order.
+ */
+static int abyss_chipset_init(struct net_device *dev)
+{
+ unsigned char reset_reg;
+ unsigned long ioaddr;
+
+ ioaddr = dev->base_addr;
+
+ reset_reg = inb(ioaddr + PCIBM2_RESET_REG);
+
+ reset_reg |= PCIBM2_RESET_REG_CHIP_NRES;
+ outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
+
+ reset_reg &= ~(PCIBM2_RESET_REG_CHIP_NRES |
+ PCIBM2_RESET_REG_FIFO_NRES |
+ PCIBM2_RESET_REG_SIF_NRES);
+ outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
+
+ tms380tr_wait(100);
+
+ reset_reg |= PCIBM2_RESET_REG_CHIP_NRES;
+ outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
+
+ reset_reg |= PCIBM2_RESET_REG_SIF_NRES;
+ outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
+
+ reset_reg |= PCIBM2_RESET_REG_FIFO_NRES;
+ outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
+
+ outb(PCIBM2_INT_CONTROL_REG_SINTEN |
+ PCIBM2_INT_CONTROL_REG_PCI_ERR_ENABLE,
+ ioaddr + PCIBM2_INT_CONTROL_REG);
+
+ outb(30, ioaddr + PCIBM2_FIFO_THRESHOLD);
+
+ return 0;
+}
+
+void abyss_chipset_close(struct net_device *dev)
+{
+ unsigned long ioaddr;
+
+ ioaddr = dev->base_addr;
+ outb(0, ioaddr + PCIBM2_RESET_REG);
+
+ return;
+}
+
+/*
+ * Read configuration data from the AT24 SEEPROM on Madge cards.
+ *
+ */
+static void abyss_read_eeprom(struct net_device *dev)
+{
+ struct net_local *tp;
+ unsigned long ioaddr;
+ unsigned short val;
+ int i;
+
+ tp = (struct net_local *)dev->priv;
+ ioaddr = dev->base_addr;
+
+ /* Must enable glue chip first */
+ abyss_enable(dev);
+
+ val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG,
+ PCIBM2_SEEPROM_RING_SPEED);
+ tp->DataRate = val?SPEED_4:SPEED_16; /* set open speed */
+ printk("%s: SEEPROM: ring speed: %dMb/sec\n", dev->name, tp->DataRate);
+
+ val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG,
+ PCIBM2_SEEPROM_RAM_SIZE) * 128;
+ printk("%s: SEEPROM: adapter RAM: %dkb\n", dev->name, val);
+
+ dev->addr_len = 6;
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = at24_readb(ioaddr + PCIBM2_SEEPROM_REG,
+ PCIBM2_SEEPROM_BIA+i);
+
+ return;
+}
+
+static int abyss_open(struct net_device *dev)
+{
+ abyss_chipset_init(dev);
+ tms380tr_open(dev);
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int abyss_close(struct net_device *dev)
+{
+ tms380tr_close(dev);
+ abyss_chipset_close(dev);
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+#ifdef MODULE
+
+int init_module(void)
+{
+ /* Probe for cards. */
+ if (abyss_probe()) {
+ printk(KERN_NOTICE "abyss.c: No cards found.\n");
+ }
+ /* lock_tms380_module(); */
+ return (0);
+}
+
+void cleanup_module(void)
+{
+ struct net_device *dev;
+ struct tms_abyss_card *this_card;
+
+ while (abyss_card_list) {
+ dev = abyss_card_list->dev;
+ unregister_netdev(dev);
+ release_region(dev->base_addr-0x10, ABYSS_IO_EXTENT);
+ free_irq(dev->irq, dev);
+ kfree(dev->priv);
+ kfree(dev);
+ this_card = abyss_card_list;
+ abyss_card_list = this_card->next;
+ kfree(this_card);
+ }
+ /* unlock_tms380_module(); */
+}
+#endif /* MODULE */
+
+
+/*
+ * Local variables:
+ * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c abyss.c"
+ * alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c abyss.c"
+ * c-set-style "K&R"
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff --git a/drivers/net/tokenring/abyss.h b/drivers/net/tokenring/abyss.h
new file mode 100644
index 000000000..0ee6e4f08
--- /dev/null
+++ b/drivers/net/tokenring/abyss.h
@@ -0,0 +1,58 @@
+/*
+ * abyss.h: Header for the abyss tms380tr module
+ *
+ * Authors:
+ * - Adam Fritzler <mid@auk.cx>
+ */
+
+#ifndef __LINUX_MADGETR_H
+#define __LINUX_MADGETR_H
+
+#ifdef __KERNEL__
+
+/*
+ * For Madge Smart 16/4 PCI Mk2. Since we increment the base address
+ * to get everything correct for the TMS SIF, we do these as negatives
+ * as they fall below the SIF in addressing.
+ */
+#define PCIBM2_INT_STATUS_REG ((short)-15)/* 0x01 */
+#define PCIBM2_INT_CONTROL_REG ((short)-14)/* 0x02 */
+#define PCIBM2_RESET_REG ((short)-12)/* 0x04 */
+#define PCIBM2_SEEPROM_REG ((short)-9) /* 0x07 */
+
+#define PCIBM2_INT_CONTROL_REG_SINTEN 0x02
+#define PCIBM2_INT_CONTROL_REG_PCI_ERR_ENABLE 0x80
+#define PCIBM2_INT_STATUS_REG_PCI_ERR 0x80
+
+#define PCIBM2_RESET_REG_CHIP_NRES 0x01
+#define PCIBM2_RESET_REG_FIFO_NRES 0x02
+#define PCIBM2_RESET_REG_SIF_NRES 0x04
+
+#define PCIBM2_FIFO_THRESHOLD 0x21
+#define PCIBM2_BURST_LENGTH 0x22
+
+/*
+ * Bits in PCIBM2_SEEPROM_REG.
+ */
+#define AT24_ENABLE 0x04
+#define AT24_DATA 0x02
+#define AT24_CLOCK 0x01
+
+/*
+ * AT24 Commands.
+ */
+#define AT24_WRITE 0xA0
+#define AT24_READ 0xA1
+
+/*
+ * Addresses in AT24 SEEPROM.
+ */
+#define PCIBM2_SEEPROM_BIA 0x12
+#define PCIBM2_SEEPROM_RING_SPEED 0x18
+#define PCIBM2_SEEPROM_RAM_SIZE 0x1A
+#define PCIBM2_SEEPROM_HWF1 0x1C
+#define PCIBM2_SEEPROM_HWF2 0x1E
+
+
+#endif /* __KERNEL__ */
+#endif /* __LINUX_MADGETR_H */
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
new file mode 100644
index 000000000..005ebf5e4
--- /dev/null
+++ b/drivers/net/tokenring/madgemc.c
@@ -0,0 +1,806 @@
+/*
+ * madgemc.c: Driver for the Madge Smart 16/4 MC16 MCA token ring card.
+ *
+ * Written 2000 by Adam Fritzler
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License, incorporated herein by reference.
+ *
+ * This driver module supports the following cards:
+ * - Madge Smart 16/4 Ringnode MC16
+ * - Madge Smart 16/4 Ringnode MC32 (??)
+ *
+ * Maintainer(s):
+ * AF Adam Fritzler mid@auk.cx
+ *
+ * Modification History:
+ * 16-Jan-00 AF Created
+ *
+ */
+static const char *version = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n";
+
+#include <linux/module.h>
+#include <linux/mca.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/netdevice.h>
+#include <linux/trdevice.h>
+#include "tms380tr.h"
+#include "madgemc.h" /* Madge-specific constants */
+
+#define MADGEMC_IO_EXTENT 32
+#define MADGEMC_SIF_OFFSET 0x08
+
+struct madgemc_card {
+ struct net_device *dev;
+
+ /*
+ * These are read from the BIA ROM.
+ */
+ unsigned int manid;
+ unsigned int cardtype;
+ unsigned int cardrev;
+ unsigned int ramsize;
+
+ /*
+ * These are read from the MCA POS registers.
+ */
+ unsigned int burstmode:2;
+ unsigned int fairness:1; /* 0 = Fair, 1 = Unfair */
+ unsigned int arblevel:4;
+ unsigned int ringspeed:2; /* 0 = 4mb, 1 = 16, 2 = Auto/none */
+ unsigned int cabletype:1; /* 0 = RJ45, 1 = DB9 */
+
+ struct madgemc_card *next;
+};
+static struct madgemc_card *madgemc_card_list = NULL;
+
+
+int madgemc_probe(void);
+static int madgemc_open(struct net_device *dev);
+static int madgemc_close(struct net_device *dev);
+static int madgemc_chipset_init(struct net_device *dev);
+static void madgemc_read_rom(struct madgemc_card *card);
+static unsigned short madgemc_setnselout_pins(struct net_device *dev);
+static void madgemc_setcabletype(struct net_device *dev, int type);
+
+static int madgemc_mcaproc(char *buf, int slot, void *d);
+
+static void madgemc_setregpage(struct net_device *dev, int page);
+static void madgemc_setsifsel(struct net_device *dev, int val);
+static void madgemc_setint(struct net_device *dev, int val);
+
+static void madgemc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+/*
+ * These work around paging, however they dont guarentee you're on the
+ * right page.
+ */
+#define SIFREADB(reg) (inb(dev->base_addr + ((reg<0x8)?reg:reg-0x8)))
+#define SIFWRITEB(val, reg) (outb(val, dev->base_addr + ((reg<0x8)?reg:reg-0x8)))
+#define SIFREADW(reg) (inw(dev->base_addr + ((reg<0x8)?reg:reg-0x8)))
+#define SIFWRITEW(val, reg) (outw(val, dev->base_addr + ((reg<0x8)?reg:reg-0x8)))
+
+/*
+ * Read a byte-length value from the register.
+ */
+static unsigned short madgemc_sifreadb(struct net_device *dev, unsigned short reg)
+{
+ unsigned short ret;
+ if (reg<0x8)
+ ret = SIFREADB(reg);
+ else {
+ madgemc_setregpage(dev, 1);
+ ret = SIFREADB(reg);
+ madgemc_setregpage(dev, 0);
+ }
+ return ret;
+}
+
+/*
+ * Write a byte-length value to a register.
+ */
+static void madgemc_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
+{
+ if (reg<0x8)
+ SIFWRITEB(val, reg);
+ else {
+ madgemc_setregpage(dev, 1);
+ SIFWRITEB(val, reg);
+ madgemc_setregpage(dev, 0);
+ }
+ return;
+}
+
+/*
+ * Read a word-length value from a register
+ */
+static unsigned short madgemc_sifreadw(struct net_device *dev, unsigned short reg)
+{
+ unsigned short ret;
+ if (reg<0x8)
+ ret = SIFREADW(reg);
+ else {
+ madgemc_setregpage(dev, 1);
+ ret = SIFREADW(reg);
+ madgemc_setregpage(dev, 0);
+ }
+ return ret;
+}
+
+/*
+ * Write a word-length value to a register.
+ */
+static void madgemc_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
+{
+ if (reg<0x8)
+ SIFWRITEW(val, reg);
+ else {
+ madgemc_setregpage(dev, 1);
+ SIFWRITEW(val, reg);
+ madgemc_setregpage(dev, 0);
+ }
+ return;
+}
+
+
+
+int __init madgemc_probe(void)
+{
+ static int versionprinted = 0;
+ struct net_device *dev;
+ struct net_local *tp;
+ struct madgemc_card *card;
+ int i,slot = 0;
+ __u8 posreg[4];
+
+ if (!MCA_bus)
+ return -1;
+
+ while (slot != MCA_NOTFOUND) {
+ /*
+ * Currently we only support the MC16/32 (MCA ID 002d)
+ */
+ slot = mca_find_unused_adapter(0x002d, slot);
+ if (slot == MCA_NOTFOUND)
+ break;
+
+ /*
+ * If we get here, we have an adapter.
+ */
+ if (versionprinted++ == 0)
+ printk("%s", version);
+
+ if ((dev = init_trdev(NULL, 0))==NULL) {
+ printk("madgemc: unable to allocate dev space\n");
+ return -1;
+ }
+ dev->dma = 0;
+
+ /*
+ * Fetch MCA config registers
+ */
+ for(i=0;i<4;i++)
+ posreg[i] = mca_read_stored_pos(slot, i+2);
+
+ card = kmalloc(sizeof(struct madgemc_card), GFP_KERNEL);
+ if (card==NULL) {
+ printk("madgemc: unable to allocate card struct\n");
+ return -1;
+ }
+ card->dev = dev;
+
+ /*
+ * Parse configuration information. This all comes
+ * directly from the publicly available @002d.ADF.
+ * Get it from Madge or your local ADF library.
+ */
+
+ /*
+ * Base address
+ */
+ dev->base_addr = 0x0a20 +
+ ((posreg[2] & MC16_POS2_ADDR2)?0x0400:0) +
+ ((posreg[0] & MC16_POS0_ADDR1)?0x1000:0) +
+ ((posreg[3] & MC16_POS3_ADDR3)?0x2000:0);
+
+ /*
+ * Interrupt line
+ */
+ switch(posreg[0] >> 6) { /* upper two bits */
+ case 0x1: dev->irq = 3; break;
+ case 0x2: dev->irq = 9; break; /* IRQ 2 = IRQ 9 */
+ case 0x3: dev->irq = 10; break;
+ default: dev->irq = 0; break;
+ }
+
+ if (dev->irq == 0) {
+ printk("%s: invalid IRQ\n", dev->name);
+ goto getout;
+ }
+
+ request_region(dev->base_addr, MADGEMC_IO_EXTENT, "madgemc");
+#if 0
+ /* why is this not working? */
+ if (request_region(dev->base_addr, MADGEMC_IO_EXTENT,
+ "madgemc")) {
+ printk(KERN_INFO "madgemc: unable to setup Smart MC in slot %d because of I/O base conflict at 0x%04lx\n", slot, dev->base_addr);
+ dev->base_addr += MADGEMC_SIF_OFFSET;
+ goto getout;
+ }
+#endif
+ dev->base_addr += MADGEMC_SIF_OFFSET;
+
+ /*
+ * Arbitration Level
+ */
+ card->arblevel = ((posreg[0] >> 1) & 0x7) + 8;
+
+ /*
+ * Burst mode and Fairness
+ */
+ card->burstmode = ((posreg[2] >> 6) & 0x3);
+ card->fairness = ((posreg[2] >> 4) & 0x1);
+
+ /*
+ * Ring Speed
+ */
+ if ((posreg[1] >> 2)&0x1)
+ card->ringspeed = 2; /* not selected */
+ else if ((posreg[2] >> 5) & 0x1)
+ card->ringspeed = 1; /* 16Mb */
+ else
+ card->ringspeed = 0; /* 4Mb */
+
+ /*
+ * Cable type
+ */
+ if ((posreg[1] >> 6)&0x1)
+ card->cabletype = 1; /* STP/DB9 */
+ else
+ card->cabletype = 0; /* UTP/RJ-45 */
+
+
+ /*
+ * ROM Info. This requires us to actually twiddle
+ * bits on the card, so we must ensure above that
+ * the base address is free of conflict (request_region above).
+ */
+ madgemc_read_rom(card);
+
+ if (card->manid != 0x4d) { /* something went wrong */
+ printk(KERN_INFO "%s: Madge MC ROM read failed (unknown manufacturer ID %02x)\n", dev->name, card->manid);
+ goto getout;
+ }
+
+ if ((card->cardtype != 0x08) && (card->cardtype != 0x0d)) {
+ printk(KERN_INFO "%s: Madge MC ROM read failed (unknown card ID %02x)\n", dev->name, card->cardtype);
+ goto getout;
+ }
+
+ /* All cards except Rev 0 and 1 MC16's have 256kb of RAM */
+ if ((card->cardtype == 0x08) && (card->cardrev <= 0x01))
+ card->ramsize = 128;
+ else
+ card->ramsize = 256;
+
+ printk("%s: %s Rev %d at 0x%04lx IRQ %d\n",
+ dev->name,
+ (card->cardtype == 0x08)?MADGEMC16_CARDNAME:
+ MADGEMC32_CARDNAME, card->cardrev,
+ dev->base_addr, dev->irq);
+
+ if (card->cardtype == 0x0d)
+ printk("%s: Warning: MC32 support is experimental and highly untested\n", dev->name);
+
+ if (card->ringspeed==2) { /* Unknown */
+ printk("%s: Warning: Ring speed not set in POS -- Please run the reference disk and set it!\n", dev->name);
+ card->ringspeed = 1; /* default to 16mb */
+ }
+
+ printk("%s: RAM Size: %dKB\n", dev->name, card->ramsize);
+
+ printk("%s: Ring Speed: %dMb/sec on %s\n", dev->name,
+ (card->ringspeed)?16:4,
+ card->cabletype?"STP/DB9":"UTP/RJ-45");
+ printk("%s: Arbitration Level: %d\n", dev->name,
+ card->arblevel);
+
+ printk("%s: Burst Mode: ", dev->name);
+ switch(card->burstmode) {
+ case 0: printk("Cycle steal"); break;
+ case 1: printk("Limited burst"); break;
+ case 2: printk("Delayed release"); break;
+ case 3: printk("Immediate release"); break;
+ }
+ printk(" (%s)\n", (card->fairness)?"Unfair":"Fair");
+
+
+ /*
+ * Enable SIF before we assign the interrupt handler,
+ * just in case we get spurious interrupts that need
+ * handling.
+ */
+ outb(0, dev->base_addr + MC_CONTROL_REG0); /* sanity */
+ madgemc_setsifsel(dev, 1);
+ if(request_irq(dev->irq, madgemc_interrupt, SA_SHIRQ,
+ "madgemc", dev))
+ goto getout;
+
+ madgemc_chipset_init(dev); /* enables interrupts! */
+ madgemc_setcabletype(dev, card->cabletype);
+
+ /* Setup MCA structures */
+ mca_set_adapter_name(slot, (card->cardtype == 0x08)?MADGEMC16_CARDNAME:MADGEMC32_CARDNAME);
+ mca_set_adapter_procfn(slot, madgemc_mcaproc, dev);
+ mca_mark_as_used(slot);
+
+ printk("%s: Ring Station Address: ", dev->name);
+ printk("%2.2x", dev->dev_addr[0]);
+ for (i = 1; i < 6; i++)
+ printk(":%2.2x", dev->dev_addr[i]);
+ printk("\n");
+
+ if (tmsdev_init(dev)) {
+ printk("%s: unable to get memory for dev->priv.\n",
+ dev->name);
+ return -1;
+ }
+ tp = (struct net_local *)dev->priv;
+
+ /*
+ * The MC16 is physically a 32bit card. However, Madge
+ * insists on calling it 16bit, so I'll assume here that
+ * they know what they're talking about. Cut off DMA
+ * at 16mb.
+ */
+ tp->dmalimit = ISA_MAX_ADDRESS; /* XXX: ?? */
+ tp->setnselout = madgemc_setnselout_pins;
+ tp->sifwriteb = madgemc_sifwriteb;
+ tp->sifreadb = madgemc_sifreadb;
+ tp->sifwritew = madgemc_sifwritew;
+ tp->sifreadw = madgemc_sifreadw;
+ tp->DataRate = (card->ringspeed)?SPEED_16:SPEED_4;
+
+ memcpy(tp->ProductID, "Madge MCA 16/4 ", PROD_ID_SIZE + 1);
+
+ dev->open = madgemc_open;
+ dev->stop = madgemc_close;
+
+ if (register_trdev(dev) == 0) {
+ /* Enlist in the card list */
+ card->next = madgemc_card_list;
+ madgemc_card_list = card;
+ } else {
+ printk("madgemc: register_trdev() returned non-zero.\n");
+
+ kfree(card);
+ kfree(dev->priv);
+ kfree(dev);
+ return -1;
+ }
+
+ slot++;
+ continue; /* successful, try to find another */
+
+ getout:
+ release_region(dev->base_addr-MADGEMC_SIF_OFFSET,
+ MADGEMC_IO_EXTENT);
+ kfree(card);
+ kfree(dev); /* release_trdev? */
+ slot++;
+ }
+
+ if (madgemc_card_list)
+ return 0;
+ return -1;
+}
+
+/*
+ * Handle interrupts generated by the card
+ *
+ * The MicroChannel Madge cards need slightly more handling
+ * after an interrupt than other TMS380 cards do.
+ *
+ * First we must make sure it was this card that generated the
+ * interrupt (since interrupt sharing is allowed). Then,
+ * because we're using level-triggered interrupts (as is
+ * standard on MCA), we must toggle the interrupt line
+ * on the card in order to claim and acknowledge the interrupt.
+ * Once that is done, the interrupt should be handlable in
+ * the normal tms380tr_interrupt() routine.
+ *
+ * There's two ways we can check to see if the interrupt is ours,
+ * both with their own disadvantages...
+ *
+ * 1) Read in the SIFSTS register from the TMS controller. This
+ * is guarenteed to be accurate, however, there's a fairly
+ * large performance penalty for doing so: the Madge chips
+ * must request the register from the Eagle, the Eagle must
+ * read them from its internal bus, and then take the route
+ * back out again, for a 16bit read.
+ *
+ * 2) Use the MC_CONTROL_REG0_SINTR bit from the Madge ASICs.
+ * The major disadvantage here is that the accuracy of the
+ * bit is in question. However, it cuts out the extra read
+ * cycles it takes to read the Eagle's SIF, as its only an
+ * 8bit read, and theoretically the Madge bit is directly
+ * connected to the interrupt latch coming out of the Eagle
+ * hardware (that statement is not verified).
+ *
+ * I can't determine which of these methods has the best win. For now,
+ * we make a compromise. Use the Madge way for the first interrupt,
+ * which should be the fast-path, and then once we hit the first
+ * interrupt, keep on trying using the SIF method until we've
+ * exhausted all contiguous interrupts.
+ *
+ */
+static void madgemc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ int pending,reg1;
+ struct net_device *dev;
+
+ if (!dev_id) {
+ printk("madgemc_interrupt: was not passed a dev_id!\n");
+ return;
+ }
+
+ dev = (struct net_device *)dev_id;
+
+ /* Make sure its really us. -- the Madge way */
+ pending = inb(dev->base_addr + MC_CONTROL_REG0);
+ if (!(pending & MC_CONTROL_REG0_SINTR))
+ return; /* not our interrupt */
+
+ /*
+ * Since we're level-triggered, we may miss the rising edge
+ * of the next interrupt while we're off handling this one,
+ * so keep checking until the SIF verifies that it has nothing
+ * left for us to do.
+ */
+ pending = STS_SYSTEM_IRQ;
+ do {
+ if (pending & STS_SYSTEM_IRQ) {
+
+ /* Toggle the interrupt to reset the latch on card */
+ reg1 = inb(dev->base_addr + MC_CONTROL_REG1);
+ outb(reg1 ^ MC_CONTROL_REG1_SINTEN,
+ dev->base_addr + MC_CONTROL_REG1);
+ outb(reg1, dev->base_addr + MC_CONTROL_REG1);
+
+ /* Continue handling as normal */
+ tms380tr_interrupt(irq, dev_id, regs);
+
+ pending = SIFREADW(SIFSTS); /* restart - the SIF way */
+
+ } else
+ return;
+ } while (1);
+
+ return; /* not reachable */
+}
+
+/*
+ * Set the card to the prefered ring speed.
+ *
+ * Unlike newer cards, the MC16/32 have their speed selection
+ * circuit connected to the Madge ASICs and not to the TMS380
+ * NSELOUT pins. Set the ASIC bits correctly here, and return
+ * zero to leave the TMS NSELOUT bits unaffected.
+ *
+ */
+unsigned short madgemc_setnselout_pins(struct net_device *dev)
+{
+ unsigned char reg1;
+ struct net_local *tp = (struct net_local *)dev->priv;
+
+ reg1 = inb(dev->base_addr + MC_CONTROL_REG1);
+
+ if(tp->DataRate == SPEED_16)
+ reg1 |= MC_CONTROL_REG1_SPEED_SEL; /* add for 16mb */
+ else if (reg1 & MC_CONTROL_REG1_SPEED_SEL)
+ reg1 ^= MC_CONTROL_REG1_SPEED_SEL; /* remove for 4mb */
+ outb(reg1, dev->base_addr + MC_CONTROL_REG1);
+
+ return 0; /* no change */
+}
+
+/*
+ * Set the register page. This equates to the SRSX line
+ * on the TMS380Cx6.
+ *
+ * Register selection is normally done via three contiguous
+ * bits. However, some boards (such as the MC16/32) use only
+ * two bits, plus a seperate bit in the glue chip. This
+ * sets the SRSX bit (the top bit). See page 4-17 in the
+ * Yellow Book for which registers are affected.
+ *
+ */
+static void madgemc_setregpage(struct net_device *dev, int page)
+{
+ static int reg1 = 0;
+
+ reg1 = inb(dev->base_addr + MC_CONTROL_REG1);
+ if ((page == 0) && (reg1 & MC_CONTROL_REG1_SRSX)) {
+ outb(reg1 ^ MC_CONTROL_REG1_SRSX,
+ dev->base_addr + MC_CONTROL_REG1);
+ }
+ else if (page == 1) {
+ outb(reg1 | MC_CONTROL_REG1_SRSX,
+ dev->base_addr + MC_CONTROL_REG1);
+ }
+ reg1 = inb(dev->base_addr + MC_CONTROL_REG1);
+
+ return;
+}
+
+/*
+ * The SIF registers are not mapped into register space by default
+ * Set this to 1 to map them, 0 to map the BIA ROM.
+ *
+ */
+static void madgemc_setsifsel(struct net_device *dev, int val)
+{
+ unsigned int reg0;
+
+ reg0 = inb(dev->base_addr + MC_CONTROL_REG0);
+ if ((val == 0) && (reg0 & MC_CONTROL_REG0_SIFSEL)) {
+ outb(reg0 ^ MC_CONTROL_REG0_SIFSEL,
+ dev->base_addr + MC_CONTROL_REG0);
+ } else if (val == 1) {
+ outb(reg0 | MC_CONTROL_REG0_SIFSEL,
+ dev->base_addr + MC_CONTROL_REG0);
+ }
+ reg0 = inb(dev->base_addr + MC_CONTROL_REG0);
+
+ return;
+}
+
+/*
+ * Enable SIF interrupts
+ *
+ * This does not enable interrupts in the SIF, but rather
+ * enables SIF interrupts to be passed onto the host.
+ *
+ */
+static void madgemc_setint(struct net_device *dev, int val)
+{
+ unsigned int reg1;
+
+ reg1 = inb(dev->base_addr + MC_CONTROL_REG1);
+ if ((val == 0) && (reg1 & MC_CONTROL_REG1_SINTEN)) {
+ outb(reg1 ^ MC_CONTROL_REG1_SINTEN,
+ dev->base_addr + MC_CONTROL_REG1);
+ } else if (val == 1) {
+ outb(reg1 | MC_CONTROL_REG1_SINTEN,
+ dev->base_addr + MC_CONTROL_REG1);
+ }
+
+ return;
+}
+
+/*
+ * Cable type is set via control register 7. Bit zero high
+ * for UTP, low for STP.
+ */
+static void madgemc_setcabletype(struct net_device *dev, int type)
+{
+ outb((type==0)?MC_CONTROL_REG7_CABLEUTP:MC_CONTROL_REG7_CABLESTP,
+ dev->base_addr + MC_CONTROL_REG7);
+}
+
+/*
+ * Enable the functions of the Madge chipset needed for
+ * full working order.
+ */
+static int madgemc_chipset_init(struct net_device *dev)
+{
+ outb(0, dev->base_addr + MC_CONTROL_REG1); /* pull SRESET low */
+ tms380tr_wait(100); /* wait for card to reset */
+
+ /* bring back into normal operating mode */
+ outb(MC_CONTROL_REG1_NSRESET, dev->base_addr + MC_CONTROL_REG1);
+
+ /* map SIF registers */
+ madgemc_setsifsel(dev, 1);
+
+ /* enable SIF interrupts */
+ madgemc_setint(dev, 1);
+
+ return 0;
+}
+
+/*
+ * Disable the board, and put back into power-up state.
+ */
+void madgemc_chipset_close(struct net_device *dev)
+{
+ /* disable interrupts */
+ madgemc_setint(dev, 0);
+ /* unmap SIF registers */
+ madgemc_setsifsel(dev, 0);
+
+ return;
+}
+
+/*
+ * Read the card type (MC16 or MC32) from the card.
+ *
+ * The configuration registers are stored in two seperate
+ * pages. Pages are flipped by clearing bit 3 of CONTROL_REG0 (PAGE)
+ * for page zero, or setting bit 3 for page one.
+ *
+ * Page zero contains the following data:
+ * Byte 0: Manufacturer ID (0x4D -- ASCII "M")
+ * Byte 1: Card type:
+ * 0x08 for MC16
+ * 0x0D for MC32
+ * Byte 2: Card revision
+ * Byte 3: Mirror of POS config register 0
+ * Byte 4: Mirror of POS 1
+ * Byte 5: Mirror of POS 2
+ *
+ * Page one contains the following data:
+ * Byte 0: Unused
+ * Byte 1-6: BIA, MSB to LSB.
+ *
+ * Note that to read the BIA, we must unmap the SIF registers
+ * by clearing bit 2 of CONTROL_REG0 (SIFSEL), as the data
+ * will reside in the same logical location. For this reason,
+ * _never_ read the BIA while the Eagle processor is running!
+ * The SIF will be completely inaccessible until the BIA operation
+ * is complete.
+ *
+ */
+static void madgemc_read_rom(struct madgemc_card *card)
+{
+ unsigned long ioaddr;
+ unsigned char reg0, reg1, tmpreg0, i;
+
+ ioaddr = card->dev->base_addr;
+
+ reg0 = inb(ioaddr + MC_CONTROL_REG0);
+ reg1 = inb(ioaddr + MC_CONTROL_REG1);
+
+ /* Switch to page zero and unmap SIF */
+ tmpreg0 = reg0 & ~(MC_CONTROL_REG0_PAGE + MC_CONTROL_REG0_SIFSEL);
+ outb(tmpreg0, ioaddr + MC_CONTROL_REG0);
+
+ card->manid = inb(ioaddr + MC_ROM_MANUFACTURERID);
+ card->cardtype = inb(ioaddr + MC_ROM_ADAPTERID);
+ card->cardrev = inb(ioaddr + MC_ROM_REVISION);
+
+ /* Switch to rom page one */
+ outb(tmpreg0 | MC_CONTROL_REG0_PAGE, ioaddr + MC_CONTROL_REG0);
+
+ /* Read BIA */
+ card->dev->addr_len = 6;
+ for (i = 0; i < 6; i++)
+ card->dev->dev_addr[i] = inb(ioaddr + MC_ROM_BIA_START + i);
+
+ /* Restore original register values */
+ outb(reg0, ioaddr + MC_CONTROL_REG0);
+ outb(reg1, ioaddr + MC_CONTROL_REG1);
+
+ return;
+}
+
+static int madgemc_open(struct net_device *dev)
+{
+ /*
+ * Go ahead and reinitialize the chipset again, just to
+ * make sure we didn't get left in a bad state.
+ */
+ madgemc_chipset_init(dev);
+ tms380tr_open(dev);
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int madgemc_close(struct net_device *dev)
+{
+ tms380tr_close(dev);
+ madgemc_chipset_close(dev);
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+/*
+ * Give some details available from /proc/mca/slotX
+ */
+static int madgemc_mcaproc(char *buf, int slot, void *d)
+{
+ struct net_device *dev = (struct net_device *)d;
+ struct madgemc_card *curcard = madgemc_card_list;
+ int len = 0;
+
+ while (curcard) { /* search for card struct */
+ if (curcard->dev == dev)
+ break;
+ curcard = curcard->next;
+ }
+ len += sprintf(buf+len, "-------\n");
+ if (curcard) {
+ struct net_local *tp = (struct net_local *)dev->priv;
+ int i;
+
+ len += sprintf(buf+len, "Card Revision: %d\n", curcard->cardrev);
+ len += sprintf(buf+len, "RAM Size: %dkb\n", curcard->ramsize);
+ len += sprintf(buf+len, "Cable type: %s\n", (curcard->cabletype)?"STP/DB9":"UTP/RJ-45");
+ len += sprintf(buf+len, "Configured ring speed: %dMb/sec\n", (curcard->ringspeed)?16:4);
+ len += sprintf(buf+len, "Running ring speed: %dMb/sec\n", (tp->DataRate==SPEED_16)?16:4);
+ len += sprintf(buf+len, "Device: %s\n", dev->name);
+ len += sprintf(buf+len, "IO Port: 0x%04lx\n", dev->base_addr);
+ len += sprintf(buf+len, "IRQ: %d\n", dev->irq);
+ len += sprintf(buf+len, "Arbitration Level: %d\n", curcard->arblevel);
+ len += sprintf(buf+len, "Burst Mode: ");
+ switch(curcard->burstmode) {
+ case 0: len += sprintf(buf+len, "Cycle steal"); break;
+ case 1: len += sprintf(buf+len, "Limited burst"); break;
+ case 2: len += sprintf(buf+len, "Delayed release"); break;
+ case 3: len += sprintf(buf+len, "Immediate release"); break;
+ }
+ len += sprintf(buf+len, " (%s)\n", (curcard->fairness)?"Unfair":"Fair");
+
+ len += sprintf(buf+len, "Ring Station Address: ");
+ len += sprintf(buf+len, "%2.2x", dev->dev_addr[0]);
+ for (i = 1; i < 6; i++)
+ len += sprintf(buf+len, " %2.2x", dev->dev_addr[i]);
+ len += sprintf(buf+len, "\n");
+ } else
+ len += sprintf(buf+len, "Card not configured\n");
+
+ return len;
+}
+
+#ifdef MODULE
+
+int init_module(void)
+{
+ /* Probe for cards. */
+ if (madgemc_probe()) {
+ printk(KERN_NOTICE "madgemc.c: No cards found.\n");
+ }
+ /* lock_tms380_module(); */
+ return (0);
+}
+
+void cleanup_module(void)
+{
+ struct net_device *dev;
+ struct madgemc_card *this_card;
+
+ while (madgemc_card_list) {
+ dev = madgemc_card_list->dev;
+ unregister_trdev(dev);
+ release_region(dev->base_addr-MADGEMC_SIF_OFFSET, MADGEMC_IO_EXTENT);
+ free_irq(dev->irq, dev);
+ kfree(dev->priv);
+ kfree(dev);
+ this_card = madgemc_card_list;
+ madgemc_card_list = this_card->next;
+ kfree(this_card);
+ }
+ /* unlock_tms380_module(); */
+}
+#endif /* MODULE */
+
+
+/*
+ * Local variables:
+ * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c madgemc.c"
+ * alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c madgemc.c"
+ * c-set-style "K&R"
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff --git a/drivers/net/tokenring/madgemc.h b/drivers/net/tokenring/madgemc.h
new file mode 100644
index 000000000..2dd822203
--- /dev/null
+++ b/drivers/net/tokenring/madgemc.h
@@ -0,0 +1,70 @@
+/*
+ * madgemc.h: Header for the madgemc tms380tr module
+ *
+ * Authors:
+ * - Adam Fritzler <mid@auk.cx>
+ */
+
+#ifndef __LINUX_MADGEMC_H
+#define __LINUX_MADGEMC_H
+
+#ifdef __KERNEL__
+
+#define MADGEMC16_CARDNAME "Madge Smart 16/4 MC16 Ringnode"
+#define MADGEMC32_CARDNAME "Madge Smart 16/4 MC32 Ringnode"
+
+/*
+ * Bit definitions for the POS config registers
+ */
+#define MC16_POS0_ADDR1 0x20
+#define MC16_POS2_ADDR2 0x04
+#define MC16_POS3_ADDR3 0x20
+
+#define MC_CONTROL_REG0 ((long)-8) /* 0x00 */
+#define MC_CONTROL_REG1 ((long)-7) /* 0x01 */
+#define MC_ADAPTER_POS_REG0 ((long)-6) /* 0x02 */
+#define MC_ADAPTER_POS_REG1 ((long)-5) /* 0x03 */
+#define MC_ADAPTER_POS_REG2 ((long)-4) /* 0x04 */
+#define MC_ADAPTER_REG5_UNUSED ((long)-3) /* 0x05 */
+#define MC_ADAPTER_REG6_UNUSED ((long)-2) /* 0x06 */
+#define MC_CONTROL_REG7 ((long)-1) /* 0x07 */
+
+#define MC_CONTROL_REG0_UNKNOWN1 0x01
+#define MC_CONTROL_REG0_UNKNOWN2 0x02
+#define MC_CONTROL_REG0_SIFSEL 0x04
+#define MC_CONTROL_REG0_PAGE 0x08
+#define MC_CONTROL_REG0_TESTINTERRUPT 0x10
+#define MC_CONTROL_REG0_UNKNOWN20 0x20
+#define MC_CONTROL_REG0_SINTR 0x40
+#define MC_CONTROL_REG0_UNKNOWN80 0x80
+
+#define MC_CONTROL_REG1_SINTEN 0x01
+#define MC_CONTROL_REG1_BITOFDEATH 0x02
+#define MC_CONTROL_REG1_NSRESET 0x04
+#define MC_CONTROL_REG1_UNKNOWN8 0x08
+#define MC_CONTROL_REG1_UNKNOWN10 0x10
+#define MC_CONTROL_REG1_UNKNOWN20 0x20
+#define MC_CONTROL_REG1_SRSX 0x40
+#define MC_CONTROL_REG1_SPEED_SEL 0x80
+
+#define MC_CONTROL_REG7_CABLESTP 0x00
+#define MC_CONTROL_REG7_CABLEUTP 0x01
+
+/*
+ * ROM Page Zero
+ */
+#define MC_ROM_MANUFACTURERID 0x00
+#define MC_ROM_ADAPTERID 0x01
+#define MC_ROM_REVISION 0x02
+#define MC_ROM_CONFIG0 0x03
+#define MC_ROM_CONFIG1 0x04
+#define MC_ROM_CONFIG2 0x05
+
+/*
+ * ROM Page One
+ */
+#define MC_ROM_UNUSED_BYTE 0x00
+#define MC_ROM_BIA_START 0x01
+
+#endif /* __KERNEL__ */
+#endif /* __LINUX_MADGEMC_H */
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
index ecc43401f..cd353e3f4 100644
--- a/drivers/net/tokenring/smctr.c
+++ b/drivers/net/tokenring/smctr.c
@@ -17,11 +17,10 @@
* JS Jay Schulist <jschlst@turbolinux.com>
*
* To do:
- * 1. MCA SMC TokenCard Support. (Some support is already done).
- * 4. Multicast support.
+ * 1. Multicast support.
*/
-static const char *version = "smctr.c: v1.0 1/1/00 by jschlst@turbolinux.com\n";
+static const char *version = "smctr.c: v1.1 1/1/00 by jschlst@turbolinux.com\n";
static const char *cardname = "smctr";
#ifdef MODULE
@@ -29,6 +28,7 @@ static const char *cardname = "smctr";
#include <linux/version.h>
#endif
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
@@ -48,6 +48,7 @@ static const char *cardname = "smctr";
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/mca.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -66,6 +67,10 @@ static unsigned int smctr_portlist[] __initdata = {
0
};
+#ifdef CONFIG_MCA
+static unsigned int smctr_posid = 0x6ec6;
+#endif
+
static int ringspeed = 0;
/* SMC Name of the Adapter. */
@@ -91,6 +96,7 @@ static int smctr_bypass_state(struct net_device *dev);
/* C */
static int smctr_checksum_firmware(struct net_device *dev);
+static int __init smctr_chk_isa(struct net_device *dev);
static int smctr_chg_rx_mask(struct net_device *dev);
static int smctr_clear_int(struct net_device *dev);
static int smctr_clear_trc_reset(int ioaddr);
@@ -109,11 +115,8 @@ static int smctr_enable_adapter_ctrl_store(struct net_device *dev);
static int smctr_enable_adapter_ram(struct net_device *dev);
static int smctr_enable_bic_int(struct net_device *dev);
-/* F */
-static int __init smctr_find_adapter(struct net_device *dev);
-
/* G */
-static int __init smctr_get_boardid(struct net_device *dev);
+static int __init smctr_get_boardid(struct net_device *dev, int mca);
static int smctr_get_group_address(struct net_device *dev);
static int smctr_get_functional_address(struct net_device *dev);
static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev);
@@ -478,13 +481,171 @@ static int smctr_checksum_firmware(struct net_device *dev)
return (0);
}
+static int smctr_chk_mca(struct net_device *dev)
+{
+#ifdef CONFIG_MCA
+ struct net_local *tp = (struct net_local *)dev->priv;
+ int current_slot;
+ __u8 r1, r2, r3, r4, r5;
+
+ current_slot = mca_find_unused_adapter(smctr_posid, 0);
+ if(current_slot == MCA_NOTFOUND)
+ return (-ENODEV);
+
+ mca_set_adapter_name(current_slot, smctr_name);
+ mca_mark_as_used(current_slot);
+ tp->slot_num = current_slot;
+
+ r1 = mca_read_stored_pos(tp->slot_num, 2);
+ r2 = mca_read_stored_pos(tp->slot_num, 3);
+
+ if(tp->slot_num)
+ outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num - 1) | CNFG_SLOT_ENABLE_BIT));
+ else
+ outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num) | CNFG_SLOT_ENABLE_BIT));
+
+ r1 = inb(CNFG_POS_REG1);
+ r2 = inb(CNFG_POS_REG0);
+
+ tp->bic_type = BIC_594_CHIP;
+
+ /* IO */
+ r2 = mca_read_stored_pos(tp->slot_num, 2);
+ r2 &= 0xF0;
+ dev->base_addr = ((__u16)r2 << 8) + (__u16)0x800;
+ request_region(dev->base_addr, SMCTR_IO_EXTENT, smctr_name);
+
+ /* IRQ */
+ r5 = mca_read_stored_pos(tp->slot_num, 5);
+ r5 &= 0xC;
+ switch(r5)
+ {
+ case 0:
+ dev->irq = 3;
+ break;
+
+ case 0x4:
+ dev->irq = 4;
+ break;
+
+ case 0x8:
+ dev->irq = 10;
+ break;
+
+ default:
+ dev->irq = 15;
+ break;
+ }
+ if(request_irq(dev->irq, smctr_interrupt, SA_SHIRQ, smctr_name, dev))
+ return (-ENODEV);
+
+ /* Get RAM base */
+ r3 = mca_read_stored_pos(tp->slot_num, 3);
+ if(r3 & 0x8)
+ {
+ if(r3 & 0x80)
+ tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0xFD0000;
+ else
+ tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0x0D0000;
+ }
+ else
+ {
+ if(r3 & 0x80)
+ tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0xFC0000;
+ else
+ tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0x0C0000;
+ }
+
+ /* Get Ram Size */
+ r3 &= 0x30;
+ r3 >>= 4;
+
+ tp->ram_usable = (__u16)CNFG_SIZE_8KB << r3;
+ tp->ram_size = (__u16)CNFG_SIZE_64KB;
+ tp->board_id |= TOKEN_MEDIA;
+
+ r4 = mca_read_stored_pos(tp->slot_num, 4);
+ if(r4 & 0x8)
+ tp->rom_base = ((__u32)(r4 & 0x7) << 13) + 0xD0000;
+ else
+ tp->rom_base = ((__u32)(r4 & 0x7) << 13) + 0xC0000;
+
+ /* Get ROM size. */
+ r4 >>= 4;
+ if(r4 == 0)
+ tp->rom_size = CNFG_SIZE_8KB;
+ else
+ {
+ if(r4 == 1)
+ tp->rom_size = CNFG_SIZE_16KB;
+ else
+ {
+ if(r4 == 2)
+ tp->rom_size = CNFG_SIZE_32KB;
+ else
+ tp->rom_size = ROM_DISABLE;
+ }
+ }
+
+ /* Get Media Type. */
+ r5 = mca_read_stored_pos(tp->slot_num, 5);
+ r5 &= CNFG_MEDIA_TYPE_MASK;
+ switch(r5)
+ {
+ case (0):
+ tp->media_type = MEDIA_STP_4;
+ break;
+
+ case (1):
+ tp->media_type = MEDIA_STP_16;
+ break;
+
+ case (3):
+ tp->media_type = MEDIA_UTP_16;
+ break;
+
+ default:
+ tp->media_type = MEDIA_UTP_4;
+ break;
+ }
+ tp->media_menu = 14;
+
+ r2 = mca_read_stored_pos(tp->slot_num, 2);
+ if(!(r2 & 0x02))
+ tp->mode_bits |= EARLY_TOKEN_REL;
+
+ /* Disable slot */
+ outb(CNFG_POS_CONTROL_REG, 0);
+
+ tp->board_id = smctr_get_boardid(dev, 1);
+ switch(tp->board_id & 0xffff)
+ {
+ case WD8115TA:
+ smctr_model = "8115T/A";
+ break;
+
+ case WD8115T:
+ smctr_model = "8115T";
+ break;
+
+ default:
+ smctr_model = "Unknown";
+ break;
+ }
+
+ return (0);
+#else
+ return (-1);
+#endif /* CONFIG_MCA */
+}
+
static int smctr_chg_rx_mask(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
int err = 0;
if(smctr_debug > 10)
- printk("%s: smctr_chg_rx_mask\n", dev->name);
+ printk("%s: smctr_chg_rx_mask\n", dev->name);
smctr_enable_16bit(dev);
smctr_set_page(dev, (__u8 *)tp->ram_access);
@@ -804,7 +965,7 @@ static int smctr_enable_bic_int(struct net_device *dev)
return (0);
}
-static int __init smctr_find_adapter(struct net_device *dev)
+static int __init smctr_chk_isa(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
int ioaddr = dev->base_addr;
@@ -813,7 +974,10 @@ static int __init smctr_find_adapter(struct net_device *dev)
int i;
if(smctr_debug > 10)
- printk("%s: smctr_find_adapter %#4x\n", dev->name, ioaddr);
+ printk("%s: smctr_chk_isa %#4x\n", dev->name, ioaddr);
+
+ if((ioaddr & 0x1F) != 0)
+ return (-ENODEV);
/* Checksum SMC node address */
for(i = 0; i < 8; i++)
@@ -823,7 +987,7 @@ static int __init smctr_find_adapter(struct net_device *dev)
}
if(chksum != NODE_ADDR_CKSUM)
- return (-1); /* Adapter Not Found */
+ return (-ENODEV); /* Adapter Not Found */
/* Grab the region so that no one else tries to probe our ioports. */
request_region(ioaddr, SMCTR_IO_EXTENT, smctr_name);
@@ -843,7 +1007,7 @@ static int __init smctr_find_adapter(struct net_device *dev)
return (-1);
/* Get adapter ID */
- tp->board_id = smctr_get_boardid(dev);
+ tp->board_id = smctr_get_boardid(dev, 0);
switch(tp->board_id & 0xffff)
{
case WD8115TA:
@@ -1011,7 +1175,7 @@ static int __init smctr_find_adapter(struct net_device *dev)
return (0);
}
-static int __init smctr_get_boardid(struct net_device *dev)
+static int __init smctr_get_boardid(struct net_device *dev, int mca)
{
struct net_local *tp = (struct net_local *)dev->priv;
int ioaddr = dev->base_addr;
@@ -1020,22 +1184,35 @@ static int __init smctr_get_boardid(struct net_device *dev)
tp->board_id = BoardIdMask = 0;
- BoardIdMask |= (INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT);
- tp->extra_info |= (INTERFACE_584_CHIP + RAM_SIZE_64K
- + NIC_825_BIT + ALTERNATE_IRQ_BIT);
-
- r = inb(ioaddr + BID_REG_1);
- r &= 0x0c;
- outb(r, ioaddr + BID_REG_1);
- r = inb(ioaddr + BID_REG_1);
+ if(mca)
+ {
+ BoardIdMask |= (MICROCHANNEL+INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT);
+ tp->extra_info |= (INTERFACE_594_CHIP+RAM_SIZE_64K+NIC_825_BIT+ALTERNATE_IRQ_BIT+SLOT_16BIT);
+ }
+ else
+ {
+ BoardIdMask|=(INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT);
+ tp->extra_info |= (INTERFACE_584_CHIP + RAM_SIZE_64K
+ + NIC_825_BIT + ALTERNATE_IRQ_BIT);
+ }
- if(r & BID_SIXTEEN_BIT_BIT)
- {
- tp->extra_info |= SLOT_16BIT;
- tp->adapter_bus = BUS_ISA16_TYPE;
- }
- else
- tp->adapter_bus = BUS_ISA8_TYPE;
+ if(!mca)
+ {
+ r = inb(ioaddr + BID_REG_1);
+ r &= 0x0c;
+ outb(r, ioaddr + BID_REG_1);
+ r = inb(ioaddr + BID_REG_1);
+
+ if(r & BID_SIXTEEN_BIT_BIT)
+ {
+ tp->extra_info |= SLOT_16BIT;
+ tp->adapter_bus = BUS_ISA16_TYPE;
+ }
+ else
+ tp->adapter_bus = BUS_ISA8_TYPE;
+ }
+ else
+ tp->adapter_bus = BUS_MCA_TYPE;
/* Get Board Id Byte */
IdByte = inb(ioaddr + BID_BOARD_ID_BYTE);
@@ -3536,10 +3713,6 @@ static int __init smctr_probe1(struct net_device *dev, int ioaddr)
return (-ENOMEM);
#endif
- /* See if we have a SMCTR card floating around. */
- if((ioaddr & 0x1F) != 0)
- return (-ENODEV); /* No Adapter */
-
/* Setup this devices private information structure */
tp = (struct net_local *)kmalloc(sizeof(struct net_local),
GFP_KERNEL);
@@ -3549,11 +3722,16 @@ static int __init smctr_probe1(struct net_device *dev, int ioaddr)
dev->priv = tp;
dev->base_addr = ioaddr;
- err = smctr_find_adapter(dev);
+ /* Actually detect an adapter now. */
+ err = smctr_chk_isa(dev);
if(err < 0)
{
- kfree_s(tp, sizeof(struct net_local));
- return (-ENODEV);
+ err = smctr_chk_mca(dev);
+ if(err < 0)
+ {
+ kfree_s(tp, sizeof(struct net_local));
+ return (-ENODEV);
+ }
}
tp = (struct net_local *)dev->priv;
@@ -5696,6 +5874,12 @@ void cleanup_module(void)
{
if(dev_smctr[i])
{
+#ifdef CONFIG_MCA
+ struct net_local *tp
+ = (struct net_local *)dev_smctr[i]->priv;
+ if(tp->slot_num)
+ mca_mark_as_unused(tp->slot_num);
+#endif
unregister_trdev(dev_smctr[i]);
release_region(dev_smctr[i]->base_addr,
SMCTR_IO_EXTENT);
diff --git a/drivers/net/tokenring/smctr.h b/drivers/net/tokenring/smctr.h
index 4a7c8c3bd..9d447dccf 100644
--- a/drivers/net/tokenring/smctr.h
+++ b/drivers/net/tokenring/smctr.h
@@ -982,6 +982,9 @@ typedef struct net_local {
__u8 join_state;
+ __u8 slot_num;
+ __u16 pos_id;
+
__u32 *ptr_una;
__u32 *ptr_bcn_type;
__u32 *ptr_tx_fifo_underruns;
@@ -1420,11 +1423,9 @@ routine */
* adapter_type The adapter_type field describes the adapter/bus
* configuration.
*/
-#define BUS_UNK_TYPE 0x0000 /* */
#define BUS_ISA16_TYPE 0x0001 /* 16 bit adap in 16 bit (E)ISA slot */
#define BUS_ISA8_TYPE 0x0002 /* 8/16b adap in 8 bit XT/(E)ISA slot */
-#define BUS_MCA_TYPE 0x0003 /* Micro Channel adapter */#define BUS_EISA32M_TYPE 0x0004 /* EISA 32 bit bus master adapter */#define BUS_EISA32S_TYPE 0x0005 /* EISA 32 bit bus slave adapter */#define BUS_PCMCIA_TYPE 0x0006 /* PCMCIA adapter */
-#define BUS_PCI_TYPE 0x0007 /* PCI bus */
+#define BUS_MCA_TYPE 0x0003 /* Micro Channel adapter */
/*
* Receive Mask definitions
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
index 5d024c2d4..7e1933895 100644
--- a/drivers/net/tokenring/tms380tr.c
+++ b/drivers/net/tokenring/tms380tr.c
@@ -1,5 +1,5 @@
/*
- * tms380tr.c: A network driver for Texas Instruments TMS380-based
+ * tms380tr.c: A network driver library for Texas Instruments TMS380-based
* Token Ring Adapters.
*
* Originally sktr.c: Written 1997 by Christoph Goos
@@ -10,14 +10,16 @@
* This software may be used and distributed according to the terms
* of the GNU Public License, incorporated herein by reference.
*
- * This device driver works with the following TMS380 adapters:
+ * The following modules are currently available for card support:
+ * - tmspci (Generic PCI card support)
+ * - abyss (Madge PCI support)
+ *
+ * The following cards are currently lacking support, even
+ * though they were supported in previous versions, because
+ * their code did not get migrated into a seperate module:
* - SysKonnect TR4/16(+) ISA (SK-4190)
- * - SysKonnect TR4/16(+) PCI (SK-4590)
- * - SysKonnect TR4/16 PCI (SK-4591)
- * - Compaq TR 4/16 PCI
- * - Thomas-Conrad TC4048 4/16 PCI
- * - 3Com 3C339 Token Link Velocity
- * - Any ISA or PCI adapter using only the TMS380 chipset
+ * They are no longer supported by this driver, at least until
+ * a module gets written for them.
*
* Sources:
* - The hardware related parts of this driver are take from
@@ -27,14 +29,16 @@
* - Also various other drivers in the linux source tree were taken
* as samples for some tasks.
* - TI TMS380 Second-Generation Token Ring User's Guide
- * - TI datasheets for respective chips
- * - David Hein at Texas Instruments
+ * - TI datasheets for respective chips
+ * - David Hein at Texas Instruments
+ * - Various Madge employees
*
* Maintainer(s):
* JS Jay Schulist jschlst@turbolinux.com
* CG Christoph Goos cgoos@syskonnect.de
* AF Adam Fritzler mid@auk.cx
- *
+ * MLP Mike Phillips phillim@amtrak.com
+ *
* Modification History:
* 29-Aug-97 CG Created
* 04-Apr-98 CG Fixed problems caused by tok_timer_check
@@ -42,22 +46,33 @@
* 27-May-98 JS Formated to Linux Kernel Format
* 31-May-98 JS Hacked in PCI support
* 16-Jun-98 JS Modulized for multiple cards with one driver
- * Sep-99 AF Renamed to tms380tr (supports more than SK's)
+ * Sep-99 AF Renamed to tms380tr (supports more than SK's)
* 23-Sep-99 AF Added Compaq and Thomas-Conrad PCI support
* Fixed a bug causing double copies on PCI
* Fixed for new multicast stuff (2.2/2.3)
* 25-Sep-99 AF Uped TPL_NUM from 3 to 9
* Removed extraneous 'No free TPL'
+ * 22-Dec-99 AF Added Madge PCI Mk2 support and generalized
+ * parts of the initilization procedure.
+ * 30-Dec-99 AF Turned tms380tr into a library ala 8390.
+ * Madge support is provided in the abyss module
+ * Generic PCI support is in the tmspci module.
*
* To do:
- * 1. Selectable 16 Mbps or 4Mbps
- * 2. Multi/Broadcast packet handling (this may have fixed itself)
- *
+ * 1. Multi/Broadcast packet handling (this may have fixed itself)
+ * 2. Write a sktrisa module that includes the old ISA support
+ * 3. Allow modules to load their own microcode
+ * 4. Speed up the BUD process -- freezing the kernel for 3+sec is
+ * quite unacceptable.
+ * 5. Still a few remaining stalls when the cable is unplugged.
*/
-static const char *version = "tms380tr.c: v1.03 29/09/1999 by Christoph Goos, Adam Fritzler\n";
+#ifdef MODULE
+static const char *version = "tms380tr.c: v1.07 21/01/2000 by Christoph Goos, Adam Fritzler\n";
+#endif
#ifdef MODULE
+#define EXPORT_SYMTAB
#include <linux/module.h>
#include <linux/version.h>
#endif
@@ -78,6 +93,7 @@ static const char *version = "tms380tr.c: v1.03 29/09/1999 by Christoph Goos, Ad
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/irq.h>
+#include <asm/uaccess.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/pci.h>
@@ -90,45 +106,6 @@ static const char *version = "tms380tr.c: v1.03 29/09/1999 by Christoph Goos, Ad
#include "tms380tr.h" /* Our Stuff */
#include "tms380tr_microcode.h" /* TI microcode for COMMprocessor */
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int tms380tr_portlist[] __initdata = {
- 0x0A20, 0x1A20, 0x0B20, 0x1B20, 0x0980, 0x1980, 0x0900, 0x1900,
- 0
-};
-
-/* A zero-terminated list of IRQs to be probed.
- * Used again after initial probe for tms380tr_chipset_init, called from tms380tr_open.
- */
-static unsigned short tms380tr_irqlist[] = {
- 3, 5, 9, 10, 11, 12, 15,
- 0
-};
-
-/* A zero-terminated list of DMAs to be probed. */
-static int tms380tr_dmalist[] __initdata = {
- 5, 6, 7,
- 0
-};
-
-/*
- * Table used for card detection and type determination.
- */
-struct cardinfo_table cardinfo[] = {
- { 0, 0, 0,
- "Unknown TMS380 Token Ring Adapter"},
- { TMS_ISA, 0, 0,
- "SK NET TR 4/16 ISA"},
- { TMS_PCI, PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TOKENRING,
- "Compaq 4/16 TR PCI"},
- { TMS_PCI, PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_TR,
- "SK NET TR 4/16 PCI"},
- { TMS_PCI, PCI_VENDOR_ID_TCONRAD, PCI_DEVICE_ID_TCONRAD_TOKENRING,
- "Thomas-Conrad TC4048 PCI 4/16"},
- { TMS_PCI, PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C339,
- "3Com Token Link Velocity"},
- { 0, 0, 0, NULL}
-};
-
/* Use 0 for production, 1 for verification, 2 for debug, and
* 3 for very verbose debug.
*/
@@ -137,24 +114,24 @@ struct cardinfo_table cardinfo[] = {
#endif
static unsigned int tms380tr_debug = TMS380TR_DEBUG;
-/* The number of low I/O ports used by the tokencard. */
-#define TMS380TR_IO_EXTENT 32
-
/* Index to functions, as function prototypes.
* Alphabetical by function name.
*/
+/* "A" */
/* "B" */
static int tms380tr_bringup_diags(struct net_device *dev);
/* "C" */
static void tms380tr_cancel_tx_queue(struct net_local* tp);
static int tms380tr_chipset_init(struct net_device *dev);
static void tms380tr_chk_irq(struct net_device *dev);
+#if 0
static unsigned char tms380tr_chk_frame(struct net_device *dev, unsigned char *Addr);
+#endif
static void tms380tr_chk_outstanding_cmds(struct net_device *dev);
static void tms380tr_chk_src_addr(unsigned char *frame, unsigned char *hw_addr);
static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqType);
-static int tms380tr_close(struct net_device *dev);
+int tms380tr_close(struct net_device *dev);
static void tms380tr_cmd_status_irq(struct net_device *dev);
/* "D" */
static void tms380tr_disable_interrupts(struct net_device *dev);
@@ -176,20 +153,15 @@ static int tms380tr_init_adapter(struct net_device *dev);
static int tms380tr_init_card(struct net_device *dev);
static void tms380tr_init_ipb(struct net_local *tp);
static void tms380tr_init_net_local(struct net_device *dev);
-static void tms380tr_init_opb(struct net_local *tp);
-static void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static int tms380tr_isa_chk_card(struct net_device *dev, int ioaddr, struct cardinfo_table **outcard);
-static int tms380tr_isa_chk_ioaddr(int ioaddr);
+static void tms380tr_init_opb(struct net_device *dev);
+void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+/* "M" */
/* "O" */
-static int tms380tr_open(struct net_device *dev);
+int tms380tr_open(struct net_device *dev);
static void tms380tr_open_adapter(struct net_device *dev);
/* "P" */
-static int tms380tr_pci_chk_card(struct net_device *dev, struct cardinfo_table **outcard);
-int tms380tr_probe(struct net_device *dev);
-static int tms380tr_probe1(struct net_device *dev, int ioaddr);
/* "R" */
static void tms380tr_rcv_status_irq(struct net_device *dev);
-static void tms380tr_read_addr(struct net_device *dev, unsigned char *Address);
static int tms380tr_read_ptr(struct net_device *dev);
static void tms380tr_read_ram(struct net_device *dev, unsigned char *Data,
unsigned short Address, int Length);
@@ -199,6 +171,7 @@ static void tms380tr_ring_status_irq(struct net_device *dev);
/* "S" */
static int tms380tr_send_packet(struct sk_buff *skb, struct net_device *dev);
static void tms380tr_set_multicast_list(struct net_device *dev);
+static int tms380tr_set_mac_address(struct net_device *dev, void *addr);
/* "T" */
static void tms380tr_timer_chk(unsigned long data);
static void tms380tr_timer_end_wait(unsigned long data);
@@ -207,269 +180,61 @@ static void tms380tr_tx_status_irq(struct net_device *dev);
static void tms380tr_update_rcv_stats(struct net_local *tp,
unsigned char DataPtr[], unsigned int Length);
/* "W" */
-static void tms380tr_wait(unsigned long time);
+void tms380tr_wait(unsigned long time);
static void tms380tr_write_rpl_status(RPL *rpl, unsigned int Status);
static void tms380tr_write_tpl_status(TPL *tpl, unsigned int Status);
-/*
- * Check for a network adapter of this type, and return '0' if one exists.
- * If dev->base_addr == 0, probe all likely locations.
- * If dev->base_addr == 1, always return failure.
- */
-int __init tms380tr_probe(struct net_device *dev)
-{
- int i;
- int base_addr = dev ? dev->base_addr : 0;
+#define SIFREADB(reg) (((struct net_local *)dev->priv)->sifreadb(dev, reg))
+#define SIFWRITEB(val, reg) (((struct net_local *)dev->priv)->sifwriteb(dev, val, reg))
+#define SIFREADW(reg) (((struct net_local *)dev->priv)->sifreadw(dev, reg))
+#define SIFWRITEW(val, reg) (((struct net_local *)dev->priv)->sifwritew(dev, val, reg))
- if(base_addr > 0x1ff) /* Check a single specified location. */
- return (tms380tr_probe1(dev, base_addr));
- else if(base_addr != 0) /* Don't probe at all. */
- return (-ENXIO);
- /*
- * Let's check for pci adapters first
- */
- if (tms380tr_probe1(dev,0) == 0) /* Success */
- return 0 ;
- /*
- * No pci cards found, let's check for isa
- */
-
- for(i = 0; tms380tr_portlist[i]; i++)
- {
- int ioaddr = tms380tr_portlist[i];
- if(check_region(ioaddr, TMS380TR_IO_EXTENT)) /* Region already used */
- continue;
- if(!tms380tr_probe1(dev, ioaddr))
- return (0);
- }
-
- return (-ENODEV);
-}
-
-struct cardinfo_table * __init tms380tr_pci_getcardinfo(unsigned short vendor,
- unsigned short device)
+#if TMS380TR_DEBUG > 0
+static int madgemc_sifprobe(struct net_device *dev)
{
- int cur;
- for (cur = 1; cardinfo[cur].name != NULL; cur++) {
- if (cardinfo[cur].type == 2) /* PCI */
- {
- if ((cardinfo[cur].vendor_id == vendor) && (cardinfo[cur].device_id == device))
- return &cardinfo[cur];
- }
- }
+ unsigned char old, chk1, chk2;
- return NULL;
-}
-
-/*
- * Detect and setup the PCI SysKonnect TR cards in slot order.
- */
-static int __init tms380tr_pci_chk_card(struct net_device *dev,
- struct cardinfo_table **outcard)
-{
- struct pci_dev *pci_device = NULL ;
- struct cardinfo_table *card;
- int i;
-
- if(!pci_present())
- return (-1); /* No PCI present. */
-
- while ( (pci_device=pci_find_class(PCI_CLASS_NETWORK_TOKEN_RING<<8, pci_device))) {
-
- unsigned int pci_irq_line;
- unsigned int pci_ioaddr;
-
- /* Remove I/O space marker in bit 0. */
- pci_irq_line = pci_device->irq ;
- pci_ioaddr = pci_device->resource[0].start ;
-/* pci_ioaddr &= ~3; */
-
- /* Don't return from here, just continue on the card discovery loop - MLP */
- if (!(card = tms380tr_pci_getcardinfo(pci_device->vendor, pci_device->device)))
- continue ;
-
- if(check_region(pci_ioaddr, TMS380TR_IO_EXTENT))
- continue;
-
- request_region(pci_ioaddr, TMS380TR_IO_EXTENT, card->name);
- if(request_irq(pci_device->irq, tms380tr_interrupt, SA_SHIRQ,
- card->name, dev)) {
- release_region(pci_ioaddr, TMS380TR_IO_EXTENT) ;
- return (-ENODEV); /* continue; ?? */
- }
- /* At this point we have found a valid tms380tr PCI TR card. */
-
- pci_ioaddr &= ~3 ;
- dev->base_addr = pci_ioaddr;
- dev->irq = pci_irq_line;
- dev->dma = 0;
-
- dev->addr_len = 6;
- tms380tr_read_addr(dev, (unsigned char*)dev->dev_addr);
+ old = SIFREADB(SIFADR); /* Get the old SIFADR value */
+
+ chk1 = 0; /* Begin with check value 0 */
+ do {
+ madgemc_setregpage(dev, 0);
+ /* Write new SIFADR value */
+ SIFWRITEB(chk1, SIFADR);
+ chk2 = SIFREADB(SIFADR);
+ if (chk2 != chk1)
+ return -1;
- printk("%s: %s found at %#4x, IRQ %d, ring station ",
- dev->name, card->name, pci_ioaddr, dev->irq);
- printk("%2.2x", dev->dev_addr[0]);
- for (i = 1; i < 6; i++)
- printk(":%2.2x", dev->dev_addr[i]);
- printk(".\n");
-
- if (outcard)
- *outcard = card;
-
- return 0 ;
- }
-
- return (-1);
+ madgemc_setregpage(dev, 1);
+ /* Read, invert and write */
+ chk2 = SIFREADB(SIFADD);
+ if (chk2 != chk1)
+ return -1;
+
+ madgemc_setregpage(dev, 0);
+ chk2 ^= 0x0FE;
+ SIFWRITEB(chk2, SIFADR);
+
+ /* Read, invert and compare */
+ madgemc_setregpage(dev, 1);
+ chk2 = SIFREADB(SIFADD);
+ madgemc_setregpage(dev, 0);
+ chk2 ^= 0x0FE;
+
+ if(chk1 != chk2)
+ return (-1); /* No adapter */
+ chk1 -= 2;
+ } while(chk1 != 0); /* Repeat 128 times (all byte values) */
+
+ madgemc_setregpage(dev, 0); /* sanity */
+ /* Restore the SIFADR value */
+ SIFWRITEB(old, SIFADR);
+
+ return (0);
}
-
-/*
- * Detect and setup the ISA SysKonnect TR cards.
- */
-static int __init tms380tr_isa_chk_card(struct net_device *dev, int ioaddr,
- struct cardinfo_table **outcard)
-{
- int i, err;
- unsigned long flags;
- struct cardinfo_table *card = NULL;
-
- err = tms380tr_isa_chk_ioaddr(ioaddr);
- if(err < 0)
- return (-ENODEV);
-
- if(virt_to_bus((void*)((unsigned long)dev->priv+sizeof(struct net_local)))
- > ISA_MAX_ADDRESS)
- {
- printk("%s: Memory not accessible for DMA\n", dev->name);
- kfree(dev->priv);
- return (-EAGAIN);
- }
-
- /* FIXME */
- card = &cardinfo[1];
-
- /* Grab the region so that no one else tries to probe our ioports. */
- request_region(ioaddr, TMS380TR_IO_EXTENT, card->name);
- dev->base_addr = ioaddr;
-
- /* Autoselect IRQ and DMA if dev->irq == 0 */
- if(dev->irq == 0)
- {
- for(i = 0; tms380tr_irqlist[i] != 0; i++)
- {
- dev->irq = tms380tr_irqlist[i];
- err = request_irq(dev->irq, &tms380tr_interrupt, 0, card->name, dev);
- if(!err)
- break;
- }
-
- if(tms380tr_irqlist[i] == 0)
- {
- printk("%s: AutoSelect no IRQ available\n", dev->name);
- return (-EAGAIN);
- }
- }
- else
- {
- err = request_irq(dev->irq, &tms380tr_interrupt, 0, card->name, dev);
- if(err)
- {
- printk("%s: Selected IRQ not available\n", dev->name);
- return (-EAGAIN);
- }
- }
-
- /* Always allocate the DMA channel after IRQ and clean up on failure */
- if(dev->dma == 0)
- {
- for(i = 0; tms380tr_dmalist[i] != 0; i++)
- {
- dev->dma = tms380tr_dmalist[i];
- err = request_dma(dev->dma, card->name);
- if(!err)
- break;
- }
-
- if(dev->dma == 0)
- {
- printk("%s: AutoSelect no DMA available\n", dev->name);
- free_irq(dev->irq, NULL);
- return (-EAGAIN);
- }
- }
- else
- {
- err = request_dma(dev->dma, card->name);
- if(err)
- {
- printk("%s: Selected DMA not available\n", dev->name);
- free_irq(dev->irq, NULL);
- return (-EAGAIN);
- }
- }
-
- flags=claim_dma_lock();
- disable_dma(dev->dma);
- set_dma_mode(dev->dma, DMA_MODE_CASCADE);
- enable_dma(dev->dma);
- release_dma_lock(flags);
-
- printk("%s: %s found at %#4x, using IRQ %d and DMA %d.\n",
- dev->name, card->name, ioaddr, dev->irq, dev->dma);
-
- if (outcard)
- *outcard = card;
-
- return (0);
-}
-
-/*
- * Passing an ioaddr of 0 tells us to do a pci card search
- */
-
-static int __init tms380tr_probe1(struct net_device *dev, int ioaddr)
-{
- static unsigned version_printed = 0;
- struct net_local *tp;
- int err;
- struct cardinfo_table *card = NULL;
-
- if(tms380tr_debug && version_printed++ == 0)
- printk(KERN_INFO "%s", version);
-
-#ifndef MODULE
- dev = init_trdev(dev, 0);
- if(dev == NULL)
- return (-ENOMEM);
#endif
- if (ioaddr == 0) {
- err = tms380tr_pci_chk_card(dev, &card);
- } else {
- err = tms380tr_isa_chk_card(dev, ioaddr, &card);
- }
- if(err < 0)
- return (-ENODEV);
-
- /* Setup this devices private information structure */
- tp = (struct net_local *)kmalloc(sizeof(struct net_local), GFP_KERNEL | GFP_DMA);
- if(tp == NULL)
- return (-ENOMEM);
- memset(tp, 0, sizeof(struct net_local));
- init_waitqueue_head(&tp->wait_for_tok_int);
- tp->CardType = card;
-
- dev->priv = tp;
- dev->init = tms380tr_init_card;
- dev->open = tms380tr_open;
- dev->stop = tms380tr_close;
- dev->do_ioctl = NULL ;
- dev->hard_start_xmit = tms380tr_send_packet;
- dev->get_stats = tms380tr_get_stats;
- dev->set_multicast_list = &tms380tr_set_multicast_list;
- return (0);
-}
/* Dummy function */
static int __init tms380tr_init_card(struct net_device *dev)
@@ -481,42 +246,6 @@ static int __init tms380tr_init_card(struct net_device *dev)
}
/*
- * This function tests if an adapter is really installed at the
- * given I/O address. Return negative if no adapter at IO addr.
- */
-static int __init tms380tr_isa_chk_ioaddr(int ioaddr)
-{
- unsigned char old, chk1, chk2;
-
- old = inb(ioaddr + SIFADR); /* Get the old SIFADR value */
-
- chk1 = 0; /* Begin with check value 0 */
- do {
- /* Write new SIFADR value */
- outb(chk1, ioaddr + SIFADR);
-
- /* Read, invert and write */
- chk2 = inb(ioaddr + SIFADD);
- chk2 ^= 0x0FE;
- outb(chk2, ioaddr + SIFADR);
-
- /* Read, invert and compare */
- chk2 = inb(ioaddr + SIFADD);
- chk2 ^= 0x0FE;
-
- if(chk1 != chk2)
- return (-1); /* No adapter */
-
- chk1 -= 2;
- } while(chk1 != 0); /* Repeat 128 times (all byte values) */
-
- /* Restore the SIFADR value */
- outb(old, ioaddr + SIFADR);
-
- return (0);
-}
-
-/*
* Open/initialize the board. This is called sometime after
* booting when the 'ifconfig' program is run.
*
@@ -524,14 +253,14 @@ static int __init tms380tr_isa_chk_ioaddr(int ioaddr)
* registers that "should" only need to be set once at boot, so that
* there is non-reboot way to recover if something goes wrong.
*/
-static int tms380tr_open(struct net_device *dev)
+int tms380tr_open(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
int err;
/* Reset the hardware here. Don't forget to set the station address. */
err = tms380tr_chipset_init(dev);
- if(err)
+ if(err)
{
printk(KERN_INFO "%s: Chipset initialization error\n",
dev->name);
@@ -548,7 +277,6 @@ static int tms380tr_open(struct net_device *dev)
printk(KERN_INFO "%s: Adapter RAM size: %dK\n",
dev->name, tms380tr_read_ptr(dev));
-
tms380tr_enable_interrupts(dev);
tms380tr_open_adapter(dev);
@@ -566,8 +294,8 @@ static int tms380tr_open(struct net_device *dev)
/* If AdapterVirtOpenFlag is 1, the adapter is now open for use */
if(tp->AdapterVirtOpenFlag == 0)
{
- tms380tr_disable_interrupts(dev);
- return (-1);
+ tms380tr_disable_interrupts(dev);
+ return (-1);
}
dev->start = 1;
@@ -579,10 +307,6 @@ static int tms380tr_open(struct net_device *dev)
tp->timer.function = tms380tr_timer_chk;
tp->timer.data = (unsigned long)dev;
add_timer(&tp->timer);
-
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif
return (0);
}
@@ -610,47 +334,20 @@ static void tms380tr_timer_end_wait(unsigned long data)
static int tms380tr_chipset_init(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
- unsigned char PosReg, Tmp;
- int i, err;
+ int err;
tms380tr_init_ipb(tp);
- tms380tr_init_opb(tp);
+ tms380tr_init_opb(dev);
tms380tr_init_net_local(dev);
- /* Set pos register: selects irq and dma channel.
- * Only for ISA bus adapters.
- */
- if(dev->dma > 0)
- {
- PosReg = 0;
- for(i = 0; tms380tr_irqlist[i] != 0; i++)
- {
- if(tms380tr_irqlist[i] == dev->irq)
- break;
- }
-
- /* Choose default cycle time, 500 nsec */
- PosReg |= CYCLE_TIME << 2;
- PosReg |= i << 4;
- i = dev->dma - 5;
- PosReg |= i;
-
- if(tp->DataRate == SPEED_4)
- PosReg |= LINE_SPEED_BIT;
- else
- PosReg &= ~LINE_SPEED_BIT;
-
- outb(PosReg, dev->base_addr + POSREG);
- Tmp = inb(dev->base_addr + POSREG);
- if((Tmp & ~CYCLE_TIME) != (PosReg & ~CYCLE_TIME))
- printk(KERN_INFO "%s: POSREG error\n", dev->name);
- }
err = tms380tr_reset_adapter(dev);
if(err < 0)
return (-1);
+
err = tms380tr_bringup_diags(dev);
if(err < 0)
return (-1);
+
err = tms380tr_init_adapter(dev);
if(err < 0)
return (-1);
@@ -690,7 +387,7 @@ static void tms380tr_init_net_local(struct net_device *dev)
skb_queue_head_init(&tp->SendSkbQueue);
tp->QueueSkb = MAX_TX_QUEUE;
-
+
/* Create circular chain of transmit lists */
for (i = 0; i < TPL_NUM; i++)
{
@@ -713,7 +410,7 @@ static void tms380tr_init_net_local(struct net_device *dev)
tp->Rpl[i].NextRPLAddr = htonl((unsigned long) virt_to_bus(&tp->Rpl[(i+1) % RPL_NUM]));
tp->Rpl[i].Status = (RX_VALID | RX_START_FRAME | RX_END_FRAME | RX_FRAME_IRQ);
tp->Rpl[i].FrameSize = 0;
- tp->Rpl[i].FragList[0].DataCount = SWAPB(tp->MaxPacketSize);
+ tp->Rpl[i].FragList[0].DataCount = cpu_to_be16((unsigned short)tp->MaxPacketSize);
/* Alloc skb and point adapter to data area */
tp->Rpl[i].Skb = dev_alloc_skb(tp->MaxPacketSize);
@@ -731,7 +428,7 @@ static void tms380tr_init_net_local(struct net_device *dev)
skb_put(tp->Rpl[i].Skb, tp->MaxPacketSize);
/* data unreachable for DMA ? then use local buffer */
- if(tp->CardType->type == TMS_ISA && virt_to_bus(tp->Rpl[i].Skb->data) + tp->MaxPacketSize > ISA_MAX_ADDRESS)
+ if(tp->dmalimit && virt_to_bus(tp->Rpl[i].Skb->data) + tp->MaxPacketSize > tp->dmalimit)
{
tp->Rpl[i].SkbStat = SKB_DATA_COPY;
tp->Rpl[i].FragList[0].DataAddr = htonl(virt_to_bus(tp->LocalRxBuffers[i]));
@@ -780,28 +477,37 @@ static void tms380tr_init_ipb(struct net_local *tp)
/*
* Initializes the open parameter block.
*/
-static void tms380tr_init_opb(struct net_local *tp)
+static void tms380tr_init_opb(struct net_device *dev)
{
+ struct net_local *tp;
unsigned long Addr;
unsigned short RplSize = RPL_SIZE;
unsigned short TplSize = TPL_SIZE;
unsigned short BufferSize = BUFFER_SIZE;
+ int i;
+
+ tp = (struct net_local *)dev->priv;
tp->ocpl.OPENOptions = 0;
tp->ocpl.OPENOptions |= ENABLE_FULL_DUPLEX_SELECTION;
tp->ocpl.FullDuplex = 0;
tp->ocpl.FullDuplex |= OPEN_FULL_DUPLEX_OFF;
- /* Fixme: If mac address setable:
- * for (i=0; i<LENGTH_OF_ADDRESS; i++)
- * mac->Vam->ocpl.NodeAddr[i] = mac->CurrentAddress[i];
+ /*
+ * Set node address
+ *
+ * We go ahead and put it in the OPB even though on
+ * most of the generic adapters this isn't required.
+ * Its simpler this way. -- ASF
*/
+ for (i=0;i<6;i++)
+ tp->ocpl.NodeAddr[i] = ((unsigned char *)dev->dev_addr)[i];
tp->ocpl.GroupAddr = 0;
tp->ocpl.FunctAddr = 0;
- tp->ocpl.RxListSize = SWAPB(RplSize);
- tp->ocpl.TxListSize = SWAPB(TplSize);
- tp->ocpl.BufSize = SWAPB(BufferSize);
+ tp->ocpl.RxListSize = cpu_to_be16((unsigned short)RplSize);
+ tp->ocpl.TxListSize = cpu_to_be16((unsigned short)TplSize);
+ tp->ocpl.BufSize = cpu_to_be16((unsigned short)BufferSize);
tp->ocpl.Reserved = 0;
tp->ocpl.TXBufMin = TX_BUF_MIN;
tp->ocpl.TXBufMax = TX_BUF_MAX;
@@ -836,7 +542,7 @@ static void tms380tr_open_adapter(struct net_device *dev)
*/
static void tms380tr_disable_interrupts(struct net_device *dev)
{
- outb(0, dev->base_addr + SIFACL);
+ SIFWRITEB(0, SIFACL);
return;
}
@@ -847,7 +553,7 @@ static void tms380tr_disable_interrupts(struct net_device *dev)
*/
static void tms380tr_enable_interrupts(struct net_device *dev)
{
- outb(ACL_SINTEN, dev->base_addr + SIFACL);
+ SIFWRITEB(ACL_SINTEN, SIFACL);
return;
}
@@ -948,8 +654,7 @@ static void tms380tr_hardware_send_packet(struct net_device *dev, struct net_loc
tp->QueueSkb++;
/* Is buffer reachable for Busmaster-DMA? */
- if(tp->CardType->type == TMS_ISA && virt_to_bus((void*)(((long) skb->data) + skb->len))
- > ISA_MAX_ADDRESS)
+ if(tp->dmalimit && virt_to_bus((void*)(((long) skb->data) + skb->len)) > tp->dmalimit)
{
/* Copy frame to local buffer */
i = tp->TplFree->TPLIndex;
@@ -975,11 +680,11 @@ static void tms380tr_hardware_send_packet(struct net_device *dev, struct net_loc
/* Save the skb for delayed return of skb to system */
tpl->Skb = skb;
- tpl->FragList[0].DataCount = (unsigned short) SWAPB(length);
+ tpl->FragList[0].DataCount = cpu_to_be16((unsigned short)length);
tpl->FragList[0].DataAddr = htonl(virt_to_bus(newbuf));
/* Write the data length in the transmit list. */
- tpl->FrameSize = (unsigned short) SWAPB(length);
+ tpl->FrameSize = cpu_to_be16((unsigned short)length);
tpl->MData = newbuf;
/* Transmit the frame and set the status values. */
@@ -1057,48 +762,41 @@ static void tms380tr_timer_chk(unsigned long data)
/*
* The typical workload of the driver: Handle the network interface interrupts.
*/
-static void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = dev_id;
struct net_local *tp;
- int ioaddr;
unsigned short irq_type;
- if(dev == NULL)
- {
+ if(dev == NULL) {
printk("%s: irq %d for unknown device.\n", dev->name, irq);
return;
}
dev->interrupt = 1;
- ioaddr = dev->base_addr;
tp = (struct net_local *)dev->priv;
- irq_type = inw(ioaddr + SIFSTS);
+ irq_type = SIFREADW(SIFSTS);
- while(irq_type & STS_SYSTEM_IRQ)
- {
+ while(irq_type & STS_SYSTEM_IRQ) {
irq_type &= STS_IRQ_MASK;
- if(!tms380tr_chk_ssb(tp, irq_type))
- {
+ if(!tms380tr_chk_ssb(tp, irq_type)) {
printk(KERN_INFO "%s: DATA LATE occurred\n", dev->name);
break;
}
- switch(irq_type)
- {
- case STS_IRQ_RECEIVE_STATUS:
- tms380tr_reset_interrupt(dev);
- tms380tr_rcv_status_irq(dev);
- break;
+ switch(irq_type) {
+ case STS_IRQ_RECEIVE_STATUS:
+ tms380tr_reset_interrupt(dev);
+ tms380tr_rcv_status_irq(dev);
+ break;
- case STS_IRQ_TRANSMIT_STATUS:
- /* Check if TRANSMIT.HALT command is complete */
- if(tp->ssb.Parm[0] & COMMAND_COMPLETE)
- {
- tp->TransmitCommandActive = 0;
+ case STS_IRQ_TRANSMIT_STATUS:
+ /* Check if TRANSMIT.HALT command is complete */
+ if(tp->ssb.Parm[0] & COMMAND_COMPLETE) {
+ tp->TransmitCommandActive = 0;
tp->TransmitHaltScheduled = 0;
/* Issue a new transmit command. */
@@ -1109,40 +807,51 @@ static void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
tms380tr_tx_status_irq(dev);
break;
- case STS_IRQ_COMMAND_STATUS:
- /* The SSB contains status of last command
- * other than receive/transmit.
- */
- tms380tr_cmd_status_irq(dev);
- break;
-
- case STS_IRQ_SCB_CLEAR:
- /* The SCB is free for another command. */
- tp->ScbInUse = 0;
- tms380tr_chk_outstanding_cmds(dev);
- break;
-
- case STS_IRQ_RING_STATUS:
- tms380tr_ring_status_irq(dev);
- break;
+ case STS_IRQ_COMMAND_STATUS:
+ /* The SSB contains status of last command
+ * other than receive/transmit.
+ */
+ tms380tr_cmd_status_irq(dev);
+ break;
+
+ case STS_IRQ_SCB_CLEAR:
+ /* The SCB is free for another command. */
+ tp->ScbInUse = 0;
+ tms380tr_chk_outstanding_cmds(dev);
+ break;
+
+ case STS_IRQ_RING_STATUS:
+ tms380tr_ring_status_irq(dev);
+ break;
- case STS_IRQ_ADAPTER_CHECK:
- tms380tr_chk_irq(dev);
- break;
+ case STS_IRQ_ADAPTER_CHECK:
+ tms380tr_chk_irq(dev);
+ break;
- default:
- printk(KERN_INFO "Unknown Token Ring IRQ\n");
- break;
+ case STS_IRQ_LLC_STATUS:
+ printk(KERN_DEBUG "tms380tr: unexpected LLC status IRQ\n");
+ break;
+
+ case STS_IRQ_TIMER:
+ printk(KERN_DEBUG "tms380tr: unexpected Timer IRQ\n");
+ break;
+
+ case STS_IRQ_RECEIVE_PENDING:
+ printk(KERN_DEBUG "tms380tr: unexpected Receive Pending IRQ\n");
+ break;
+
+ default:
+ printk(KERN_INFO "Unknown Token Ring IRQ (0x%04x)\n", irq_type);
+ break;
}
/* Reset system interrupt if not already done. */
if(irq_type != STS_IRQ_TRANSMIT_STATUS
- && irq_type != STS_IRQ_RECEIVE_STATUS)
- {
+ && irq_type != STS_IRQ_RECEIVE_STATUS) {
tms380tr_reset_interrupt(dev);
}
- irq_type = inw(ioaddr + SIFSTS);
+ irq_type = SIFREADW(SIFSTS);
}
dev->interrupt = 0;
@@ -1436,7 +1145,7 @@ static void tms380tr_cmd_status_irq(struct net_device *dev)
/*
* The inverse routine to tms380tr_open().
*/
-static int tms380tr_close(struct net_device *dev)
+int tms380tr_close(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
dev->tbusy = 1;
@@ -1469,13 +1178,9 @@ static int tms380tr_close(struct net_device *dev)
release_dma_lock(flags);
}
- outw(0xFF00, dev->base_addr + SIFCMD);
- if(dev->dma > 0)
- outb(0xff, dev->base_addr + POSREG);
-
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
+ SIFWRITEW(0xFF00, SIFCMD);
+ if(dev->dma > 0) /* what the? */
+ SIFWRITEB(0xff, POSREG);
tms380tr_cancel_tx_queue(tp);
@@ -1549,7 +1254,7 @@ static void tms380tr_set_multicast_list(struct net_device *dev)
/*
* Wait for some time (microseconds)
*/
-static void tms380tr_wait(unsigned long time)
+void tms380tr_wait(unsigned long time)
{
#if 0
long tmp;
@@ -1570,7 +1275,6 @@ static void tms380tr_wait(unsigned long time)
*/
static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue)
{
- int ioaddr = dev->base_addr;
unsigned short cmd;
unsigned short SifStsValue;
unsigned long loop_counter;
@@ -1579,9 +1283,9 @@ static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue
cmd = (unsigned short)WriteValue;
loop_counter = 0,5 * 800000;
do {
- SifStsValue = inw(ioaddr + SIFSTS);
+ SifStsValue = SIFREADW(SIFSTS);
} while((SifStsValue & CMD_INTERRUPT_ADAPTER) && loop_counter--);
- outw(cmd, ioaddr + SIFCMD);
+ SIFWRITEW(cmd, SIFCMD);
return;
}
@@ -1595,22 +1299,19 @@ static int tms380tr_reset_adapter(struct net_device *dev)
struct net_local *tp = (struct net_local *)dev->priv;
unsigned short *fw_ptr = (unsigned short *)&tms380tr_code;
unsigned short count, c;
- int ioaddr = dev->base_addr;
/* Hardware adapter reset */
- outw(ACL_ARESET, ioaddr + SIFACL);
+ SIFWRITEW(ACL_ARESET, SIFACL);
tms380tr_wait(40);
- c = inw(ioaddr + SIFACL);
+ c = SIFREADW(SIFACL);
tms380tr_wait(20);
if(dev->dma == 0) /* For PCI adapters */
{
- c &= ~(ACL_SPEED4 | ACL_SPEED16); /* Clear bits */
- if(tp->DataRate == SPEED_4)
- c |= ACL_SPEED4; /* Set 4Mbps */
- else
- c |= ACL_SPEED16; /* Set 16Mbps */
+ c &= ~(ACL_NSELOUT0 | ACL_NSELOUT1); /* Clear bits */
+ if(tp->setnselout)
+ c |= (*tp->setnselout)(dev);
}
/* In case a command is pending - forget it */
@@ -1618,18 +1319,20 @@ static int tms380tr_reset_adapter(struct net_device *dev)
c &= ~ACL_ARESET; /* Clear adapter reset bit */
c |= ACL_CPHALT; /* Halt adapter CPU, allow download */
+ c |= ACL_BOOT;
+ c |= ACL_SINTEN;
c &= ~ACL_PSDMAEN; /* Clear pseudo dma bit */
- outw(c, ioaddr + SIFACL);
+ SIFWRITEW(c, SIFACL);
tms380tr_wait(40);
/* Download firmware via DIO interface: */
do {
/* Download first address part */
- outw(*fw_ptr, ioaddr + SIFADX);
+ SIFWRITEW(*fw_ptr, SIFADX);
fw_ptr++;
/* Download second address part */
- outw(*fw_ptr, ioaddr + SIFADD);
+ SIFWRITEW(*fw_ptr, SIFADD);
fw_ptr++;
if((count = *fw_ptr) != 0) /* Load loop counter */
@@ -1637,17 +1340,17 @@ static int tms380tr_reset_adapter(struct net_device *dev)
fw_ptr++; /* Download block data */
for(; count > 0; count--)
{
- outw(*fw_ptr, ioaddr + SIFINC);
+ SIFWRITEW(*fw_ptr, SIFINC);
fw_ptr++;
}
}
else /* Stop, if last block downloaded */
{
- c = inw(ioaddr + SIFACL);
+ c = SIFREADW(SIFACL);
c &= (~ACL_CPHALT | ACL_SINTEN);
/* Clear CPHALT and start BUD */
- outw(c, ioaddr + SIFACL);
+ SIFWRITEW(c, SIFACL);
return (1);
}
} while(count == 0);
@@ -1663,7 +1366,6 @@ static int tms380tr_bringup_diags(struct net_device *dev)
{
int loop_cnt, retry_cnt;
unsigned short Status;
- int ioaddr = dev->base_addr;
tms380tr_wait(HALF_SECOND);
tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET);
@@ -1679,7 +1381,7 @@ static int tms380tr_bringup_diags(struct net_device *dev)
do { /* Inspect BUD results */
loop_cnt--;
tms380tr_wait(HALF_SECOND);
- Status = inw(ioaddr + SIFSTS);
+ Status = SIFREADW(SIFSTS);
Status &= STS_MASK;
if(tms380tr_debug > 3)
@@ -1701,11 +1403,16 @@ static int tms380tr_bringup_diags(struct net_device *dev)
}
} while(retry_cnt > 0);
- Status = inw(ioaddr + SIFSTS);
- Status &= STS_ERROR_MASK; /* Hardware error occurred! */
-
- printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n",
- dev->name, Status);
+ Status = SIFREADW(SIFSTS);
+
+ /* Hardware error occurred! */
+ Status &= 0x001f;
+ if (Status & 0x0010)
+ printk(KERN_INFO "%s: BUD Error: Timeout\n", dev->name);
+ else if ((Status & 0x000f) > 6)
+ printk(KERN_INFO "%s: BUD Error: Illegal Failure\n", dev->name);
+ else
+ printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n", dev->name, Status & 0x000f);
return (-1);
}
@@ -1727,7 +1434,6 @@ static int tms380tr_init_adapter(struct net_device *dev)
unsigned char *sb_ptr = (unsigned char *) &tp->ssb;
unsigned short Status;
int i, loop_cnt, retry_cnt;
- int ioaddr = dev->base_addr;
/* Normalize: byte order low/high, word order high/low! (only IPB!) */
tp->ipb.SCB_Addr = SWAPW(virt_to_bus(&tp->scb));
@@ -1740,14 +1446,14 @@ static int tms380tr_init_adapter(struct net_device *dev)
retry_cnt--;
/* Transfer initialization block */
- outw(0x0001, ioaddr + SIFADX);
+ SIFWRITEW(0x0001, SIFADX);
/* To address 0001:0A00 of adapter RAM */
- outw(0x0A00, ioaddr + SIFADD);
+ SIFWRITEW(0x0A00, SIFADD);
/* Write 11 words to adapter RAM */
for(i = 0; i < 11; i++)
- outw(ipb_ptr[i], ioaddr + SIFINC);
+ SIFWRITEW(ipb_ptr[i], SIFINC);
/* Execute SCB adapter command */
tms380tr_exec_sifcmd(dev, CMD_EXECUTE);
@@ -1761,7 +1467,7 @@ static int tms380tr_init_adapter(struct net_device *dev)
tms380tr_wait(HALF_SECOND);
/* Mask interesting status bits */
- Status = inw(ioaddr + SIFSTS);
+ Status = SIFREADW(SIFSTS);
Status &= STS_MASK;
} while(((Status &(STS_INITIALIZE | STS_ERROR | STS_TEST)) != 0)
&& ((Status & STS_ERROR) == 0) && (loop_cnt != 0));
@@ -1792,7 +1498,7 @@ static int tms380tr_init_adapter(struct net_device *dev)
if((Status & STS_ERROR) != 0)
{
/* Initialization error occurred */
- Status = inw(ioaddr + SIFSTS);
+ Status = SIFREADW(SIFSTS);
Status &= STS_ERROR_MASK;
/* ShowInitialisationErrorCode(Status); */
return (-1); /* Unrecoverable error */
@@ -1820,7 +1526,6 @@ static void tms380tr_chk_outstanding_cmds(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
unsigned long Addr = 0;
- unsigned char i = 0;
if(tp->CMDqueue == 0)
return; /* No command execution */
@@ -1839,14 +1544,6 @@ static void tms380tr_chk_outstanding_cmds(struct net_device *dev)
/* Execute OPEN command */
tp->CMDqueue ^= OC_OPEN;
- /* Copy the 18 bytes of the product ID */
- while((tp->CardType->name[i] != '\0')
- && (i < PROD_ID_SIZE))
- {
- tp->ProductID[i] = tp->CardType->name[i];
- i++;
- }
-
Addr = htonl(virt_to_bus(&tp->ocpl));
tp->scb.Parm[0] = LOWORD(Addr);
tp->scb.Parm[1] = HIWORD(Addr);
@@ -2001,7 +1698,7 @@ static void tms380tr_ring_status_irq(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
- tp->CurrentRingStatus = SWAPB(tp->ssb.Parm[0]);
+ tp->CurrentRingStatus = be16_to_cpu((unsigned short)tp->ssb.Parm[0]);
/* First: fill up statistics */
if(tp->ssb.Parm[0] & SIGNAL_LOSS)
@@ -2071,19 +1768,18 @@ static void tms380tr_chk_irq(struct net_device *dev)
{
int i;
unsigned short AdapterCheckBlock[4];
- unsigned short ioaddr = dev->base_addr;
struct net_local *tp = (struct net_local *)dev->priv;
tp->AdapterOpenFlag = 0; /* Adapter closed now */
/* Page number of adapter memory */
- outw(0x0001, ioaddr + SIFADX);
+ SIFWRITEW(0x0001, SIFADX);
/* Address offset */
- outw(CHECKADDR, ioaddr + SIFADR);
+ SIFWRITEW(CHECKADDR, SIFADR);
/* Reading 8 byte adapter check block. */
for(i = 0; i < 4; i++)
- AdapterCheckBlock[i] = inw(ioaddr + SIFINC);
+ AdapterCheckBlock[i] = SIFREADW(SIFINC);
if(tms380tr_debug > 3)
{
@@ -2234,8 +1930,8 @@ static int tms380tr_read_ptr(struct net_device *dev)
tms380tr_read_ram(dev, (unsigned char *)&tp->intptrs.BurnedInAddrPtr,
ADAPTER_INT_PTRS, 16);
tms380tr_read_ram(dev, (unsigned char *)&adapterram,
- (unsigned short)SWAPB(tp->intptrs.AdapterRAMPtr), 2);
- return SWAPB(adapterram);
+ cpu_to_be16((unsigned short)tp->intptrs.AdapterRAMPtr), 2);
+ return be16_to_cpu(adapterram);
}
/*
@@ -2246,22 +1942,21 @@ static void tms380tr_read_ram(struct net_device *dev, unsigned char *Data,
{
int i;
unsigned short old_sifadx, old_sifadr, InWord;
- unsigned short ioaddr = dev->base_addr;
/* Save the current values */
- old_sifadx = inw(ioaddr + SIFADX);
- old_sifadr = inw(ioaddr + SIFADR);
+ old_sifadx = SIFREADW(SIFADX);
+ old_sifadr = SIFREADW(SIFADR);
/* Page number of adapter memory */
- outw(0x0001, ioaddr + SIFADX);
+ SIFWRITEW(0x0001, SIFADX);
/* Address offset in adapter RAM */
- outw(Address, ioaddr + SIFADR);
+ SIFWRITEW(Address, SIFADR);
/* Copy len byte from adapter memory to system data area. */
i = 0;
for(;;)
{
- InWord = inw(ioaddr + SIFINC);
+ InWord = SIFREADW(SIFINC);
*(Data + i) = HIBYTE(InWord); /* Write first byte */
if(++i == Length) /* All is done break */
@@ -2273,30 +1968,8 @@ static void tms380tr_read_ram(struct net_device *dev, unsigned char *Data,
}
/* Restore original values */
- outw(old_sifadx, ioaddr + SIFADX);
- outw(old_sifadr, ioaddr + SIFADR);
-
- return;
-}
-
-/*
- * Reads MAC address from adapter ROM.
- */
-static void tms380tr_read_addr(struct net_device *dev, unsigned char *Address)
-{
- int i, In;
- unsigned short ioaddr = dev->base_addr;
-
- /* Address: 0000:0000 */
- outw(0, ioaddr + SIFADX);
- outw(0, ioaddr + SIFADR);
-
- /* Read six byte MAC address data */
- for(i = 0; i < 6; i++)
- {
- In = inw(ioaddr + SIFINC);
- *(Address + i) = (unsigned char)(In >> 8);
- }
+ SIFWRITEW(old_sifadx, SIFADX);
+ SIFWRITEW(old_sifadr, SIFADR);
return;
}
@@ -2447,7 +2120,7 @@ static void tms380tr_rcv_status_irq(struct net_device *dev)
/* Get the frame size (Byte swap for Intel).
* Do this early (see workaround comment below)
*/
- Length = (unsigned short)SWAPB(rpl->FrameSize);
+ Length = be16_to_cpu((unsigned short)rpl->FrameSize);
/* Check if the Frame_Start, Frame_End and
* Frame_Complete bits are set.
@@ -2463,15 +2136,16 @@ static void tms380tr_rcv_status_irq(struct net_device *dev)
* Length2 is there because there have also been
* cases where the FrameSize was partially written
*/
- Length2 = (unsigned short)SWAPB(rpl->FrameSize);
+ Length2 = be16_to_cpu((unsigned short)rpl->FrameSize);
if(Length == 0 || Length != Length2)
{
tp->RplHead = SaveHead;
break; /* Return to tms380tr_interrupt */
}
-#if 0 /* This might happen for multicast or broadcast packets.
- The upper layers are expected to handle this, not here */
+#if 0 /* This might happen for multicast or broadcast packets.
+ The upper layers are expected to handle this, not here */
+
/* Drop frames sent by myself */
if(tms380tr_chk_frame(dev, rpl->MData))
{
@@ -2552,8 +2226,7 @@ static void tms380tr_rcv_status_irq(struct net_device *dev)
skb_put(rpl->Skb, tp->MaxPacketSize);
/* Data unreachable for DMA ? then use local buffer */
- if(tp->CardType->type == TMS_ISA && virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize
- > ISA_MAX_ADDRESS)
+ if(tp->dmalimit && virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize > tp->dmalimit)
{
rpl->SkbStat = SKB_DATA_COPY;
rpl->FragList[0].DataAddr = htonl(virt_to_bus(tp->LocalRxBuffers[rpl->RPLIndex]));
@@ -2568,7 +2241,7 @@ static void tms380tr_rcv_status_irq(struct net_device *dev)
}
}
- rpl->FragList[0].DataCount = SWAPB(tp->MaxPacketSize);
+ rpl->FragList[0].DataCount = cpu_to_be16((unsigned short)tp->MaxPacketSize);
rpl->FrameSize = 0;
/* Pass the last RPL back to the adapter */
@@ -2619,6 +2292,7 @@ static void tms380tr_update_rcv_stats(struct net_local *tp, unsigned char DataPt
return;
}
+#if 0
/*
* Check if it is a frame of myself. Compare source address with my current
* address in reverse direction, and mask out the TR_RII.
@@ -2639,6 +2313,20 @@ static unsigned char tms380tr_chk_frame(struct net_device *dev, unsigned char *A
return (1); /* It is my frame. */
}
+#endif
+
+static int tms380tr_set_mac_address(struct net_device *dev, void *addr)
+{
+ struct net_local *tp = (struct net_local *)dev->priv;
+ struct sockaddr *saddr = addr;
+
+ if (tp->AdapterOpenFlag || tp->AdapterVirtOpenFlag) {
+ printk(KERN_WARNING "%s: Cannot set MAC/LAA address while card is open\n", dev->name);
+ return -EIO;
+ }
+ memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len);
+ return 0;
+}
#if TMS380TR_DEBUG > 0
/*
@@ -2651,80 +2339,73 @@ static void tms380tr_dump(unsigned char *Data, int length)
for (i = 0, j = 0; i < length / 8; i++, j += 8)
{
printk(KERN_DEBUG "%02x %02x %02x %02x %02x %02x %02x %02x\n",
- Data[j+0],Data[j+1],Data[j+2],Data[j+3],
- Data[j+4],Data[j+5],Data[j+6],Data[j+7]);
+ Data[j+0],Data[j+1],Data[j+2],Data[j+3],
+ Data[j+4],Data[j+5],Data[j+6],Data[j+7]);
}
return;
}
#endif
+int tmsdev_init(struct net_device *dev)
+{
+ if (dev->priv == NULL)
+ {
+ struct net_local *tms_local;
+
+ dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL | GFP_DMA);
+ if (dev->priv == NULL)
+ return -ENOMEM;
+ memset(dev->priv, 0, sizeof(struct net_local));
+ tms_local = (struct net_local *)dev->priv;
+ init_waitqueue_head(&tms_local->wait_for_tok_int);
+ }
+
+ /* These can be overridden by the card driver if needed */
+ dev->init = tms380tr_init_card;
+ dev->open = tms380tr_open;
+ dev->stop = tms380tr_close;
+ dev->do_ioctl = NULL;
+ dev->hard_start_xmit = tms380tr_send_packet;
+ dev->get_stats = tms380tr_get_stats;
+ dev->set_multicast_list = &tms380tr_set_multicast_list;
+ dev->set_mac_address = tms380tr_set_mac_address;
+
+ return 0;
+}
+
#ifdef MODULE
-static struct net_device* dev_tms380tr[TMS380TR_MAX_ADAPTERS];
-static int io[TMS380TR_MAX_ADAPTERS] = { 0, 0 };
-static int irq[TMS380TR_MAX_ADAPTERS] = { 0, 0 };
-static int mem[TMS380TR_MAX_ADAPTERS] = { 0, 0 };
+EXPORT_SYMBOL(tms380tr_open);
+EXPORT_SYMBOL(tms380tr_close);
+EXPORT_SYMBOL(tms380tr_interrupt);
+EXPORT_SYMBOL(tmsdev_init);
+EXPORT_SYMBOL(tms380tr_wait);
-MODULE_PARM(io, "1-" __MODULE_STRING(TMS380TR_MAX_ADAPTERS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(TMS380TR_MAX_ADAPTERS) "i");
-MODULE_PARM(mem, "1-" __MODULE_STRING(TMS380TR_MAX_ADAPTERS) "i");
+struct module *TMS380_module = NULL;
int init_module(void)
{
- int i;
-
- for(i = 0; i < TMS380TR_MAX_ADAPTERS; i++)
- {
- irq[i] = 0;
- mem[i] = 0;
- dev_tms380tr[i] = NULL;
- dev_tms380tr[i] = init_trdev(dev_tms380tr[i], 0);
- if(dev_tms380tr[i] == NULL)
- return (-ENOMEM);
-
- dev_tms380tr[i]->base_addr = io[i];
- dev_tms380tr[i]->irq = irq[i];
- dev_tms380tr[i]->mem_start = mem[i];
- dev_tms380tr[i]->init = &tms380tr_probe;
-
- if(register_trdev(dev_tms380tr[i]) != 0)
- {
- kfree_s(dev_tms380tr[i], sizeof(struct net_device));
- dev_tms380tr[i] = NULL;
- if(i == 0)
- {
- printk("tms380tr: register_trdev() returned non-zero.\n");
- return (-EIO);
- }
- else
- return (0);
- }
-
- }
-
- return (0);
+ printk("%s", version);
+
+ TMS380_module = &__this_module;
+ return 0;
}
void cleanup_module(void)
{
- int i;
-
- for(i = 0; i < TMS380TR_MAX_ADAPTERS; i++)
- {
- if(dev_tms380tr[i])
- {
- unregister_trdev(dev_tms380tr[i]);
- release_region(dev_tms380tr[i]->base_addr, TMS380TR_IO_EXTENT);
- if(dev_tms380tr[i]->irq)
- free_irq(dev_tms380tr[i]->irq, dev_tms380tr[i]);
- if(dev_tms380tr[i]->dma > 0)
- free_dma(dev_tms380tr[i]->dma);
- if(dev_tms380tr[i]->priv)
- kfree_s(dev_tms380tr[i]->priv, sizeof(struct net_local));
- kfree_s(dev_tms380tr[i], sizeof(struct net_device));
- dev_tms380tr[i] = NULL;
- }
- }
+ TMS380_module = NULL;
}
-#endif /* MODULE */
+#endif
+
+
+/*
+ * Local variables:
+ * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tms380tr.c"
+ * alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tms380tr.c"
+ * c-set-style "K&R"
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff --git a/drivers/net/tokenring/tms380tr.h b/drivers/net/tokenring/tms380tr.h
index 7896be0a0..f387de814 100644
--- a/drivers/net/tokenring/tms380tr.h
+++ b/drivers/net/tokenring/tms380tr.h
@@ -1,7 +1,9 @@
-/* tms380tr.h: TI TMS380 Token Ring driver for Linux
+/*
+ * tms380tr.h: TI TMS380 Token Ring driver for Linux
*
* Authors:
* - Christoph Goos <cgoos@syskonnect.de>
+ * - Adam Fritzler <mid@auk.cx>
*/
#ifndef __LINUX_TMS380TR_H
@@ -9,6 +11,13 @@
#ifdef __KERNEL__
+/* module prototypes */
+int tms380tr_open(struct net_device *dev);
+int tms380tr_close(struct net_device *dev);
+void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+int tmsdev_init(struct net_device *dev);
+void tms380tr_wait(unsigned long time);
+
#define TMS380TR_MAX_ADAPTERS 7
#define SEND_TIMEOUT 10*HZ
@@ -30,9 +39,6 @@
/* -------------------------------------------------------------- */
/*------------------------------------------------------------------*/
-/* Swap bytes of a word. */
-#define SWAPB(x) (((unsigned short)((x) << 8)) | ((unsigned short)((x) >> 8)))
-
/* Swap words of a long. */
#define SWAPW(x) (((x) << 16) | ((x) >> 16))
@@ -51,24 +57,34 @@
/* Token ring adapter I/O addresses for normal mode. */
-#define SIFDAT 0L /* SIF/DMA data. */
-#define SIFINC 2L /* IO Word data with auto increment. */
-#define SIFINH 3L /* IO Byte data with auto increment. */
-#define SIFADR 4L /* SIF/DMA Address. */
-#define SIFCMD 6L /* SIF Command. */
-#define SIFSTS 6L /* SIF Status. */
-#define SIFACL 8L /* SIF Adapter Control Register. */
-#define SIFADD 10L /* SIF/DMA Address. */
-#define SIFADX 12L
-#define DMALEN 14L /* SIF DMA length. */
-#define POSREG 16L /* Adapter Program Option Select (POS)
+
+/*
+ * The SIF registers. Common to all adapters.
+ */
+/* Basic SIF (SRSX = 0) */
+#define SIFDAT 0x00 /* SIF/DMA data. */
+#define SIFINC 0x02 /* IO Word data with auto increment. */
+#define SIFINH 0x03 /* IO Byte data with auto increment. */
+#define SIFADR 0x04 /* SIF/DMA Address. */
+#define SIFCMD 0x06 /* SIF Command. */
+#define SIFSTS 0x06 /* SIF Status. */
+
+/* "Extended" SIF (SRSX = 1) */
+#define SIFACL 0x08 /* SIF Adapter Control Register. */
+#define SIFADD 0x0a /* SIF/DMA Address. -- 0x0a */
+#define SIFADX 0x0c /* 0x0c */
+#define DMALEN 0x0e /* SIF DMA length. -- 0x0e */
+
+/*
+ * POS Registers. Only for ISA Adapters.
+ */
+#define POSREG 0x10 /* Adapter Program Option Select (POS)
* Register: base IO address + 16 byte.
*/
#define POSREG_2 24L /* only for TR4/16+ adapter
- * base IO address + 24 byte.
+ * base IO address + 24 byte. -- 0x18
*/
-
/* SIFCMD command codes (high-low) */
#define CMD_INTERRUPT_ADAPTER 0x8000 /* Cause internal adapter interrupt */
#define CMD_ADAPTER_RESET 0x4000 /* Hardware reset of adapter */
@@ -118,8 +134,13 @@
* (1/0): can be written if ACL_ARESET
* is zero.
*/
-#define ACL_SPEED4 0x0003
-#define ACL_SPEED16 0x0001
+#define ACL_PEN 0x0004
+
+#define ACL_NSELOUT0 0x0002
+#define ACL_NSELOUT1 0x0001 /* NSELOUTx have a card-specific
+ * meaning for setting ring speed.
+ */
+
#define PS_DMA_MASK (ACL_SWHRQ | ACL_PSDMAEN)
@@ -145,69 +166,72 @@
/* Interrupt Codes (only MAC IRQs) */
-#define STS_IRQ_ADAPTER_CHECK 0x0000 /* unrecoverable hardware or
+#define STS_IRQ_ADAPTER_CHECK 0x0000 /* unrecoverable hardware or
* software error.
*/
-#define STS_IRQ_RING_STATUS 0x0004 /* SSB is updated with ring status. */
-#define STS_IRQ_SCB_CLEAR 0x0006 /* SCB clear, following an
+#define STS_IRQ_RING_STATUS 0x0004 /* SSB is updated with ring status. */
+#define STS_IRQ_LLC_STATUS 0x0005 /* Not used in MAC-only microcode */
+#define STS_IRQ_SCB_CLEAR 0x0006 /* SCB clear, following an
* SCB_REQUEST IRQ.
*/
-#define STS_IRQ_COMMAND_STATUS 0x0008 /* SSB is updated with command
+#define STS_IRQ_TIMER 0x0007 /* Not normally used in MAC ucode */
+#define STS_IRQ_COMMAND_STATUS 0x0008 /* SSB is updated with command
* status.
*/
-#define STS_IRQ_RECEIVE_STATUS 0x000A /* SSB is updated with receive
+#define STS_IRQ_RECEIVE_STATUS 0x000A /* SSB is updated with receive
* status.
*/
-#define STS_IRQ_TRANSMIT_STATUS 0x000C /* SSB is updated with transmit
+#define STS_IRQ_TRANSMIT_STATUS 0x000C /* SSB is updated with transmit
* status
*/
-#define STS_IRQ_MASK 0x000F /* = STS_ERROR_MASK. */
+#define STS_IRQ_RECEIVE_PENDING 0x000E /* Not used in MAC-only microcode */
+#define STS_IRQ_MASK 0x000F /* = STS_ERROR_MASK. */
/* TRANSMIT_STATUS completion code: (SSB.Parm[0]) */
-#define COMMAND_COMPLETE 0x0080 /* TRANSMIT command completed
+#define COMMAND_COMPLETE 0x0080 /* TRANSMIT command completed
* (avoid this!) issue another transmit
* to send additional frames.
*/
-#define FRAME_COMPLETE 0x0040 /* Frame has been transmitted;
+#define FRAME_COMPLETE 0x0040 /* Frame has been transmitted;
* INTERRUPT_FRAME bit was set in the
* CSTAT request; indication of possibly
* more than one frame transmissions!
* SSB.Parm[0-1]: 32 bit pointer to
* TPL of last frame.
*/
-#define LIST_ERROR 0x0020 /* Error in one of the TPLs that
+#define LIST_ERROR 0x0020 /* Error in one of the TPLs that
* compose the frame; TRANSMIT
- * terminated; Parm[1-2]: 32 bit pointer
+ * terminated; Parm[1-2]: 32bit pointer
* to TPL which starts the error
* frame; error details in bits 8-13.
* (14?)
*/
-#define FRAME_SIZE_ERROR 0x8000 /* FRAME_SIZE does not equal the sum of
+#define FRAME_SIZE_ERROR 0x8000 /* FRAME_SIZE does not equal the sum of
* the valid DATA_COUNT fields;
* FRAME_SIZE less than header plus
* information field. (15 bytes +
* routing field) Or if FRAME_SIZE
* was specified as zero in one list.
*/
-#define TX_THRESHOLD 0x4000 /* FRAME_SIZE greater than (BUFFER_SIZE
+#define TX_THRESHOLD 0x4000 /* FRAME_SIZE greater than (BUFFER_SIZE
* - 9) * TX_BUF_MAX.
*/
-#define ODD_ADDRESS 0x2000 /* Odd forward pointer value is
+#define ODD_ADDRESS 0x2000 /* Odd forward pointer value is
* read on a list without END_FRAME
* indication.
*/
-#define FRAME_ERROR 0x1000 /* START_FRAME bit is (not) anticipated,
+#define FRAME_ERROR 0x1000 /* START_FRAME bit (not) anticipated,
* but (not) set.
*/
-#define ACCESS_PRIORITY_ERROR 0x0800 /* Access priority requested has not
+#define ACCESS_PRIORITY_ERROR 0x0800 /* Access priority requested has not
* been allowed.
*/
-#define UNENABLED_MAC_FRAME 0x0400 /* MAC frame has source class of zero
+#define UNENABLED_MAC_FRAME 0x0400 /* MAC frame has source class of zero
* or MAC frame PCF ATTN field is
* greater than one.
*/
-#define ILLEGAL_FRAME_FORMAT 0x0200 /* Bit 0 or FC field was set to one. */
+#define ILLEGAL_FRAME_FORMAT 0x0200 /* Bit 0 or FC field was set to one. */
/*
@@ -222,98 +246,98 @@
*
* The following defines the command code bits and the command queue:
*/
-#define OC_OPEN 0x0001 /* OPEN command */
-#define OC_TRANSMIT 0x0002 /* TRANSMIT command */
-#define OC_TRANSMIT_HALT 0x0004 /* TRANSMIT_HALT command */
-#define OC_RECEIVE 0x0008 /* RECEIVE command */
-#define OC_CLOSE 0x0010 /* CLOSE command */
-#define OC_SET_GROUP_ADDR 0x0020 /* SET_GROUP_ADDR command */
-#define OC_SET_FUNCT_ADDR 0x0040 /* SET_FUNCT_ADDR command */
-#define OC_READ_ERROR_LOG 0x0080 /* READ_ERROR_LOG command */
-#define OC_READ_ADAPTER 0x0100 /* READ_ADAPTER command */
-#define OC_MODIFY_OPEN_PARMS 0x0400 /* MODIFY_OPEN_PARMS command */
-#define OC_RESTORE_OPEN_PARMS 0x0800 /* RESTORE_OPEN_PARMS command */
-#define OC_SET_FIRST_16_GROUP 0x1000 /* SET_FIRST_16_GROUP command */
-#define OC_SET_BRIDGE_PARMS 0x2000 /* SET_BRIDGE_PARMS command */
-#define OC_CONFIG_BRIDGE_PARMS 0x4000 /* CONFIG_BRIDGE_PARMS command */
-
-#define OPEN 0x0300 /* C: open command. S: completion. */
-#define TRANSMIT 0x0400 /* C: transmit command. S: completion
+#define OC_OPEN 0x0001 /* OPEN command */
+#define OC_TRANSMIT 0x0002 /* TRANSMIT command */
+#define OC_TRANSMIT_HALT 0x0004 /* TRANSMIT_HALT command */
+#define OC_RECEIVE 0x0008 /* RECEIVE command */
+#define OC_CLOSE 0x0010 /* CLOSE command */
+#define OC_SET_GROUP_ADDR 0x0020 /* SET_GROUP_ADDR command */
+#define OC_SET_FUNCT_ADDR 0x0040 /* SET_FUNCT_ADDR command */
+#define OC_READ_ERROR_LOG 0x0080 /* READ_ERROR_LOG command */
+#define OC_READ_ADAPTER 0x0100 /* READ_ADAPTER command */
+#define OC_MODIFY_OPEN_PARMS 0x0400 /* MODIFY_OPEN_PARMS command */
+#define OC_RESTORE_OPEN_PARMS 0x0800 /* RESTORE_OPEN_PARMS command */
+#define OC_SET_FIRST_16_GROUP 0x1000 /* SET_FIRST_16_GROUP command */
+#define OC_SET_BRIDGE_PARMS 0x2000 /* SET_BRIDGE_PARMS command */
+#define OC_CONFIG_BRIDGE_PARMS 0x4000 /* CONFIG_BRIDGE_PARMS command */
+
+#define OPEN 0x0300 /* C: open command. S: completion. */
+#define TRANSMIT 0x0400 /* C: transmit command. S: completion
* status. (reject: COMMAND_REJECT if
* adapter not opened, TRANSMIT already
* issued or address passed in the SCB
* not word aligned)
*/
-#define TRANSMIT_HALT 0x0500 /* C: interrupt TX TPL chain; if no
+#define TRANSMIT_HALT 0x0500 /* C: interrupt TX TPL chain; if no
* TRANSMIT command issued, the command
- * is ignored. (completion with TRANSMIT
+ * is ignored (completion with TRANSMIT
* status (0x0400)!)
*/
-#define RECEIVE 0x0600 /* C: receive command. S: completion
+#define RECEIVE 0x0600 /* C: receive command. S: completion
* status. (reject: COMMAND_REJECT if
* adapter not opened, RECEIVE already
* issued or address passed in the SCB
* not word aligned)
*/
-#define CLOSE 0x0700 /* C: close adapter. S: completion.
+#define CLOSE 0x0700 /* C: close adapter. S: completion.
* (COMMAND_REJECT if adapter not open)
*/
-#define SET_GROUP_ADDR 0x0800 /* C: alter adapter group address after
- * OPEN. S: completion. (COMMAND_REJECT
+#define SET_GROUP_ADDR 0x0800 /* C: alter adapter group address after
+ * OPEN. S: completion. (COMMAND_REJECT
* if adapter not open)
*/
-#define SET_FUNCT_ADDR 0x0900 /* C: alter adapter functional address
+#define SET_FUNCT_ADDR 0x0900 /* C: alter adapter functional address
* after OPEN. S: completion.
* (COMMAND_REJECT if adapter not open)
*/
-#define READ_ERROR_LOG 0x0A00 /* C: read adapter error counters.
+#define READ_ERROR_LOG 0x0A00 /* C: read adapter error counters.
* S: completion. (command ignored
* if adapter not open!)
*/
-#define READ_ADAPTER 0x0B00 /* C: read data from adapter memory.
+#define READ_ADAPTER 0x0B00 /* C: read data from adapter memory.
* (important: after init and before
* open!) S: completion. (ADAPTER_CHECK
* interrupt if undefined storage area
* read)
*/
-#define MODIFY_OPEN_PARMS 0x0D00 /* C: modify some adapter operational
+#define MODIFY_OPEN_PARMS 0x0D00 /* C: modify some adapter operational
* parameters. (bit correspondend to
* WRAP_INTERFACE is ignored)
* S: completion. (reject:
* COMMAND_REJECT)
*/
-#define RESTORE_OPEN_PARMS 0x0E00 /* C: modify some adapter operational
+#define RESTORE_OPEN_PARMS 0x0E00 /* C: modify some adapter operational
* parameters. (bit correspondend
* to WRAP_INTERFACE is ignored)
* S: completion. (reject:
* COMMAND_REJECT)
*/
-#define SET_FIRST_16_GROUP 0x0F00 /* C: alter the first two bytes in
+#define SET_FIRST_16_GROUP 0x0F00 /* C: alter the first two bytes in
* adapter group address.
* S: completion. (reject:
* COMMAND_REJECT)
*/
-#define SET_BRIDGE_PARMS 0x1000 /* C: values and conditions for the
+#define SET_BRIDGE_PARMS 0x1000 /* C: values and conditions for the
* adapter hardware to use when frames
* are copied for forwarding.
* S: completion. (reject:
* COMMAND_REJECT)
*/
-#define CONFIG_BRIDGE_PARMS 0x1100 /* C: ..
+#define CONFIG_BRIDGE_PARMS 0x1100 /* C: ..
* S: completion. (reject:
* COMMAND_REJECT)
*/
-#define SPEED_4 4
-#define SPEED_16 16 /* Default transmission speed */
+#define SPEED_4 4
+#define SPEED_16 16 /* Default transmission speed */
/* Initialization Parameter Block (IPB); word alignment necessary! */
-#define BURST_SIZE 0x0018 /* Default burst size */
-#define BURST_MODE 0x9F00 /* Burst mode enable */
-#define DMA_RETRIES 0x0505 /* Magic DMA retry number... */
+#define BURST_SIZE 0x0018 /* Default burst size */
+#define BURST_MODE 0x9F00 /* Burst mode enable */
+#define DMA_RETRIES 0x0505 /* Magic DMA retry number... */
-#define CYCLE_TIME 3 /* Default AT-bus cycle time: 500 ns
+#define CYCLE_TIME 3 /* Default AT-bus cycle time: 500 ns
* (later adapter version: fix cycle time!)
*/
#define LINE_SPEED_BIT 0x80
@@ -327,7 +351,7 @@
#define FOUR_SECONDS (ONE_SECOND_TICKS * 4)
#define FIVE_SECONDS (ONE_SECOND_TICKS * 5)
-#define BUFFER_SIZE 2048 /* Buffers on Adapter */
+#define BUFFER_SIZE 2048 /* Buffers on Adapter */
#pragma pack(1)
typedef struct {
@@ -337,18 +361,18 @@ typedef struct {
/* Interrupt vectors the adapter places on attached system bus. */
unsigned char CMD_Status_IV; /* Interrupt vector: command status. */
- unsigned char TX_IV; /* Interrupt vector: transmit. */
- unsigned char RX_IV; /* Interrupt vector: receive. */
+ unsigned char TX_IV; /* Interrupt vector: transmit. */
+ unsigned char RX_IV; /* Interrupt vector: receive. */
unsigned char Ring_Status_IV; /* Interrupt vector: ring status. */
- unsigned char SCB_Clear_IV; /* Interrupt vector: SCB clear. */
+ unsigned char SCB_Clear_IV; /* Interrupt vector: SCB clear. */
unsigned char Adapter_CHK_IV; /* Interrupt vector: adapter check. */
unsigned short RX_Burst_Size; /* Max. number of transfer cycles. */
unsigned short TX_Burst_Size; /* During DMA burst; even value! */
- unsigned short DMA_Abort_Thrhld; /* Number of DMA retries. */
+ unsigned short DMA_Abort_Thrhld;/* Number of DMA retries. */
- unsigned long SCB_Addr; /* SCB address: even, word aligned, high-low. */
- unsigned long SSB_Addr; /* SSB address: even, word aligned, high-low. */
+ unsigned long SCB_Addr; /* SCB address: even, word aligned, high-low */
+ unsigned long SSB_Addr; /* SSB address: even, word aligned, high-low */
} IPB, *IPB_Ptr;
#pragma pack()
@@ -361,10 +385,10 @@ typedef struct {
#define RPL_SIZE 14 /* (with TI firmware v2.26 handling
* up to nine fragments possible)
*/
-#define TX_BUF_MIN 20 /* ??? (Stephan: calculation with */
-#define TX_BUF_MAX 40 /* BUFFER_SIZE and MAX_FRAME_SIZE) ???
+#define TX_BUF_MIN 20 /* ??? (Stephan: calculation with */
+#define TX_BUF_MAX 40 /* BUFFER_SIZE and MAX_FRAME_SIZE) ???
*/
-#define DISABLE_EARLY_TOKEN_RELEASE 0x1000
+#define DISABLE_EARLY_TOKEN_RELEASE 0x1000
/* OPEN Options (high-low) */
#define WRAP_INTERFACE 0x0080 /* Inserting omitted for test
@@ -372,51 +396,52 @@ typedef struct {
* as receive data. (usefull for
* testing; change: CLOSE necessary)
*/
-#define DISABLE_HARD_ERROR 0x0040 /* On HARD_ERROR & TRANSMIT_BEACON
+#define DISABLE_HARD_ERROR 0x0040 /* On HARD_ERROR & TRANSMIT_BEACON
* no RING.STATUS interrupt.
*/
-#define DISABLE_SOFT_ERROR 0x0020 /* On SOFT_ERROR, no RING.STATUS
+#define DISABLE_SOFT_ERROR 0x0020 /* On SOFT_ERROR, no RING.STATUS
* interrupt.
*/
-#define PASS_ADAPTER_MAC_FRAMES 0x0010 /* Passing unsupported MAC frames
+#define PASS_ADAPTER_MAC_FRAMES 0x0010 /* Passing unsupported MAC frames
* to system.
*/
-#define PASS_ATTENTION_FRAMES 0x0008 /* All changed attention MAC frames are
+#define PASS_ATTENTION_FRAMES 0x0008 /* All changed attention MAC frames are
* passed to the system.
*/
-#define PAD_ROUTING_FIELD 0x0004 /* Routing field is padded to 18
+#define PAD_ROUTING_FIELD 0x0004 /* Routing field is padded to 18
* bytes.
*/
-#define FRAME_HOLD 0x0002 /* Adapter waits for entire frame before
+#define FRAME_HOLD 0x0002 /*Adapter waits for entire frame before
* initiating DMA transfer; otherwise:
* DMA transfer initiation if internal
* buffer filled.
*/
-#define CONTENDER 0x0001 /* Adapter participates in the monitor
+#define CONTENDER 0x0001 /* Adapter participates in the monitor
* contention process.
*/
-#define PASS_BEACON_MAC_FRAMES 0x8000 /* Adapter passes beacon MAC frames
+#define PASS_BEACON_MAC_FRAMES 0x8000 /* Adapter passes beacon MAC frames
* to the system.
*/
-#define EARLY_TOKEN_RELEASE 0x1000 /* Only valid in 16 Mbps operation;
+#define EARLY_TOKEN_RELEASE 0x1000 /* Only valid in 16 Mbps operation;
* 0 = ETR. (no effect in 4 Mbps
* operation)
*/
-#define COPY_ALL_MAC_FRAMES 0x0400 /* All MAC frames are copied to
+#define COPY_ALL_MAC_FRAMES 0x0400 /* All MAC frames are copied to
* the system. (after OPEN: duplicate
* address test (DAT) MAC frame is
* first received frame copied to the
* system)
*/
-#define COPY_ALL_NON_MAC_FRAMES 0x0200 /* All non MAC frames are copied to
+#define COPY_ALL_NON_MAC_FRAMES 0x0200 /* All non MAC frames are copied to
* the system.
*/
-#define PASS_FIRST_BUF_ONLY 0x0100 /* Passes only first internal buffer
+#define PASS_FIRST_BUF_ONLY 0x0100 /* Passes only first internal buffer
* of each received frame; FrameSize
* of RPLs must contain internal
* BUFFER_SIZE bits for promiscous mode.
*/
-#define ENABLE_FULL_DUPLEX_SELECTION 0x2000 /* Enable the use of full-duplex
+#define ENABLE_FULL_DUPLEX_SELECTION 0x2000
+ /* Enable the use of full-duplex
* settings with bits in byte 22 in
* ocpl. (new feature in firmware
* version 3.09)
@@ -434,7 +459,7 @@ typedef struct {
* fragments following.
*/
-#define ISA_MAX_ADDRESS 0x00ffffff
+#define ISA_MAX_ADDRESS 0x00ffffff
#pragma pack(1)
typedef struct {
@@ -1031,15 +1056,6 @@ struct s_RPL { /* Receive Parameter List */
int RPLIndex;
};
-#define TMS_ISA 1
-#define TMS_PCI 2
-struct cardinfo_table {
- int type; /* 1 = ISA, 2 = PCI */
- int vendor_id;
- int device_id;
- char *name;
-};
-
/* Information that need to be kept for each board. */
typedef struct net_local {
#pragma pack(1)
@@ -1094,7 +1110,7 @@ typedef struct net_local {
struct tr_statistics MacStat; /* MAC statistics structure */
- struct cardinfo_table *CardType;
+ unsigned long dmalimit; /* the max DMA address (ie, ISA) */
struct timer_list timer;
@@ -1103,6 +1119,13 @@ typedef struct net_local {
INTPTRS intptrs; /* Internal adapter pointer. Must be read
* before OPEN command.
*/
+ unsigned short (*setnselout)(struct net_device *);
+ unsigned short (*sifreadb)(struct net_device *, unsigned short);
+ void (*sifwriteb)(struct net_device *, unsigned short, unsigned short);
+ unsigned short (*sifreadw)(struct net_device *, unsigned short);
+ void (*sifwritew)(struct net_device *, unsigned short, unsigned short);
+
+ void *tmspriv;
} NET_LOCAL;
#endif /* __KERNEL__ */
diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c
new file mode 100644
index 000000000..ffcfab931
--- /dev/null
+++ b/drivers/net/tokenring/tmspci.c
@@ -0,0 +1,336 @@
+/*
+ * tmspci.c: A generic network driver for TMS380-based PCI token ring cards.
+ *
+ * Written 1999 by Adam Fritzler
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License, incorporated herein by reference.
+ *
+ * This driver module supports the following cards:
+ * - SysKonnect TR4/16(+) PCI (SK-4590)
+ * - SysKonnect TR4/16 PCI (SK-4591)
+ * - Compaq TR 4/16 PCI
+ * - Thomas-Conrad TC4048 4/16 PCI
+ * - 3Com 3C339 Token Link Velocity
+ *
+ * Maintainer(s):
+ * AF Adam Fritzler mid@auk.cx
+ *
+ * Modification History:
+ * 30-Dec-99 AF Split off from the tms380tr driver.
+ * 22-Jan-00 AF Updated to use indirect read/writes
+ *
+ * TODO:
+ * 1. See if we can use MMIO instead of port accesses
+ *
+ */
+static const char *version = "tmspci.c: v1.01 22/01/2000 by Adam Fritzler\n";
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <linux/netdevice.h>
+#include <linux/trdevice.h>
+#include "tms380tr.h"
+
+#define TMS_PCI_IO_EXTENT 32
+
+struct cardinfo_table {
+ int vendor_id; /* PCI info */
+ int device_id;
+ int registeroffset; /* SIF offset from dev->base_addr */
+ unsigned char nselout[2]; /* NSELOUT vals for 4mb([0]) and 16mb([1]) */
+ char *name;
+};
+
+struct cardinfo_table probelist[] = {
+ { 0, 0,
+ 0x0000, {0x00, 0x00}, "Unknown TMS380 Token Ring Adapter"},
+ { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TOKENRING,
+ 0x0000, {0x03, 0x01}, "Compaq 4/16 TR PCI"},
+ { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_TR,
+ 0x0000, {0x03, 0x01}, "SK NET TR 4/16 PCI"},
+ { PCI_VENDOR_ID_TCONRAD, PCI_DEVICE_ID_TCONRAD_TOKENRING,
+ 0x0000, {0x03, 0x01}, "Thomas-Conrad TC4048 PCI 4/16"},
+ { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C339,
+ 0x0000, {0x03, 0x01}, "3Com Token Link Velocity"},
+ { 0, 0, 0, {0x00, 0x00}, NULL}
+};
+
+int tms_pci_probe(void);
+static int tms_pci_open(struct net_device *dev);
+static int tms_pci_close(struct net_device *dev);
+static void tms_pci_read_eeprom(struct net_device *dev);
+static unsigned short tms_pci_setnselout_pins(struct net_device *dev);
+
+static unsigned short tms_pci_sifreadb(struct net_device *dev, unsigned short reg)
+{
+ return inb(dev->base_addr + reg);
+}
+
+static unsigned short tms_pci_sifreadw(struct net_device *dev, unsigned short reg)
+{
+ return inw(dev->base_addr + reg);
+}
+
+static void tms_pci_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
+{
+ outb(val, dev->base_addr + reg);
+}
+
+static void tms_pci_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
+{
+ outw(val, dev->base_addr + reg);
+}
+
+struct tms_pci_card {
+ struct net_device *dev;
+ struct pci_dev *pci_dev;
+ struct cardinfo_table *cardinfo;
+ struct tms_pci_card *next;
+};
+static struct tms_pci_card *tms_pci_card_list = NULL;
+
+
+struct cardinfo_table * __init tms_pci_getcardinfo(unsigned short vendor,
+ unsigned short device)
+{
+ int cur;
+ for (cur = 1; probelist[cur].name != NULL; cur++) {
+ if ((probelist[cur].vendor_id == vendor) &&
+ (probelist[cur].device_id == device))
+ return &probelist[cur];
+ }
+
+ return NULL;
+}
+
+int __init tms_pci_probe(void)
+{
+ static int versionprinted = 0;
+ struct pci_dev *pdev = NULL ;
+ struct net_device *dev;
+ struct net_local *tp;
+ int i;
+
+ if (!pci_present())
+ return (-1); /* No PCI present. */
+
+ while ( (pdev=pci_find_class(PCI_CLASS_NETWORK_TOKEN_RING<<8, pdev))) {
+ unsigned int pci_irq_line;
+ unsigned long pci_ioaddr;
+ struct tms_pci_card *card;
+ struct cardinfo_table *cardinfo;
+
+ if ((cardinfo =
+ tms_pci_getcardinfo(pdev->vendor, pdev->device)) == NULL)
+ continue;
+
+ if (versionprinted++ == 0)
+ printk("%s", version);
+
+ pci_enable_device(pdev);
+
+ /* Remove I/O space marker in bit 0. */
+ pci_irq_line = pdev->irq;
+ pci_ioaddr = pdev->resource[0].start ;
+
+ if(check_region(pci_ioaddr, TMS_PCI_IO_EXTENT))
+ continue;
+
+ /* At this point we have found a valid card. */
+
+ dev = init_trdev(NULL, 0);
+
+ request_region(pci_ioaddr, TMS_PCI_IO_EXTENT, cardinfo->name);
+ if(request_irq(pdev->irq, tms380tr_interrupt, SA_SHIRQ,
+ cardinfo->name, dev)) {
+ release_region(pci_ioaddr, TMS_PCI_IO_EXTENT);
+ continue; /*return (-ENODEV);*/ /* continue; ?? */
+ }
+
+ /*
+ if (load_tms380_module("tmspci.c")) {
+ return 0;
+ }
+ */
+
+ pci_ioaddr &= ~3 ;
+ dev->base_addr = pci_ioaddr;
+ dev->irq = pci_irq_line;
+ dev->dma = 0;
+
+ printk("%s: %s\n", dev->name, cardinfo->name);
+ printk("%s: IO: %#4lx IRQ: %d\n",
+ dev->name, dev->base_addr, dev->irq);
+ /*
+ * Some cards have their TMS SIF registers offset from
+ * their given base address. Account for that here.
+ */
+ dev->base_addr += cardinfo->registeroffset;
+
+ tms_pci_read_eeprom(dev);
+
+ printk("%s: Ring Station Address: ", dev->name);
+ printk("%2.2x", dev->dev_addr[0]);
+ for (i = 1; i < 6; i++)
+ printk(":%2.2x", dev->dev_addr[i]);
+ printk("\n");
+
+ if (tmsdev_init(dev)) {
+ printk("%s: unable to get memory for dev->priv.\n", dev->name);
+ return 0;
+ }
+
+ tp = (struct net_local *)dev->priv;
+ tp->dmalimit = 0; /* XXX: should be the max PCI32 DMA max */
+ tp->setnselout = tms_pci_setnselout_pins;
+
+ tp->sifreadb = tms_pci_sifreadb;
+ tp->sifreadw = tms_pci_sifreadw;
+ tp->sifwriteb = tms_pci_sifwriteb;
+ tp->sifwritew = tms_pci_sifwritew;
+
+ memcpy(tp->ProductID, cardinfo->name, PROD_ID_SIZE + 1);
+
+ tp->tmspriv = cardinfo;
+
+ dev->open = tms_pci_open;
+ dev->stop = tms_pci_close;
+
+ if (register_trdev(dev) == 0) {
+ /* Enlist in the card list */
+ card = kmalloc(sizeof(struct tms_pci_card), GFP_KERNEL);
+ card->next = tms_pci_card_list;
+ tms_pci_card_list = card;
+ card->dev = dev;
+ card->pci_dev = pdev;
+ card->cardinfo = cardinfo;
+ } else {
+ printk("%s: register_trdev() returned non-zero.\n", dev->name);
+ kfree(dev->priv);
+ kfree(dev);
+ return -1;
+ }
+ }
+
+ if (tms_pci_card_list)
+ return 0;
+ return (-1);
+}
+
+/*
+ * Reads MAC address from adapter RAM, which should've read it from
+ * the onboard ROM.
+ *
+ * Calling this on a board that does not support it can be a very
+ * dangerous thing. The Madge board, for instance, will lock your
+ * machine hard when this is called. Luckily, its supported in a
+ * seperate driver. --ASF
+ */
+static void tms_pci_read_eeprom(struct net_device *dev)
+{
+ int i;
+
+ /* Address: 0000:0000 */
+ tms_pci_sifwritew(dev, 0, SIFADX);
+ tms_pci_sifwritew(dev, 0, SIFADR);
+
+ /* Read six byte MAC address data */
+ dev->addr_len = 6;
+ for(i = 0; i < 6; i++)
+ dev->dev_addr[i] = tms_pci_sifreadw(dev, SIFINC) >> 8;
+}
+
+unsigned short tms_pci_setnselout_pins(struct net_device *dev)
+{
+ unsigned short val = 0;
+ struct net_local *tp = (struct net_local *)dev->priv;
+ struct cardinfo_table *cardinfo = (struct cardinfo_table *)tp->tmspriv;
+
+ if(tp->DataRate == SPEED_4)
+ val |= cardinfo->nselout[0]; /* Set 4Mbps */
+ else
+ val |= cardinfo->nselout[1]; /* Set 16Mbps */
+ return val;
+}
+
+static int tms_pci_open(struct net_device *dev)
+{
+ tms380tr_open(dev);
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int tms_pci_close(struct net_device *dev)
+{
+ tms380tr_close(dev);
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+#ifdef MODULE
+
+int init_module(void)
+{
+ /* Probe for cards. */
+ if (tms_pci_probe()) {
+ printk(KERN_NOTICE "tmspci.c: No cards found.\n");
+ }
+ /* lock_tms380_module(); */
+ return (0);
+}
+
+void cleanup_module(void)
+{
+ struct net_device *dev;
+ struct tms_pci_card *this_card;
+
+ while (tms_pci_card_list) {
+ dev = tms_pci_card_list->dev;
+
+ /*
+ * If we used a register offset, revert here.
+ */
+ if (dev->priv)
+ {
+ struct net_local *tp;
+ struct cardinfo_table *cardinfo;
+
+ tp = (struct net_local *)dev->priv;
+ cardinfo = (struct cardinfo_table *)tp->tmspriv;
+
+ dev->base_addr -= cardinfo->registeroffset;
+ }
+ unregister_netdev(dev);
+ release_region(dev->base_addr, TMS_PCI_IO_EXTENT);
+ free_irq(dev->irq, dev);
+ kfree(dev->priv);
+ kfree(dev);
+ this_card = tms_pci_card_list;
+ tms_pci_card_list = this_card->next;
+ kfree(this_card);
+ }
+ /* unlock_tms380_module(); */
+}
+#endif /* MODULE */
+
+
+/*
+ * Local variables:
+ * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tmspci.c"
+ * alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tmspci.c"
+ * c-set-style "K&R"
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
diff --git a/drivers/net/wan/Config.in b/drivers/net/wan/Config.in
index 503854a0f..962e171fa 100644
--- a/drivers/net/wan/Config.in
+++ b/drivers/net/wan/Config.in
@@ -34,10 +34,11 @@ if [ "$CONFIG_WAN" = "y" ]; then
if [ "$CONFIG_WAN_ROUTER_DRIVERS" = "y" ]; then
dep_tristate ' Sangoma WANPIPE(tm) multiprotocol cards' CONFIG_VENDOR_SANGOMA $CONFIG_WAN_ROUTER_DRIVERS
if [ "$CONFIG_VENDOR_SANGOMA" != "n" ]; then
- int 'Maximum number of cards' CONFIG_WANPIPE_CARDS 1
- bool ' WANPIPE X.25 support' CONFIG_WANPIPE_X25
+ int ' Maximum number of cards' CONFIG_WANPIPE_CARDS 1
+ bool ' WANPIPE Cisco HDLC support' CONFIG_WANPIPE_CHDLC
bool ' WANPIPE Frame Relay support' CONFIG_WANPIPE_FR
bool ' WANPIPE PPP support' CONFIG_WANPIPE_PPP
+ bool ' WANPIPE X.25 support' CONFIG_WANPIPE_X25
fi
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
dep_tristate ' Cyclom 2X(tm) cards (EXPERIMENTAL)' CONFIG_CYCLADES_SYNC $CONFIG_WAN_ROUTER_DRIVERS
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
index 73060f5b9..67f6bb59b 100644
--- a/drivers/net/wan/Makefile
+++ b/drivers/net/wan/Makefile
@@ -102,6 +102,9 @@ ifeq ($(CONFIG_VENDOR_SANGOMA),y)
ifeq ($(CONFIG_WANPIPE_X25),y)
L_OBJS += sdla_x25.o
endif
+ ifeq ($(CONFIG_WANPIPE_CHDLC),y)
+ L_OBJS += sdla_chdlc.o
+ endif
ifeq ($(CONFIG_WANPIPE_FR),y)
L_OBJS += sdla_fr.o
endif
@@ -122,6 +125,9 @@ ifeq ($(CONFIG_VENDOR_SANGOMA),m)
ifeq ($(CONFIG_WANPIPE_FR),y)
WANPIPE_OBJS += sdla_fr.o
endif
+ ifeq ($(CONFIG_WANPIPE_CHDLC),y)
+ WANPIPE_OBJS += sdla_chdlc.o
+ endif
ifeq ($(CONFIG_WANPIPE_PPP),y)
WANPIPE_OBJS += sdla_ppp.o
endif
diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c
index b9b72ddeb..188b06c97 100644
--- a/drivers/net/wan/cycx_main.c
+++ b/drivers/net/wan/cycx_main.c
@@ -13,6 +13,8 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
* ============================================================================
+* 2000/01/21 acme rename cyclomx_open to cyclomx_mod_inc_use_count
+* and cyclomx_close to cyclomx_mod_dec_use_count
* 2000/01/08 acme cleanup
* 1999/11/06 acme cycx_down back to life (it needs to be
* called to iounmap the dpmbase)
@@ -49,7 +51,7 @@ MODULE_DESCRIPTION("Cyclom 2X Sync Card Driver.");
/* Defines & Macros */
#define DRV_VERSION 0 /* version number */
-#define DRV_RELEASE 5 /* release (minor version) number */
+#define DRV_RELEASE 6 /* release (minor version) number */
#define MAX_CARDS 1 /* max number of adapters */
#ifndef CONFIG_CYCLOMX_CARDS /* configurable option */
@@ -132,9 +134,9 @@ int __init cyclomx_init (void)
err = register_wan_device(wandev);
if (err) {
- printk(KERN_ERR
- "%s: %s registration failed with error %d!\n",
- drvname, card->devname, err);
+ printk(KERN_ERR "%s: %s registration failed with "
+ "error %d!\n",
+ drvname, card->devname, err);
break;
}
}
@@ -238,7 +240,7 @@ static int setup (wan_device_t *wandev, wandev_conf_t *conf)
/* Initialize WAN device data space */
wandev->irq = irq;
wandev->dma = wandev->ioport = 0;
- wandev->maddr = (unsigned long*)card->hw.dpmbase;
+ wandev->maddr = card->hw.dpmbase;
wandev->msize = card->hw.dpmsize;
wandev->hw_opt[2] = 0;
wandev->hw_opt[3] = card->hw.fwid;
@@ -338,7 +340,7 @@ static void cycx_isr (int irq, void *dev_id, struct pt_regs *regs)
* have to call MOD_INC_USE_COUNT, but cannot include 'module.h' where it's
* defined more than once into the same kernel module.
*/
-void cyclomx_open (cycx_t *card)
+void cyclomx_mod_inc_use_count (cycx_t *card)
{
++card->open_cnt;
MOD_INC_USE_COUNT;
@@ -350,7 +352,7 @@ void cyclomx_open (cycx_t *card)
* have to call MOD_DEC_USE_COUNT, but cannot include 'module.h' where it's
* defined more than once into the same kernel module.
*/
-void cyclomx_close (cycx_t *card)
+void cyclomx_mod_dec_use_count (cycx_t *card)
{
--card->open_cnt;
MOD_DEC_USE_COUNT;
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index e9156df92..e11c9bcfe 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -70,6 +70,7 @@
* 1998/12/26 acme Minimal debug code cleanup
* 1998/08/08 acme Initial version.
*/
+
#define CYCLOMX_X25_DEBUG 1
#include <linux/version.h>
@@ -188,7 +189,6 @@ static void x25_dump_devs(wan_device_t *wandev);
*
* This routine is called by the main Cyclom 2X module during setup. At this
* point adapter is completely initialized and X.25 firmware is running.
- * o read firmware version (to make sure it's alive)
* o configure adapter
* o initialize protocol-specific fields of the adapter data space.
*
@@ -336,7 +336,8 @@ static int update (wan_device_t *wandev)
*
* Return: 0 o.k.
* < 0 failure (channel will not be created) */
-static int new_if (wan_device_t *wandev, struct net_device *dev, wanif_conf_t *conf)
+static int new_if (wan_device_t *wandev, struct net_device *dev,
+ wanif_conf_t *conf)
{
cycx_t *card = wandev->private;
x25_channel_t *chan;
@@ -507,7 +508,7 @@ static int if_open (struct net_device *dev)
dev->interrupt = 0;
dev->tbusy = 0;
dev->start = 1;
- cyclomx_open(card);
+ cyclomx_mod_inc_use_count(card);
return 0;
}
@@ -525,7 +526,7 @@ static int if_close (struct net_device *dev)
if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING)
chan_disconnect(dev);
- cyclomx_close(card);
+ cyclomx_mod_dec_use_count(card);
return 0;
}
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index 9cadf1e0b..29bedf8f9 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -1666,7 +1666,7 @@ int __init sdla_init(struct net_device *dev)
return(0);
}
-int __init sdla_setup(void)
+int __init sdla_c_setup(void)
{
printk("%s.\n", version);
register_frad(devname);
@@ -1680,7 +1680,7 @@ int init_module(void)
{
int result;
- sdla_setup();
+ sdla_c_setup();
if ((result = register_netdev(&sdla0)) != 0)
return result;
return 0;
diff --git a/drivers/net/wan/sdla_chdlc.c b/drivers/net/wan/sdla_chdlc.c
new file mode 100644
index 000000000..3df910ea1
--- /dev/null
+++ b/drivers/net/wan/sdla_chdlc.c
@@ -0,0 +1,2785 @@
+/*****************************************************************************
+* sdla_chdlc.c WANPIPE(tm) Multiprotocol WAN Link Driver. Cisco HDLC module.
+*
+* Authors: Nenad Corbic <ncorbic@sangoma.com>
+* Gideon Hack
+*
+* Copyright: (c) 1995-1999 Sangoma Technologies 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.
+* ============================================================================
+* Nov 20, 1999 Nenad Corbic Fixed zero length API bug.
+* Sep 30, 1999 Nenad Corbic Fixed dynamic IP and route setup.
+* Sep 23, 1999 Nenad Corbic Added SMP support, fixed tracing
+* Sep 13, 1999 Nenad Corbic Split up Port 0 and 1 into separate devices.
+* Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
+* Oct 30, 1998 Jaspreet Singh Added Support for CHDLC API (HDLC STREAMING).
+* Oct 28, 1998 Jaspreet Singh Added Support for Dual Port CHDLC.
+* Aug 07, 1998 David Fong Initial version.
+*****************************************************************************/
+
+#include <linux/version.h>
+#include <linux/kernel.h> /* printk(), and other useful stuff */
+#include <linux/stddef.h> /* offsetof(), etc. */
+#include <linux/errno.h> /* return codes */
+#include <linux/string.h> /* inline memset(), etc. */
+#include <linux/malloc.h> /* kmalloc(), kfree() */
+#include <linux/wanrouter.h> /* WAN router definitions */
+#include <linux/wanpipe.h> /* WANPIPE common user API definitions */
+#include <linux/if_arp.h> /* ARPHRD_* defines */
+#include <linux/inetdevice.h>
+#include <asm/uaccess.h>
+#include <linux/in.h> /* sockaddr_in */
+#include <linux/inet.h>
+#include <linux/if.h>
+#include <asm/byteorder.h> /* htons(), etc. */
+#include <linux/sdlapci.h>
+#include <asm/io.h>
+
+#include <linux/sdla_chdlc.h> /* CHDLC firmware API definitions */
+
+/****** Defines & Macros ****************************************************/
+
+#ifdef _DEBUG_
+#define STATIC
+#else
+#define STATIC static
+#endif
+
+/* reasons for enabling the timer interrupt on the adapter */
+#define TMR_INT_ENABLED_UDP 0x0001
+#define TMR_INT_ENABLED_UPDATE 0x0002
+
+#define CHDLC_DFLT_DATA_LEN 1500 /* default MTU */
+#define CHDLC_HDR_LEN 1
+
+#define IFF_POINTTOPOINT 0x10
+
+#define WANPIPE 0x00
+#define API 0x01
+#define CHDLC_API 0x01
+
+#define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" )
+
+
+/******Data Structures*****************************************************/
+
+/* This structure is placed in the private data area of the device structure.
+ * The card structure used to occupy the private area but now the following
+ * structure will incorporate the card structure along with CHDLC specific data
+ */
+
+typedef struct chdlc_private_area
+{
+ sdla_t *card;
+ int TracingEnabled; /* For enabling Tracing */
+ unsigned long curr_trace_addr; /* Used for Tracing */
+ unsigned long start_trace_addr;
+ unsigned long end_trace_addr;
+ unsigned long base_addr_trace_buffer;
+ unsigned long end_addr_trace_buffer;
+ unsigned short number_trace_elements;
+ unsigned available_buffer_space;
+ unsigned long router_start_time;
+ unsigned char route_status;
+ unsigned char route_removed;
+ unsigned long tick_counter; /* For 5s timeout counter */
+ unsigned long router_up_time;
+ u32 IP_address; /* IP addressing */
+ u32 IP_netmask;
+ unsigned char mc; /* Mulitcast support on/off */
+ unsigned short udp_pkt_lgth; /* udp packet processing */
+ char udp_pkt_src;
+ char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
+ unsigned short timer_int_enabled;
+ char update_comms_stats; /* updating comms stats */
+ //FIXME: add driver stats as per frame relay!
+
+} chdlc_private_area_t;
+
+/* Route Status options */
+#define NO_ROUTE 0x00
+#define ADD_ROUTE 0x01
+#define ROUTE_ADDED 0x02
+#define REMOVE_ROUTE 0x03
+
+
+/* variable for keeping track of enabling/disabling FT1 monitor status */
+static int rCount = 0;
+
+/* variable for tracking how many interfaces to open for WANPIPE on the
+ two ports */
+
+extern void disable_irq(unsigned int);
+extern void enable_irq(unsigned int);
+
+/****** Function Prototypes *************************************************/
+/* WAN link driver entry points. These are called by the WAN router module. */
+static int update (wan_device_t* wandev);
+static int new_if (wan_device_t* wandev, struct net_device* dev,
+ wanif_conf_t* conf);
+static int del_if (wan_device_t* wandev, struct net_device* dev);
+
+/* Network device interface */
+static int if_init (struct net_device* dev);
+static int if_open (struct net_device* dev);
+static int if_close (struct net_device* dev);
+static int if_header (struct sk_buff* skb, struct net_device* dev,
+ unsigned short type, void* daddr, void* saddr, unsigned len);
+#ifdef LINUX_2_1
+static int if_rebuild_hdr (struct sk_buff *skb);
+#else
+static int if_rebuild_hdr (void* hdr, struct net_device* dev, unsigned long raddr,
+ struct sk_buff* skb);
+#endif
+static int if_send (struct sk_buff* skb, struct net_device* dev);
+static struct enet_statistics* if_stats (struct net_device* dev);
+
+/* CHDLC Firmware interface functions */
+static int chdlc_configure (sdla_t* card, void* data);
+static int chdlc_comm_enable (sdla_t* card);
+static int chdlc_comm_disable (sdla_t* card);
+static int chdlc_read_version (sdla_t* card, char* str);
+static int chdlc_set_intr_mode (sdla_t* card, unsigned mode);
+static int chdlc_send (sdla_t* card, void* data, unsigned len);
+static int chdlc_read_comm_err_stats (sdla_t* card);
+static int chdlc_read_op_stats (sdla_t* card);
+
+
+/* Miscellaneous CHDLC Functions */
+static int set_chdlc_config (sdla_t* card);
+static void init_chdlc_tx_rx_buff( sdla_t* card, struct net_device *dev );
+static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb);
+static int process_chdlc_exception(sdla_t *card);
+static int process_global_exception(sdla_t *card);
+static int update_comms_stats(sdla_t* card,
+ chdlc_private_area_t* chdlc_priv_area);
+static int configure_ip (sdla_t* card);
+static int unconfigure_ip (sdla_t* card);
+static void process_route(sdla_t *card);
+static void port_set_state (sdla_t *card, int);
+
+
+/* Interrupt handlers */
+static void wpc_isr (sdla_t* card);
+static void rx_intr (sdla_t* card);
+static void timer_intr(sdla_t *);
+
+/* Miscellaneous functions */
+static int chk_bcast_mcast_addr(sdla_t* card, struct net_device* dev,
+ struct sk_buff *skb);
+static int reply_udp( unsigned char *data, unsigned int mbox_len );
+static int intr_test( sdla_t* card, struct net_device *dev );
+static int udp_pkt_type( struct sk_buff *skb , sdla_t* card);
+static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
+ struct sk_buff *skb, struct net_device* dev,
+ chdlc_private_area_t* chdlc_priv_area);
+static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev,
+ chdlc_private_area_t* chdlc_priv_area);
+static unsigned short calc_checksum (char *, int);
+static void s508_lock (sdla_t *card, unsigned long *smp_flags);
+static void s508_unlock (sdla_t *card, unsigned long *smp_flags);
+
+
+static int Intr_test_counter;
+/****** Public Functions ****************************************************/
+
+/*============================================================================
+ * Cisco HDLC protocol initialization routine.
+ *
+ * This routine is called by the main WANPIPE module during setup. At this
+ * point adapter is completely initialized and firmware is running.
+ * o read firmware version (to make sure it's alive)
+ * o configure adapter
+ * o initialize protocol-specific fields of the adapter data space.
+ *
+ * Return: 0 o.k.
+ * < 0 failure.
+ */
+int wpc_init (sdla_t* card, wandev_conf_t* conf)
+{
+ unsigned char port_num;
+ int err;
+ unsigned long max_permitted_baud = 0;
+
+ union
+ {
+ char str[80];
+ } u;
+ volatile CHDLC_MAILBOX_STRUCT* mb;
+ CHDLC_MAILBOX_STRUCT* mb1;
+ unsigned long timeout;
+
+ /* Verify configuration ID */
+ if (conf->config_id != WANCONFIG_CHDLC) {
+ printk(KERN_INFO "%s: invalid configuration ID %u!\n",
+ card->devname, conf->config_id);
+ return -EINVAL;
+ }
+
+ /* Find out which Port to use */
+ if ((conf->comm_port == WANOPT_PRI) || (conf->comm_port == WANOPT_SEC)){
+ if (card->next){
+
+ if (conf->comm_port != card->next->u.c.comm_port){
+ card->u.c.comm_port = conf->comm_port;
+ }else{
+ printk(KERN_ERR "%s: ERROR - %s port used!\n",
+ card->wandev.name, PORT(conf->comm_port));
+ return -EINVAL;
+ }
+ }else{
+ card->u.c.comm_port = conf->comm_port;
+ }
+ }else{
+ printk(KERN_ERR "%s: ERROR - Invalid Port Selected!\n",
+ card->wandev.name);
+ return -EINVAL;
+ }
+
+
+ /* Initialize protocol-specific fields */
+ if(card->hw.type != SDLA_S514){
+
+ if (card->u.c.comm_port == WANOPT_PRI){
+ card->mbox = (void *) card->hw.dpmbase;
+ }else{
+ card->mbox = (void *) card->hw.dpmbase +
+ SEC_BASE_ADDR_MB_STRUCT - PRI_BASE_ADDR_MB_STRUCT;
+ }
+ }else{
+ /* for a S514 adapter, set a pointer to the actual mailbox in the */
+ /* allocated virtual memory area */
+ if (card->u.c.comm_port == WANOPT_PRI){
+ card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT;
+ }else{
+ card->mbox = (void *) card->hw.dpmbase + SEC_BASE_ADDR_MB_STRUCT;
+ }
+ }
+
+ mb = mb1 = card->mbox;
+
+ if (!card->configured){
+
+ /* The board will place an 'I' in the return code to indicate that it is
+ ready to accept commands. We expect this to be completed in less
+ than 1 second. */
+
+ timeout = jiffies;
+ while (mb->return_code != 'I') /* Wait 1s for board to initialize */
+ if ((jiffies - timeout) > 1*HZ) break;
+
+ if (mb->return_code != 'I') {
+ printk(KERN_INFO
+ "%s: Initialization not completed by adapter\n",
+ card->devname);
+ printk(KERN_INFO "Please contact Sangoma representative.\n");
+ return -EIO;
+ }
+ }
+
+ /* Read firmware version. Note that when adapter initializes, it
+ * clears the mailbox, so it may appear that the first command was
+ * executed successfully when in fact it was merely erased. To work
+ * around this, we execute the first command twice.
+ */
+
+ if (chdlc_read_version(card, u.str))
+ return -EIO;
+
+ printk(KERN_INFO "%s: Running Cisco HDLC firmware v%s\n",
+ card->devname, u.str);
+
+ card->isr = &wpc_isr;
+ card->poll = NULL;
+ card->exec = NULL;
+ card->wandev.update = &update;
+ card->wandev.new_if = &new_if;
+ card->wandev.del_if = &del_if;
+ card->wandev.state = WAN_DUALPORT;
+ card->wandev.udp_port = conf->udp_port;
+
+ card->wandev.new_if_cnt = 0;
+
+ /* This is for the ports link state */
+ card->u.c.state = WAN_DISCONNECTED;
+
+ /* reset the number of times the 'update()' proc has been called */
+ card->u.c.update_call_count = 0;
+
+ card->wandev.ttl = conf->ttl;
+ card->wandev.interface = conf->interface;
+
+ if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&&
+ card->hw.type != SDLA_S514){
+ printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n",
+ card->devname, PORT(card->u.c.comm_port));
+ return -EIO;
+ }
+
+ card->wandev.clocking = conf->clocking;
+
+ port_num = card->u.c.comm_port;
+
+ /* Setup Port Bps */
+
+ if(card->wandev.clocking) {
+
+ if(port_num == WANOPT_PRI) {
+ /* For Primary Port 0 */
+ max_permitted_baud =
+ (card->hw.type == SDLA_S514) ?
+ PRI_MAX_BAUD_RATE_S514 :
+ PRI_MAX_BAUD_RATE_S508;
+ }
+ else if(port_num == WANOPT_SEC) {
+ /* For Secondary Port 1 */
+ max_permitted_baud =
+ (card->hw.type == SDLA_S514) ?
+ SEC_MAX_BAUD_RATE_S514 :
+ SEC_MAX_BAUD_RATE_S508;
+ }
+
+ if(conf->bps > max_permitted_baud) {
+ conf->bps = max_permitted_baud;
+ printk(KERN_INFO "%s: Baud too high!\n",
+ card->wandev.name);
+ printk(KERN_INFO "%s: Baud rate set to %lu bps\n",
+ card->wandev.name, max_permitted_baud);
+ }
+
+ card->wandev.bps = conf->bps;
+ }else{
+ card->wandev.bps = 0;
+ }
+
+ /* Setup the Port MTU */
+ if(port_num == WANOPT_PRI) {
+ /* For Primary Port 0 */
+ card->wandev.mtu =
+ (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
+ min(conf->mtu, PRI_MAX_NO_DATA_BYTES_IN_FRAME) :
+ CHDLC_DFLT_DATA_LEN;
+ } else if(port_num == WANOPT_SEC) {
+ /* For Secondary Port 1 */
+ card->wandev.mtu =
+ (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
+ min(conf->mtu, SEC_MAX_NO_DATA_BYTES_IN_FRAME) :
+ CHDLC_DFLT_DATA_LEN;
+ }
+
+ /* Set up the interrupt status area */
+ /* Read the CHDLC Configuration and obtain:
+ * Ptr to shared memory infor struct
+ * Use this pointer to calculate the value of card->u.c.flags !
+ */
+ mb1->buffer_length = 0;
+ mb1->command = READ_CHDLC_CONFIGURATION;
+ err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT;
+ if(err != COMMAND_OK) {
+ clear_bit(1, (void*)&card->wandev.critical);
+
+ if(card->hw.type != SDLA_S514)
+ enable_irq(card->hw.irq);
+
+ chdlc_error(card, err, mb1);
+ return -EIO;
+ }
+
+ if(card->hw.type == SDLA_S514){
+ card->u.c.flags = (void *)(card->hw.dpmbase +
+ (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
+ ptr_shared_mem_info_struct));
+ }else{
+ card->u.c.flags = (void *)(card->hw.dpmbase +
+ (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
+ ptr_shared_mem_info_struct % SDLA_WINDOWSIZE));
+ }
+
+ return 0;
+}
+
+/******* WAN Device Driver Entry Points *************************************/
+
+/*============================================================================
+ * Update device status & statistics
+ * This procedure is called when updating the PROC file system and returns
+ * various communications statistics. These statistics are accumulated from 3
+ * different locations:
+ * 1) The 'if_stats' recorded for the device.
+ * 2) Communication error statistics on the adapter.
+ * 3) CHDLC operational statistics on the adapter.
+ * The board level statistics are read during a timer interrupt. Note that we
+ * read the error and operational statistics during consecitive timer ticks so
+ * as to minimize the time that we are inside the interrupt handler.
+ *
+ */
+static int update (wan_device_t* wandev)
+{
+ sdla_t* card = wandev->private;
+ struct net_device* dev = card->wandev.dev;
+ volatile chdlc_private_area_t* chdlc_priv_area = dev->priv;
+ SHARED_MEMORY_INFO_STRUCT *flags;
+ unsigned long timeout;
+
+ /* sanity checks */
+ if((wandev == NULL) || (wandev->private == NULL))
+ return -EFAULT;
+
+ if(wandev->state == WAN_UNCONFIGURED)
+ return -ENODEV;
+
+ /* more sanity checks */
+ if(!card->u.c.flags)
+ return -ENODEV;
+ if(test_bit(1, (void*)&card->wandev.critical))
+ return -EAGAIN;
+
+ if(!dev->start)
+ return -ENODEV;
+
+ flags = card->u.c.flags;
+ if(chdlc_priv_area->update_comms_stats){
+ return -EAGAIN;
+ }
+
+ /* we will need 2 timer interrupts to complete the */
+ /* reading of the statistics */
+ chdlc_priv_area->update_comms_stats = 2;
+ flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
+ chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UPDATE;
+
+ /* wait a maximum of 1 second for the statistics to be updated */
+ timeout = jiffies;
+ for(;;) {
+ if(chdlc_priv_area->update_comms_stats == 0)
+ break;
+ if ((jiffies - timeout) > (1 * HZ)){
+ chdlc_priv_area->update_comms_stats = 0;
+ chdlc_priv_area->timer_int_enabled &=
+ ~TMR_INT_ENABLED_UPDATE;
+ return -EAGAIN;
+ }
+ }
+
+ return 0;
+}
+
+
+/*============================================================================
+ * Create new logical channel.
+ * This routine is called by the router when ROUTER_IFNEW IOCTL is being
+ * handled.
+ * o parse media- and hardware-specific configuration
+ * o make sure that a new channel can be created
+ * o allocate resources, if necessary
+ * o prepare network device structure for registaration.
+ *
+ * Return: 0 o.k.
+ * < 0 failure (channel will not be created)
+ */
+static int new_if (wan_device_t* wandev, struct net_device* dev, wanif_conf_t* conf)
+{
+ sdla_t* card = wandev->private;
+ chdlc_private_area_t* chdlc_priv_area;
+
+ if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) {
+ printk(KERN_INFO "%s: invalid interface name!\n",
+ card->devname);
+ return -EINVAL;
+ }
+
+ /* allocate and initialize private data */
+ chdlc_priv_area = kmalloc(sizeof(chdlc_private_area_t), GFP_KERNEL);
+
+ if(chdlc_priv_area == NULL)
+ return -ENOMEM;
+
+ memset(chdlc_priv_area, 0, sizeof(chdlc_private_area_t));
+
+ chdlc_priv_area->card = card;
+
+ /* initialize data */
+ strcpy(card->u.c.if_name, conf->name);
+
+ if(card->wandev.new_if_cnt > 0) {
+ kfree(chdlc_priv_area);
+ return -EEXIST;
+ }
+
+ card->wandev.new_if_cnt++;
+
+ chdlc_priv_area->TracingEnabled = 0;
+ chdlc_priv_area->route_status = NO_ROUTE;
+ chdlc_priv_area->route_removed = 0;
+
+ /* Setup protocol options */
+
+ card->u.c.protocol_options = 0;
+
+ if (conf->ignore_dcd == WANOPT_YES){
+ card->u.c.protocol_options |= IGNORE_DCD_FOR_LINK_STAT;
+ }
+
+ if (conf->ignore_cts == WANOPT_YES){
+ card->u.c.protocol_options |= IGNORE_CTS_FOR_LINK_STAT;
+ }
+
+ if (conf->ignore_keepalive == WANOPT_YES) {
+ card->u.c.protocol_options |= IGNORE_KPALV_FOR_LINK_STAT;
+ card->u.c.kpalv_tx = MIN_Tx_KPALV_TIMER;
+ card->u.c.kpalv_rx = MIN_Rx_KPALV_TIMER;
+ card->u.c.kpalv_err = MIN_KPALV_ERR_TOL;
+
+ } else { /* Do not ignore keepalives */
+
+ card->u.c.kpalv_tx =
+ (conf->keepalive_tx_tmr - MIN_Tx_KPALV_TIMER) >= 0 ?
+ min (conf->keepalive_tx_tmr, MAX_Tx_KPALV_TIMER) :
+ DEFAULT_Tx_KPALV_TIMER;
+
+ card->u.c.kpalv_rx =
+ (conf->keepalive_rx_tmr - MIN_Rx_KPALV_TIMER) >= 0 ?
+ min (conf->keepalive_rx_tmr, MAX_Rx_KPALV_TIMER) :
+ DEFAULT_Rx_KPALV_TIMER;
+
+ card->u.c.kpalv_err =
+ (conf->keepalive_err_margin - MIN_KPALV_ERR_TOL) >= 0 ?
+ min (conf->keepalive_err_margin, MAX_KPALV_ERR_TOL) :
+ DEFAULT_KPALV_ERR_TOL;
+ }
+
+
+ /* Setup slarp timer to control delay between slarps
+ */
+ card->u.c.slarp_timer =
+ (conf->slarp_timer - MIN_SLARP_REQ_TIMER) >=0 ?
+ min (conf->slarp_timer, MAX_SLARP_REQ_TIMER) :
+ DEFAULT_SLARP_REQ_TIMER;
+
+
+ /* If HDLC_STRAMING is enabled then IGNORE DCD, CTS and KEEPALIVES
+ * are automatically ignored
+ */
+ if (conf->hdlc_streaming == WANOPT_YES) {
+ printk(KERN_INFO "%s: Enabling HDLC STREAMING Mode\n",
+ wandev->name);
+ card->u.c.protocol_options = HDLC_STREAMING_MODE;
+ }
+
+
+ /* Setup wanpipe as a router (WANPIPE) or as an API */
+ if( strcmp(conf->usedby, "WANPIPE") == 0) {
+ printk(KERN_INFO "%s: Running in WANPIPE mode !\n",wandev->name);
+ card->u.c.usedby = WANPIPE;
+
+ } else if( strcmp(conf->usedby, "API") == 0){
+
+#ifdef CHDLC_API
+ card->u.c.usedby = API;
+ printk(KERN_INFO "%s: Running in API mode !\n",wandev->name);
+#else
+ printk(KERN_INFO "%s: API Mode is not supported!\n",
+ wandev->name);
+ printk(KERN_INFO "%s: Chdlc API patch can be obtained from Sangoma Tech.\n",
+ wandev->name);
+ kfree(chdlc_priv_area);
+ return -EINVAL;
+#endif
+ }
+
+
+ /* Get Multicast Information */
+ chdlc_priv_area->mc = conf->mc;
+
+ /* prepare network device data space for registration */
+ dev->name = card->u.c.if_name;
+ dev->init = &if_init;
+ dev->priv = chdlc_priv_area;
+
+ return 0;
+}
+
+/*============================================================================
+ * Delete logical channel.
+ */
+static int del_if (wan_device_t* wandev, struct net_device* dev)
+{
+
+/* FIXME: This code generates kernel panic during
+ router stop!. Investigate futher.
+ (Error is dereferencing a NULL pointer)
+
+ if(dev->priv){
+
+ kfree(dev->priv);
+ dev->priv = NULL;
+
+ }
+*/
+ return 0;
+}
+
+
+/****** Network Device Interface ********************************************/
+
+/*============================================================================
+ * Initialize Linux network interface.
+ *
+ * This routine is called only once for each interface, during Linux network
+ * interface registration. Returning anything but zero will fail interface
+ * registration.
+ */
+static int if_init (struct net_device* dev)
+ {
+ chdlc_private_area_t* chdlc_priv_area = dev->priv;
+ sdla_t* card = chdlc_priv_area->card;
+ wan_device_t* wandev = &card->wandev;
+#ifndef LINUX_2_1
+ int i;
+#endif
+
+ /* Initialize device driver entry points */
+ dev->open = &if_open;
+ dev->stop = &if_close;
+ dev->hard_header = &if_header;
+ dev->rebuild_header = &if_rebuild_hdr;
+ dev->hard_start_xmit = &if_send;
+ dev->get_stats = &if_stats;
+
+ /* Initialize media-specific parameters */
+ dev->flags |= IFF_POINTTOPOINT;
+
+ /* Enable Mulitcasting if user selected */
+ if (chdlc_priv_area->mc == WANOPT_YES){
+ dev->flags |= IFF_MULTICAST;
+ }
+
+#ifndef LINUX_2_1
+ dev->family = AF_INET;
+#endif
+ dev->type = ARPHRD_PPP; /* ARP hw type -- dummy value */
+ dev->mtu = card->wandev.mtu;
+ dev->hard_header_len = CHDLC_HDR_LEN;
+
+ /* Initialize hardware parameters */
+ dev->irq = wandev->irq;
+ dev->dma = wandev->dma;
+ dev->base_addr = wandev->ioport;
+ dev->mem_start = wandev->maddr;
+ dev->mem_end = wandev->maddr + wandev->msize - 1;
+
+ /* Set transmit buffer queue length
+ * If too low packets will not be retransmitted
+ * by stack.
+ */
+ dev->tx_queue_len = 100;
+
+ /* Initialize socket buffers */
+#ifdef LINUX_2_1
+ dev_init_buffers(dev);
+#else
+ for (i = 0; i < DEV_NUMBUFFS; ++i)
+ skb_queue_head_init(&dev->buffs[i]);
+#endif
+
+ return 0;
+}
+
+/*============================================================================
+ * Open network interface.
+ * o enable communications and interrupts.
+ * o prevent module from unloading by incrementing use count
+ *
+ * Return 0 if O.k. or errno.
+ */
+static int if_open (struct net_device* dev)
+{
+ chdlc_private_area_t* chdlc_priv_area = dev->priv;
+ sdla_t* card = chdlc_priv_area->card;
+ SHARED_MEMORY_INFO_STRUCT* flags = card->u.c.flags;
+ struct timeval tv;
+ int err = 0;
+
+ /* Only one open per interface is allowed */
+
+ if(dev->start)
+ return -EBUSY;
+
+ if(test_and_set_bit(1, (void*)&card->wandev.critical)) {
+ return -EAGAIN;
+ }
+
+ /* Setup the Board for CHDLC */
+ if (set_chdlc_config(card)) {
+ clear_bit(1, (void*)&card->wandev.critical);
+ return -EIO;
+ }
+
+ if (!card->configured && !card->wandev.piggyback){
+ /* Perform interrupt testing */
+ err = intr_test(card, dev);
+
+ if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) {
+ printk(KERN_ERR "%s: Interrupt test failed (%i)\n",
+ card->devname, Intr_test_counter);
+ printk(KERN_ERR "%s: Please choose another interrupt\n",
+ card->devname);
+ clear_bit(1, (void*)&card->wandev.critical);
+ return -EIO;
+ }
+
+ printk(KERN_INFO "%s: Interrupt test passed (%i)\n",
+ card->devname, Intr_test_counter);
+ card->configured = 1;
+ }else{
+ printk(KERN_INFO "%s: Card configured, skip interrupt test\n",
+ card->devname);
+ }
+
+ /* Initialize Rx/Tx buffer control fields */
+ init_chdlc_tx_rx_buff(card, dev);
+
+ /* Set interrupt mode and mask */
+ if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME |
+ APP_INT_ON_GLOBAL_EXCEP_COND |
+ APP_INT_ON_TX_FRAME |
+ APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){
+
+ clear_bit(1, (void*)&card->wandev.critical);
+ return -EIO;
+ }
+
+
+ /* Mask the Transmit and Timer interrupt */
+ flags->interrupt_info_struct.interrupt_permission &=
+ ~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER);
+
+
+ /* Enable communications */
+ if (chdlc_comm_enable(card)) {
+ clear_bit(1, (void*)&card->wandev.critical);
+ return -EIO;
+ }
+
+ clear_bit(1, (void*)&card->wandev.critical);
+
+ port_set_state(card, WAN_CONNECTING);
+ do_gettimeofday(&tv);
+ chdlc_priv_area->router_start_time = tv.tv_sec;
+
+ dev->interrupt = 0;
+ dev->tbusy = 0;
+ dev->start = 1;
+ dev->flags |= IFF_POINTTOPOINT;
+ wanpipe_open(card);
+
+ return err;
+}
+
+/*============================================================================
+ * Close network interface.
+ * o if this is the last close, then disable communications and interrupts.
+ * o reset flags.
+ */
+static int if_close (struct net_device* dev)
+{
+ chdlc_private_area_t* chdlc_priv_area = dev->priv;
+ sdla_t* card = chdlc_priv_area->card;
+
+ if(test_and_set_bit(1, (void*)&card->wandev.critical))
+ return -EAGAIN;
+
+ dev->start = 0;
+ wanpipe_close(card);
+ port_set_state(card, WAN_DISCONNECTED);
+ chdlc_set_intr_mode(card, 0);
+ chdlc_comm_disable(card);
+
+ clear_bit(1, (void*)&card->wandev.critical);
+
+ return 0;
+}
+
+/*============================================================================
+ * Build media header.
+ *
+ * The trick here is to put packet type (Ethertype) into 'protocol' field of
+ * the socket buffer, so that we don't forget it. If packet type is not
+ * supported, set skb->protocol to 0 and discard packet later.
+ *
+ * Return: media header length.
+ */
+static int if_header (struct sk_buff* skb, struct net_device* dev,
+ unsigned short type, void* daddr, void* saddr, unsigned len)
+{
+ skb->protocol = htons(type);
+
+ return CHDLC_HDR_LEN;
+}
+
+/*============================================================================
+ * Re-build media header.
+ *
+ * Return: 1 physical address resolved.
+ * 0 physical address not resolved
+ */
+#ifdef LINUX_2_1
+static int if_rebuild_hdr (struct sk_buff *skb)
+{
+ return 1;
+}
+#else
+static int if_rebuild_hdr (void* hdr, struct net_device* dev, unsigned long raddr,
+ struct sk_buff* skb)
+{
+ return 1;
+}
+#endif
+
+/*============================================================================
+ * Send a packet on a network interface.
+ * o set tbusy flag (marks start of the transmission) to block a timer-based
+ * transmit from overlapping.
+ * o check link state. If link is not up, then drop the packet.
+ * o execute adapter send command.
+ * o free socket buffer
+ *
+ * Return: 0 complete (socket buffer must be freed)
+ * non-0 packet may be re-transmitted (tbusy must be set)
+ *
+ * Notes:
+ * 1. This routine is called either by the protocol stack or by the "net
+ * bottom half" (with interrupts enabled).
+ * 2. Setting tbusy flag will inhibit further transmit requests from the
+ * protocol stack and can be used for flow control with protocol layer.
+ */
+static int if_send (struct sk_buff* skb, struct net_device* dev)
+{
+ chdlc_private_area_t *chdlc_priv_area = dev->priv;
+ sdla_t *card = chdlc_priv_area->card;
+ SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
+ INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct;
+ int udp_type = 0;
+ unsigned long smp_flags;
+
+ if(skb == NULL) {
+ /* If we get here, some higher layer thinks we've missed an
+ * tx-done interrupt.
+ */
+ printk(KERN_INFO "%s: interface %s got kicked!\n",
+ card->devname, dev->name);
+ mark_bh(NET_BH);
+ return 0;
+ }
+
+ if(dev->tbusy) {
+
+ /* If our device stays busy for at least 5 seconds then we will
+ * kick start the device by making dev->tbusy = 0. We expect
+ * that our device never stays busy more than 5 seconds. So this
+ * is only used as a last resort.
+ */
+ ++card->wandev.stats.collisions;
+
+ if((jiffies - chdlc_priv_area->tick_counter) < (5 * HZ)) {
+ return 1;
+ }
+
+ printk (KERN_INFO "%s: Transmit timeout !\n",
+ card->devname);
+
+ /* unbusy the interface */
+ dev->tbusy = 0;
+ }
+
+ if(ntohs(skb->protocol) != 0x16) {
+
+ /* check the udp packet type */
+ udp_type = udp_pkt_type(skb, card);
+ if(udp_type == UDP_CPIPE_TYPE) {
+ if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev,
+ chdlc_priv_area))
+ chdlc_int->interrupt_permission |=
+ APP_INT_ON_TIMER;
+ return 0;
+ }
+
+ /* check to see if the source IP address is a broadcast or */
+ /* multicast IP address */
+ if(chk_bcast_mcast_addr(card, dev, skb))
+ return 0;
+ }
+
+ /* Lock the 508 Card: SMP is supported */
+ if(card->hw.type != SDLA_S514){
+ s508_lock(card,&smp_flags);
+ }
+
+ if(test_and_set_bit(0, (void*)&card->wandev.critical)) {
+
+ printk(KERN_INFO "%s: Critical in if_send: %x\n",
+ card->wandev.name,card->wandev.critical);
+ ++card->wandev.stats.tx_dropped;
+#ifdef LINUX_2_1
+ dev_kfree_skb(skb);
+#else
+ dev_kfree_skb(skb, FREE_WRITE);
+#endif
+ if(card->hw.type != SDLA_S514){
+ s508_unlock(card,&smp_flags);
+ }
+ return 0;
+ }
+
+ if(card->u.c.state != WAN_CONNECTED)
+ ++card->wandev.stats.tx_dropped;
+
+ else if(!skb->protocol)
+ ++card->wandev.stats.tx_errors;
+
+ else {
+ void* data = skb->data;
+ unsigned len = skb->len;
+ unsigned char attr;
+
+ /* If it's an API packet pull off the API
+ * header. Also check that the packet size
+ * is larger than the API header
+ */
+ if (card->u.c.usedby == API){
+ api_tx_hdr_t* api_tx_hdr;
+
+ if (len <= sizeof(api_tx_hdr_t)){
+#ifdef LINUX_2_1
+ dev_kfree_skb(skb);
+#else
+ dev_kfree_skb(skb, FREE_WRITE);
+#endif
+ ++card->wandev.stats.tx_dropped;
+ clear_bit(0, (void*)&card->wandev.critical);
+ if(card->hw.type != SDLA_S514){
+ s508_unlock(card,&smp_flags);
+ }
+ return 0;
+ }
+
+ api_tx_hdr = (api_tx_hdr_t *)data;
+ attr = api_tx_hdr->attr;
+ data += sizeof(api_tx_hdr_t);
+ len -= sizeof(api_tx_hdr_t);
+ }
+
+ if(chdlc_send(card, data, len)) {
+ dev->tbusy = 1;
+ chdlc_priv_area->tick_counter = jiffies;
+ chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME;
+ }
+ else {
+ ++card->wandev.stats.tx_packets;
+#ifdef LINUX_2_1
+ card->wandev.stats.tx_bytes += len;
+#endif
+ }
+ }
+
+ if (!dev->tbusy) {
+#ifdef LINUX_2_1
+ dev_kfree_skb(skb);
+#else
+ dev_kfree_skb(skb, FREE_WRITE);
+#endif
+ }
+
+ clear_bit(0, (void*)&card->wandev.critical);
+ if(card->hw.type != SDLA_S514){
+ s508_unlock(card,&smp_flags);
+ }
+ return dev->tbusy;
+}
+
+
+/*============================================================================
+ * Check to see if the packet to be transmitted contains a broadcast or
+ * multicast source IP address.
+ */
+
+static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev,
+ struct sk_buff *skb)
+{
+ u32 src_ip_addr;
+ u32 broadcast_ip_addr = 0;
+#ifdef LINUX_2_1
+ struct in_device *in_dev;
+#endif
+ /* read the IP source address from the outgoing packet */
+ src_ip_addr = *(u32 *)(skb->data + 12);
+
+ /* read the IP broadcast address for the device */
+#ifdef LINUX_2_1
+ in_dev = dev->ip_ptr;
+ if(in_dev != NULL) {
+ struct in_ifaddr *ifa= in_dev->ifa_list;
+ if(ifa != NULL)
+ broadcast_ip_addr = ifa->ifa_broadcast;
+ else
+ return 0;
+ }
+#else
+ broadcast_ip_addr = dev->pa_brdaddr;
+#endif
+
+ /* check if the IP Source Address is a Broadcast address */
+ if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) {
+ printk(KERN_INFO "%s: Broadcast Source Address silently discarded\n",
+ card->devname);
+#ifdef LINUX_2_1
+ dev_kfree_skb(skb);
+#else
+ dev_kfree_skb(skb, FREE_WRITE);
+#endif
+ ++card->wandev.stats.tx_dropped;
+ return 1;
+ }
+
+ /* check if the IP Source Address is a Multicast address */
+ if((ntohl(src_ip_addr) >= 0xE0000001) &&
+ (ntohl(src_ip_addr) <= 0xFFFFFFFE)) {
+ printk(KERN_INFO "%s: Multicast Source Address silently discarded\n",
+ card->devname);
+#ifdef LINUX_2_1
+ dev_kfree_skb(skb);
+#else
+ dev_kfree_skb(skb, FREE_WRITE);
+#endif
+ ++card->wandev.stats.tx_dropped;
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/*============================================================================
+ * Reply to UDP Management system.
+ * Return length of reply.
+ */
+static int reply_udp( unsigned char *data, unsigned int mbox_len )
+{
+
+ unsigned short len, udp_length, temp, ip_length;
+ unsigned long ip_temp;
+ int even_bound = 0;
+ chdlc_udp_pkt_t *c_udp_pkt = (chdlc_udp_pkt_t *)data;
+
+ /* Set length of packet */
+ len = sizeof(ip_pkt_t)+
+ sizeof(udp_pkt_t)+
+ sizeof(wp_mgmt_t)+
+ sizeof(cblock_t)+
+ sizeof(trace_info_t)+
+ mbox_len;
+
+ /* fill in UDP reply */
+ c_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY;
+
+ /* fill in UDP length */
+ udp_length = sizeof(udp_pkt_t)+
+ sizeof(wp_mgmt_t)+
+ sizeof(cblock_t)+
+ sizeof(trace_info_t)+
+ mbox_len;
+
+ /* put it on an even boundary */
+ if ( udp_length & 0x0001 ) {
+ udp_length += 1;
+ len += 1;
+ even_bound = 1;
+ }
+
+ temp = (udp_length<<8)|(udp_length>>8);
+ c_udp_pkt->udp_pkt.udp_length = temp;
+
+ /* swap UDP ports */
+ temp = c_udp_pkt->udp_pkt.udp_src_port;
+ c_udp_pkt->udp_pkt.udp_src_port =
+ c_udp_pkt->udp_pkt.udp_dst_port;
+ c_udp_pkt->udp_pkt.udp_dst_port = temp;
+
+ /* add UDP pseudo header */
+ temp = 0x1100;
+ *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound)) = temp;
+ temp = (udp_length<<8)|(udp_length>>8);
+ *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound+2)) = temp;
+
+
+ /* calculate UDP checksum */
+ c_udp_pkt->udp_pkt.udp_checksum = 0;
+ c_udp_pkt->udp_pkt.udp_checksum = calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET);
+
+ /* fill in IP length */
+ ip_length = len;
+ temp = (ip_length<<8)|(ip_length>>8);
+ c_udp_pkt->ip_pkt.total_length = temp;
+
+ /* swap IP addresses */
+ ip_temp = c_udp_pkt->ip_pkt.ip_src_address;
+ c_udp_pkt->ip_pkt.ip_src_address = c_udp_pkt->ip_pkt.ip_dst_address;
+ c_udp_pkt->ip_pkt.ip_dst_address = ip_temp;
+
+ /* fill in IP checksum */
+ c_udp_pkt->ip_pkt.hdr_checksum = 0;
+ c_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t));
+
+ return len;
+
+} /* reply_udp */
+
+unsigned short calc_checksum (char *data, int len)
+{
+ unsigned short temp;
+ unsigned long sum=0;
+ int i;
+
+ for( i = 0; i <len; i+=2 ) {
+ memcpy(&temp,&data[i],2);
+ sum += (unsigned long)temp;
+ }
+
+ while (sum >> 16 ) {
+ sum = (sum & 0xffffUL) + (sum >> 16);
+ }
+
+ temp = (unsigned short)sum;
+ temp = ~temp;
+
+ if( temp == 0 )
+ temp = 0xffff;
+
+ return temp;
+}
+
+
+/*============================================================================
+ * Get ethernet-style interface statistics.
+ * Return a pointer to struct enet_statistics.
+ */
+#ifdef LINUX_2_1
+static struct net_device_stats* if_stats (struct net_device* dev)
+{
+ sdla_t *my_card;
+ chdlc_private_area_t* chdlc_priv_area = dev->priv;
+
+ my_card = chdlc_priv_area->card;
+ return &my_card->wandev.stats;
+}
+#else
+static struct enet_statistics* if_stats (struct net_device* dev)
+{
+ sdla_t *my_card;
+ chdlc_private_area_t* chdlc_priv_area = dev->priv;
+
+ my_card = chdlc_priv_area->card;
+ return &my_card->wandev.stats;
+}
+#endif
+
+/****** Cisco HDLC Firmware Interface Functions *******************************/
+
+/*============================================================================
+ * Read firmware code version.
+ * Put code version as ASCII string in str.
+ */
+static int chdlc_read_version (sdla_t* card, char* str)
+{
+ CHDLC_MAILBOX_STRUCT* mb = card->mbox;
+ int len;
+ char err;
+ mb->buffer_length = 0;
+ mb->command = READ_CHDLC_CODE_VERSION;
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+
+ if(err != COMMAND_OK) {
+ chdlc_error(card,err,mb);
+ }
+ else if (str) { /* is not null */
+ len = mb->buffer_length;
+ memcpy(str, mb->data, len);
+ str[len] = '\0';
+ }
+ return (err);
+}
+
+/*-----------------------------------------------------------------------------
+ * Configure CHDLC firmware.
+ */
+static int chdlc_configure (sdla_t* card, void* data)
+{
+ int err;
+ CHDLC_MAILBOX_STRUCT *mailbox = card->mbox;
+ int data_length = sizeof(CHDLC_CONFIGURATION_STRUCT);
+
+ mailbox->buffer_length = data_length;
+ memcpy(mailbox->data, data, data_length);
+ mailbox->command = SET_CHDLC_CONFIGURATION;
+ err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT;
+
+ if (err != COMMAND_OK) chdlc_error (card, err, mailbox);
+
+ return err;
+}
+
+
+/*============================================================================
+ * Set interrupt mode -- HDLC Version.
+ */
+
+static int chdlc_set_intr_mode (sdla_t* card, unsigned mode)
+{
+ CHDLC_MAILBOX_STRUCT* mb = card->mbox;
+ CHDLC_INT_TRIGGERS_STRUCT* int_data =
+ (CHDLC_INT_TRIGGERS_STRUCT *)mb->data;
+ int err;
+
+ int_data->CHDLC_interrupt_triggers = mode;
+ int_data->IRQ = card->hw.irq;
+ int_data->interrupt_timer = 1;
+
+ mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT);
+ mb->command = SET_CHDLC_INTERRUPT_TRIGGERS;
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+ if (err != COMMAND_OK)
+ chdlc_error (card, err, mb);
+ return err;
+}
+
+
+/*============================================================================
+ * Enable communications.
+ */
+
+static int chdlc_comm_enable (sdla_t* card)
+{
+ int err;
+ CHDLC_MAILBOX_STRUCT* mb = card->mbox;
+
+ mb->buffer_length = 0;
+ mb->command = ENABLE_CHDLC_COMMUNICATIONS;
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+ if (err != COMMAND_OK)
+ chdlc_error(card, err, mb);
+ return err;
+}
+
+/*============================================================================
+ * Disable communications and Drop the Modem lines (DCD and RTS).
+ */
+static int chdlc_comm_disable (sdla_t* card)
+{
+ int err;
+ CHDLC_MAILBOX_STRUCT* mb = card->mbox;
+
+ mb->buffer_length = 0;
+ mb->command = DISABLE_CHDLC_COMMUNICATIONS;
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+ if (err != COMMAND_OK)
+ chdlc_error(card,err,mb);
+
+ mb->command = SET_MODEM_STATUS;
+ mb->buffer_length = 1;
+ mb->data[0] = 0;
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+ if (err != COMMAND_OK)
+ chdlc_error(card,err,mb);
+
+ return err;
+}
+
+/*============================================================================
+ * Read communication error statistics.
+ */
+static int chdlc_read_comm_err_stats (sdla_t* card)
+{
+ int err;
+ CHDLC_MAILBOX_STRUCT* mb = card->mbox;
+
+ mb->buffer_length = 0;
+ mb->command = READ_COMMS_ERROR_STATS;
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+ if (err != COMMAND_OK)
+ chdlc_error(card,err,mb);
+ return err;
+}
+
+
+/*============================================================================
+ * Read CHDLC operational statistics.
+ */
+static int chdlc_read_op_stats (sdla_t* card)
+{
+ int err;
+ CHDLC_MAILBOX_STRUCT* mb = card->mbox;
+
+ mb->buffer_length = 0;
+ mb->command = READ_CHDLC_OPERATIONAL_STATS;
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+ if (err != COMMAND_OK)
+ chdlc_error(card,err,mb);
+ return err;
+}
+
+
+/*============================================================================
+ * Update communications error and general packet statistics.
+ */
+static int update_comms_stats(sdla_t* card,
+ chdlc_private_area_t* chdlc_priv_area)
+{
+ CHDLC_MAILBOX_STRUCT* mb = card->mbox;
+ COMMS_ERROR_STATS_STRUCT* err_stats;
+ CHDLC_OPERATIONAL_STATS_STRUCT *op_stats;
+
+ /* on the first timer interrupt, read the comms error statistics */
+ if(chdlc_priv_area->update_comms_stats == 2) {
+ if(chdlc_read_comm_err_stats(card))
+ return 1;
+ err_stats = (COMMS_ERROR_STATS_STRUCT *)mb->data;
+ card->wandev.stats.rx_over_errors =
+ err_stats->Rx_overrun_err_count;
+ card->wandev.stats.rx_crc_errors =
+ err_stats->CRC_err_count;
+ card->wandev.stats.rx_frame_errors =
+ err_stats->Rx_abort_count;
+ card->wandev.stats.rx_fifo_errors =
+ err_stats->Rx_dis_pri_bfrs_full_count;
+ card->wandev.stats.rx_missed_errors =
+ card->wandev.stats.rx_fifo_errors;
+ card->wandev.stats.tx_aborted_errors =
+ err_stats->sec_Tx_abort_count;
+ }
+
+ /* on the second timer interrupt, read the operational statistics */
+ else {
+ if(chdlc_read_op_stats(card))
+ return 1;
+ op_stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)mb->data;
+ card->wandev.stats.rx_length_errors =
+ (op_stats->Rx_Data_discard_short_count +
+ op_stats->Rx_Data_discard_long_count);
+ }
+
+ return 0;
+}
+
+/*============================================================================
+ * Send packet.
+ * Return: 0 - o.k.
+ * 1 - no transmit buffers available
+ */
+static int chdlc_send (sdla_t* card, void* data, unsigned len)
+{
+ CHDLC_DATA_TX_STATUS_EL_STRUCT *txbuf = card->u.c.txbuf;
+
+ if (txbuf->opp_flag)
+ return 1;
+
+ sdla_poke(&card->hw, txbuf->ptr_data_bfr, data, len);
+
+ txbuf->frame_length = len;
+ txbuf->opp_flag = 1; /* start transmission */
+
+ /* Update transmit buffer control fields */
+ card->u.c.txbuf = ++txbuf;
+
+ if ((void*)txbuf > card->u.c.txbuf_last)
+ card->u.c.txbuf = card->u.c.txbuf_base;
+
+ return 0;
+}
+
+/****** Firmware Error Handler **********************************************/
+
+/*============================================================================
+ * Firmware error handler.
+ * This routine is called whenever firmware command returns non-zero
+ * return code.
+ *
+ * Return zero if previous command has to be cancelled.
+ */
+static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb)
+{
+ unsigned cmd = mb->command;
+
+ switch (err) {
+
+ case CMD_TIMEOUT:
+ printk(KERN_ERR "%s: command 0x%02X timed out!\n",
+ card->devname, cmd);
+ break;
+
+ case S514_BOTH_PORTS_SAME_CLK_MODE:
+ if(cmd == SET_CHDLC_CONFIGURATION) {
+ printk(KERN_INFO
+ "%s: Configure both ports for the same clock source\n",
+ card->devname);
+ break;
+ }
+
+ default:
+ printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n",
+ card->devname, cmd, err);
+ }
+
+ return 0;
+}
+
+/****** Interrupt Handlers **************************************************/
+
+/*============================================================================
+ * Cisco HDLC interrupt service routine.
+ */
+STATIC void wpc_isr (sdla_t* card)
+{
+ struct net_device* dev;
+ chdlc_private_area_t* chdlc_priv_area;
+ SHARED_MEMORY_INFO_STRUCT* flags = NULL;
+ int i, interrupt_serviced = 0;
+ sdla_t *my_card;
+
+
+ /* Check for which port the interrupt has been generated
+ * Since Secondary Port is piggybacking on the Primary
+ * the check must be done here.
+ */
+
+ flags = card->u.c.flags;
+ if (!flags->interrupt_info_struct.interrupt_type){
+ /* Check for a second port (piggybacking) */
+ if((my_card = card->next)){
+ flags = my_card->u.c.flags;
+ if (flags->interrupt_info_struct.interrupt_type){
+ card = my_card;
+ }
+ }
+ }
+
+ dev = card->wandev.dev;
+
+ card->in_isr = 1;
+
+ /* if critical due to peripheral operations
+ * ie. update() or getstats() then reset the interrupt and
+ * wait for the board to retrigger.
+ */
+ if(test_bit(1, (void*)&card->wandev.critical)) {
+ if(card->u.c.flags != NULL) {
+ flags = card->u.c.flags;
+ if(flags->interrupt_info_struct.
+ interrupt_type) {
+ flags->interrupt_info_struct.
+ interrupt_type = 0;
+ }
+ }
+ card->in_isr = 0;
+ return;
+ }
+
+
+ /* On a 508 Card, if critical due to if_send
+ * Major Error !!!
+ */
+ if(card->hw.type != SDLA_S514) {
+ if(test_and_set_bit(0, (void*)&card->wandev.critical)) {
+ printk(KERN_INFO "%s: Critical while in ISR: %x\n",
+ card->devname, card->wandev.critical);
+ card->in_isr = 0;
+ return;
+ }
+ }
+
+ /* FIXME: Take this check out later in the future */
+ if(card->u.c.flags != NULL) {
+
+ flags = card->u.c.flags;
+
+ switch(flags->interrupt_info_struct.interrupt_type) {
+
+ case RX_APP_INT_PEND: /* 0x01: receive interrupt */
+ interrupt_serviced = 1;
+ rx_intr(card);
+ break;
+
+ case TX_APP_INT_PEND: /* 0x02: transmit interrupt */
+ interrupt_serviced = 1;
+ flags->interrupt_info_struct.interrupt_permission &=
+ ~APP_INT_ON_TX_FRAME;
+
+ chdlc_priv_area = dev->priv;
+ dev->tbusy = 0;
+ mark_bh(NET_BH);
+ break;
+
+ case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */
+ interrupt_serviced = 1;
+ ++ Intr_test_counter;
+ break;
+
+ case CHDLC_EXCEP_COND_APP_INT_PEND: /* 0x20 */
+ interrupt_serviced = 1;
+ process_chdlc_exception(card);
+ break;
+
+ case GLOBAL_EXCEP_COND_APP_INT_PEND:
+ interrupt_serviced = 1;
+ process_global_exception(card);
+ break;
+
+ case TIMER_APP_INT_PEND:
+ interrupt_serviced = 1;
+ timer_intr(card);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if(!interrupt_serviced) {
+ printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n",
+ card->devname,
+ flags->interrupt_info_struct.interrupt_type);
+ printk(KERN_INFO "Code name: ");
+ for(i = 0; i < 4; i ++)
+ printk(KERN_INFO "%c",
+ flags->global_info_struct.codename[i]);
+ printk(KERN_INFO "\nCode version: ");
+ for(i = 0; i < 4; i ++)
+ printk(KERN_INFO "%c",
+ flags->global_info_struct.codeversion[i]);
+ printk(KERN_INFO "\n");
+ }
+
+ card->in_isr = 0;
+ flags->interrupt_info_struct.interrupt_type = 0;
+ if(card->hw.type != SDLA_S514){
+ clear_bit(0, (void*)&card->wandev.critical);
+ }
+
+}
+
+/*============================================================================
+ * Receive interrupt handler.
+ */
+static void rx_intr (sdla_t* card)
+{
+ struct net_device *dev;
+ chdlc_private_area_t *chdlc_priv_area;
+ SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
+ CHDLC_DATA_RX_STATUS_EL_STRUCT *rxbuf = card->u.c.rxmb;
+ struct sk_buff *skb;
+ unsigned len;
+ void *buf;
+ int i,udp_type;
+
+ if (rxbuf->opp_flag != 0x01) {
+ printk(KERN_INFO
+ "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n",
+ card->devname, (unsigned)rxbuf, rxbuf->opp_flag);
+ printk(KERN_INFO "Code name: ");
+ for(i = 0; i < 4; i ++)
+ printk(KERN_INFO "%c",
+ flags->global_info_struct.codename[i]);
+ printk(KERN_INFO "\nCode version: ");
+ for(i = 0; i < 4; i ++)
+ printk(KERN_INFO "%c",
+ flags->global_info_struct.codeversion[i]);
+ printk(KERN_INFO "\n");
+ return;
+ }
+
+ dev = card->wandev.dev;
+ chdlc_priv_area = dev->priv;
+
+ if(dev && dev->start) {
+
+ len = rxbuf->frame_length;
+
+ /* Allocate socket buffer */
+ skb = dev_alloc_skb(len);
+
+ if (skb != NULL) {
+ /* Copy data to the socket buffer */
+ unsigned addr = rxbuf->ptr_data_bfr;
+
+ if((addr + len) >
+ card->u.c.rx_top + 1) {
+ unsigned tmp =
+ card->u.c.rx_top - addr + 1;
+ buf = skb_put(skb, tmp);
+ sdla_peek(&card->hw, addr, buf, tmp);
+ addr = card->u.c.rx_base;
+ len -= tmp;
+ }
+
+ buf = skb_put(skb, len);
+ sdla_peek(&card->hw, addr, buf, len);
+
+ /* Decapsulate packet */
+ skb->protocol = htons(ETH_P_IP);
+
+ card->wandev.stats.rx_packets ++;
+#ifdef LINUX_2_1
+ card->wandev.stats.rx_bytes += skb->len;
+#endif
+ udp_type = udp_pkt_type( skb, card );
+
+ if(udp_type == UDP_CPIPE_TYPE) {
+ if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK,
+ card, skb, dev, chdlc_priv_area)) {
+ flags->interrupt_info_struct.
+ interrupt_permission |=
+ APP_INT_ON_TIMER;
+ }
+
+ } else {
+
+ if(card->u.c.usedby == API) {
+ api_rx_hdr_t* api_rx_hdr;
+ skb_push(skb, sizeof(api_rx_hdr_t));
+ api_rx_hdr =
+ (api_rx_hdr_t*)&skb->data[0x00];
+ api_rx_hdr->error_flag =
+ rxbuf->error_flag;
+ api_rx_hdr->time_stamp =
+ rxbuf->time_stamp;
+ skb->protocol = htons(0x16);
+ skb->pkt_type = PACKET_HOST;
+ }
+
+/* FIXME: we should check to see if the received packet is a multicast packet so that we can increment the multicast statistic
+ ++ chdlc_priv_area->if_stats.multicast;
+*/
+ /* Pass it up the protocol stack */
+ skb->dev = dev;
+ skb->mac.raw = skb->data;
+ netif_rx(skb);
+ }
+
+ } else {
+ printk(KERN_INFO
+ "%s: no socket buffers available!\n",
+ card->devname);
+ ++card->wandev.stats.rx_dropped;
+ }
+ }
+
+ /* Release buffer element and calculate a pointer to the next one */
+ rxbuf->opp_flag = 0x00;
+ card->u.c.rxmb = ++ rxbuf;
+ if((void*)rxbuf > card->u.c.rxbuf_last)
+ card->u.c.rxmb = card->u.c.rxbuf_base;
+}
+
+/*============================================================================
+ * Timer interrupt handler.
+ * The timer interrupt is used for two purposes:
+ * 1) Processing udp calls from 'cpipemon'.
+ * 2) Reading board-level statistics for updating the proc file system.
+ */
+void timer_intr(sdla_t *card)
+{
+ struct net_device* dev;
+ chdlc_private_area_t* chdlc_priv_area = NULL;
+ SHARED_MEMORY_INFO_STRUCT* flags = NULL;
+
+ dev = card->wandev.dev;
+ chdlc_priv_area = dev->priv;
+
+ /* process a udp call if pending */
+ if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP) {
+ process_udp_mgmt_pkt(card, dev,
+ chdlc_priv_area);
+ chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP;
+ }
+
+ /* read the communications statistics if required */
+ if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE) {
+ update_comms_stats(card, chdlc_priv_area);
+ if(!(-- chdlc_priv_area->update_comms_stats)) {
+ chdlc_priv_area->timer_int_enabled &=
+ ~TMR_INT_ENABLED_UPDATE;
+ }
+ }
+
+ /* only disable the timer interrupt if there are no udp or statistic */
+ /* updates pending */
+ if(!chdlc_priv_area->timer_int_enabled) {
+ flags = card->u.c.flags;
+ flags->interrupt_info_struct.interrupt_permission &=
+ ~APP_INT_ON_TIMER;
+ }
+}
+
+/*------------------------------------------------------------------------------
+ Miscellaneous Functions
+ - set_chdlc_config() used to set configuration options on the board
+------------------------------------------------------------------------------*/
+
+static int set_chdlc_config(sdla_t* card)
+{
+
+ struct net_device * dev = card->wandev.dev;
+ chdlc_private_area_t *chdlc_priv_area = dev->priv;
+ CHDLC_CONFIGURATION_STRUCT cfg;
+
+ memset(&cfg, 0, sizeof(CHDLC_CONFIGURATION_STRUCT));
+
+ if(card->wandev.clocking)
+ cfg.baud_rate = card->wandev.bps;
+
+ cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
+ INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
+
+ cfg.modem_config_options = 0;
+ cfg.modem_status_timer = 100;
+
+ cfg.CHDLC_protocol_options = card->u.c.protocol_options;
+ cfg.percent_data_buffer_for_Tx = 50;
+ cfg.CHDLC_statistics_options = (CHDLC_TX_DATA_BYTE_COUNT_STAT |
+ CHDLC_RX_DATA_BYTE_COUNT_STAT);
+ cfg.max_CHDLC_data_field_length = card->wandev.mtu;
+ cfg.transmit_keepalive_timer = card->u.c.kpalv_tx;
+ cfg.receive_keepalive_timer = card->u.c.kpalv_rx;
+ cfg.keepalive_error_tolerance = card->u.c.kpalv_err;
+ cfg.SLARP_request_timer = card->u.c.slarp_timer;
+
+ if (cfg.SLARP_request_timer) {
+ cfg.IP_address = 0;
+ cfg.IP_netmask = 0;
+ }
+ else {
+#ifdef LINUX_2_1
+ struct in_device *in_dev = dev->ip_ptr;
+
+ if(in_dev != NULL) {
+ struct in_ifaddr *ifa = in_dev->ifa_list;
+
+ if (ifa != NULL ) {
+ cfg.IP_address = ntohl(ifa->ifa_local);
+ cfg.IP_netmask = ntohl(ifa->ifa_mask);
+ chdlc_priv_area->IP_address =
+ ntohl(ifa->ifa_local);
+ chdlc_priv_area->IP_netmask =
+ ntohl(ifa->ifa_mask);
+ }
+ }
+#else
+ cfg.IP_address = ntohl(dev->pa_addr);
+ cfg.IP_netmask = ntohl(dev->pa_mask);
+ chdlc_priv_area->IP_address = ntohl(dev->pa_addr);
+ chdlc_priv_area->IP_netmask = ntohl(dev->pa_mask);
+#endif
+
+ /* FIXME: We must re-think this message in next release
+ if((cfg.IP_address & 0x000000FF) > 2) {
+ printk(KERN_WARNING "\n");
+ printk(KERN_WARNING " WARNING:%s configured with an\n",
+ card->devname);
+ printk(KERN_WARNING " invalid local IP address.\n");
+ printk(KERN_WARNING " Slarp pragmatics will fail.\n");
+ printk(KERN_WARNING " IP address should be of the\n");
+ printk(KERN_WARNING " format A.B.C.1 or A.B.C.2.\n");
+ }
+ */
+ }
+
+ return chdlc_configure(card, &cfg);
+}
+
+
+
+/*============================================================================
+ * Process global exception condition
+ */
+static int process_global_exception(sdla_t *card)
+{
+ CHDLC_MAILBOX_STRUCT* mbox = card->mbox;
+ int err;
+
+ mbox->buffer_length = 0;
+ mbox->command = READ_GLOBAL_EXCEPTION_CONDITION;
+ err = sdla_exec(mbox) ? mbox->return_code : CMD_TIMEOUT;
+
+ if(err != CMD_TIMEOUT ){
+
+ switch(mbox->return_code) {
+
+ case EXCEP_MODEM_STATUS_CHANGE:
+
+ printk(KERN_INFO "%s: Modem status change\n",
+ card->devname);
+
+ switch(mbox->data[0] & (DCD_HIGH | CTS_HIGH)) {
+ case (DCD_HIGH):
+ printk(KERN_INFO "%s: DCD high, CTS low\n",card->devname);
+ break;
+ case (CTS_HIGH):
+ printk(KERN_INFO "%s: DCD low, CTS high\n",card->devname); break;
+ case ((DCD_HIGH | CTS_HIGH)):
+ printk(KERN_INFO "%s: DCD high, CTS high\n",card->devname);
+ break;
+ default:
+ printk(KERN_INFO "%s: DCD low, CTS low\n",card->devname);
+ break;
+ }
+ break;
+
+ case EXCEP_TRC_DISABLED:
+ printk(KERN_INFO "%s: Line trace disabled\n",
+ card->devname);
+ break;
+
+ case EXCEP_IRQ_TIMEOUT:
+ printk(KERN_INFO "%s: IRQ timeout occurred\n",
+ card->devname);
+ break;
+
+ default:
+ printk(KERN_INFO "%s: Global exception %x\n",
+ card->devname, mbox->return_code);
+ break;
+ }
+ }
+ return 0;
+}
+
+
+/*============================================================================
+ * Process chdlc exception condition
+ */
+static int process_chdlc_exception(sdla_t *card)
+{
+ CHDLC_MAILBOX_STRUCT* mb = card->mbox;
+ int err;
+
+ mb->buffer_length = 0;
+ mb->command = READ_CHDLC_EXCEPTION_CONDITION;
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+ if(err != CMD_TIMEOUT) {
+
+ switch (err) {
+
+ case EXCEP_LINK_ACTIVE:
+ port_set_state(card, WAN_CONNECTED);
+ break;
+
+ case EXCEP_LINK_INACTIVE_MODEM:
+ port_set_state(card, WAN_DISCONNECTED);
+ unconfigure_ip(card);
+ break;
+
+ case EXCEP_LINK_INACTIVE_KPALV:
+ port_set_state(card, WAN_DISCONNECTED);
+ printk(KERN_INFO "%s: Keepalive timer expired.\n",
+ card->devname);
+ unconfigure_ip(card);
+ break;
+
+ case EXCEP_IP_ADDRESS_DISCOVERED:
+ if (configure_ip(card))
+ return -1;
+ break;
+
+ case EXCEP_LOOPBACK_CONDITION:
+ printk(KERN_INFO "%s: Loopback Condition Detected.\n",
+ card->devname);
+ break;
+
+ case NO_CHDLC_EXCEP_COND_TO_REPORT:
+ printk(KERN_INFO "%s: No exceptions reported.\n",
+ card->devname);
+ break;
+ }
+
+ }
+ return 0;
+}
+
+
+/*============================================================================
+ * Configure IP from SLARP negotiation
+ * This adds dynamic routes when SLARP has provided valid addresses
+ */
+
+static int configure_ip (sdla_t* card)
+{
+ struct net_device *dev = card->wandev.dev;
+ chdlc_private_area_t *chdlc_priv_area = dev->priv;
+ char err;
+
+ /* set to discover */
+ if(card->u.c.slarp_timer != 0x00) {
+ CHDLC_MAILBOX_STRUCT* mb = card->mbox;
+ CHDLC_CONFIGURATION_STRUCT *cfg;
+
+ mb->buffer_length = 0;
+ mb->command = READ_CHDLC_CONFIGURATION;
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+
+ if(err != COMMAND_OK) {
+ chdlc_error(card,err,mb);
+ return -1;
+ }
+
+ cfg = (CHDLC_CONFIGURATION_STRUCT *)mb->data;
+ chdlc_priv_area->IP_address = cfg->IP_address;
+ chdlc_priv_area->IP_netmask = cfg->IP_netmask;
+ }
+
+ /* Set flag to add route */
+ chdlc_priv_area->route_status = ADD_ROUTE;
+
+ /* The idea here is to add the route in the poll routine.
+ This way, we aren't in interrupt context when adding routes */
+ card->poll = process_route;
+
+ return 0;
+}
+
+
+/*============================================================================
+ * Un-Configure IP negotiated by SLARP
+ * This removes dynamic routes when the link becomes inactive.
+ */
+
+static int unconfigure_ip (sdla_t* card)
+{
+ struct net_device *dev = card->wandev.dev;
+ chdlc_private_area_t *chdlc_priv_area= dev->priv;
+
+ if (chdlc_priv_area->route_status == ROUTE_ADDED) {
+ chdlc_priv_area->route_status = REMOVE_ROUTE;
+ /* The idea here is to delete the route in
+ * the poll routine.
+ * This way, we aren't in interrupt context
+ * when adding routes
+ */
+ card->poll = process_route;
+ }
+ return 0;
+}
+
+/*============================================================================
+ * Routine to add/remove routes
+ * Called like a polling routine when Routes are flagged to be added/removed.
+ */
+
+static void process_route (sdla_t *card)
+{
+ struct net_device *dev = card->wandev.dev;
+ unsigned char port_num;
+ chdlc_private_area_t *chdlc_priv_area = NULL;
+ u32 local_IP_addr = 0;
+ u32 remote_IP_addr = 0;
+ u32 IP_netmask, IP_addr;
+ int err = 0;
+#ifdef LINUX_2_1
+ struct in_device *in_dev;
+ mm_segment_t fs;
+ struct ifreq if_info;
+ struct sockaddr_in *if_data1, *if_data2;
+#else
+ unsigned long fs = 0;
+ struct rtentry route;
+#endif
+
+ chdlc_priv_area = dev->priv;
+ port_num = card->u.c.comm_port;
+
+ if((chdlc_priv_area->route_status == ADD_ROUTE) &&
+ ((chdlc_priv_area->IP_address & 0x000000FF) > 2)) {
+ printk(KERN_INFO "%s: Dynamic route failure.\n",card->devname);
+ if(card->u.c.slarp_timer) {
+ printk(KERN_INFO "%s: Bad IP address %s received\n",
+ card->devname,
+ in_ntoa(ntohl(chdlc_priv_area->IP_address)));
+ printk(KERN_INFO "%s: from remote station.\n",
+ card->devname);
+ }else{
+ printk(KERN_INFO "%s: Bad IP address %s issued\n",
+ card->devname,
+ in_ntoa(ntohl(chdlc_priv_area->IP_address)));
+ printk(KERN_INFO "%s: to remote station. Local\n",
+ card->devname);
+ printk(KERN_INFO "%s: IP address must be A.B.C.1\n",
+ card->devname);
+ printk(KERN_INFO "%s: or A.B.C.2.\n",card->devname);
+ }
+
+ /* remove the route due to the IP address error condition */
+ chdlc_priv_area->route_status = REMOVE_ROUTE;
+ err = 1;
+ }
+
+ /* If we are removing a route with bad IP addressing, then use the */
+ /* locally configured IP addresses */
+ if((chdlc_priv_area->route_status == REMOVE_ROUTE) && err) {
+
+ /* do not remove a bad route that has already been removed */
+ if(chdlc_priv_area->route_removed) {
+ card->poll = NULL;
+ return;
+ }
+
+#ifdef LINUX_2_1
+ in_dev = dev->ip_ptr;
+
+ if(in_dev != NULL) {
+ struct in_ifaddr *ifa = in_dev->ifa_list;
+ if (ifa != NULL ) {
+ local_IP_addr = ifa->ifa_local;
+ IP_netmask = ifa->ifa_mask;
+ }
+ }
+#else
+ local_IP_addr = dev->pa_addr;
+ remote_IP_addr = dev->pa_dstaddr;
+ IP_netmask = dev->pa_mask;
+#endif
+ }else{
+ /* According to Cisco HDLC, if the point-to-point address is
+ A.B.C.1, then we are the opposite (A.B.C.2), and vice-versa.
+ */
+ IP_netmask = ntohl(chdlc_priv_area->IP_netmask);
+ remote_IP_addr = ntohl(chdlc_priv_area->IP_address);
+ local_IP_addr = (remote_IP_addr & ntohl(0xFFFFFF00)) +
+ (~remote_IP_addr & ntohl(0x0003));
+
+ if(!card->u.c.slarp_timer) {
+ IP_addr = local_IP_addr;
+ local_IP_addr = remote_IP_addr;
+ remote_IP_addr = IP_addr;
+ }
+ }
+
+ fs = get_fs(); /* Save file system */
+ set_fs(get_ds()); /* Get user space block */
+
+#ifdef LINUX_2_1
+ /* Setup a structure for adding/removing routes */
+ memset(&if_info, 0, sizeof(if_info));
+ strcpy(if_info.ifr_name, dev->name);
+
+#else
+ /* Setup a structure for adding/removing routes */
+ dev->pa_mask = IP_netmask;
+ dev->pa_dstaddr = remote_IP_addr;
+ dev->pa_addr = local_IP_addr;
+
+ memset(&route, 0, sizeof(route));
+ route.rt_dev = dev->name;
+ route.rt_flags = 0;
+ ((struct sockaddr_in *)&(route.rt_dst))->sin_addr.s_addr =
+ dev->pa_dstaddr;
+ ((struct sockaddr_in *)&(route.rt_dst))->sin_family = AF_INET;
+ ((struct sockaddr_in *)&(route.rt_genmask))->sin_addr.s_addr =
+ 0xFFFFFFFF;
+ ((struct sockaddr_in *)&(route.rt_genmask))->sin_family =
+ AF_INET;
+#endif
+
+ switch (chdlc_priv_area->route_status) {
+
+ case ADD_ROUTE:
+
+ if(!card->u.c.slarp_timer) {
+#ifdef LINUX_2_1
+ if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
+ if_data2->sin_addr.s_addr = remote_IP_addr;
+ if_data2->sin_family = AF_INET;
+ err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
+#else
+ err = ip_rt_new(&route);
+#endif
+ } else {
+#ifdef LINUX_2_1
+ if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
+ if_data1->sin_addr.s_addr = local_IP_addr;
+ if_data1->sin_family = AF_INET;
+ if(!(err = devinet_ioctl(SIOCSIFADDR, &if_info))){
+ if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
+ if_data2->sin_addr.s_addr = remote_IP_addr;
+ if_data2->sin_family = AF_INET;
+ err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
+ }
+#else
+ err = ip_rt_new(&route);
+#endif
+ }
+
+ if(err) {
+ printk(KERN_INFO "%s: Add route %s failed (%d)\n",
+ card->devname, in_ntoa(remote_IP_addr), err);
+ } else {
+ ((chdlc_private_area_t *)dev->priv)->route_status = ROUTE_ADDED;
+ printk(KERN_INFO "%s: Dynamic route added.\n",
+ card->devname);
+ printk(KERN_INFO "%s: Local IP addr : %s\n",
+ card->devname, in_ntoa(local_IP_addr));
+ printk(KERN_INFO "%s: Remote IP addr: %s\n",
+ card->devname, in_ntoa(remote_IP_addr));
+ chdlc_priv_area->route_removed = 0;
+ }
+ break;
+
+
+ case REMOVE_ROUTE:
+
+#ifdef LINUX_2_1
+ /* Change the local ip address of the interface to 0.
+ * This will also delete the destination route.
+ */
+ if(!card->u.c.slarp_timer) {
+ if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
+ if_data2->sin_addr.s_addr = 0;
+ if_data2->sin_family = AF_INET;
+ err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
+ } else {
+ if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
+ if_data1->sin_addr.s_addr = 0;
+ if_data1->sin_family = AF_INET;
+ err = devinet_ioctl(SIOCSIFADDR,&if_info);
+
+ }
+#else
+ /* set the point-to-point IP address to 0.0.0.0 */
+ dev->pa_dstaddr = 0;
+ err = ip_rt_kill(&route);
+#endif
+ if(err) {
+ printk(KERN_INFO
+ "%s: Remove route %s failed, (err %d)\n",
+ card->devname, in_ntoa(remote_IP_addr),
+ err);
+ } else {
+ ((chdlc_private_area_t *)dev->priv)->route_status =
+ NO_ROUTE;
+ printk(KERN_INFO "%s: Dynamic route removed: %s\n",
+ card->devname, in_ntoa(local_IP_addr));
+ chdlc_priv_area->route_removed = 1;
+ }
+ break;
+ }
+
+ set_fs(fs); /* Restore file system */
+
+ /* Once we've processed the route, stop polling */
+ card->poll = NULL;
+
+}
+
+
+/*=============================================================================
+ * Store a UDP management packet for later processing.
+ */
+
+static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
+ struct sk_buff *skb, struct net_device* dev,
+ chdlc_private_area_t* chdlc_priv_area )
+{
+ int udp_pkt_stored = 0;
+
+ if(!chdlc_priv_area->udp_pkt_lgth &&
+ (skb->len <= MAX_LGTH_UDP_MGNT_PKT)) {
+ chdlc_priv_area->udp_pkt_lgth = skb->len;
+ chdlc_priv_area->udp_pkt_src = udp_pkt_src;
+ memcpy(chdlc_priv_area->udp_pkt_data, skb->data, skb->len);
+ chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UDP;
+ udp_pkt_stored = 1;
+ }
+
+#ifdef LINUX_2_1
+ dev_kfree_skb(skb);
+#else
+ if(udp_pkt_src == UDP_PKT_FRM_STACK)
+ dev_kfree_skb(skb, FREE_WRITE);
+ else
+ dev_kfree_skb(skb, FREE_READ);
+#endif
+
+ return(udp_pkt_stored);
+}
+
+
+/*=============================================================================
+ * Process UDP management packet.
+ */
+
+static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev,
+ chdlc_private_area_t* chdlc_priv_area )
+{
+ unsigned char *buf;
+ unsigned int frames, len;
+ struct sk_buff *new_skb;
+ unsigned short buffer_length, real_len;
+ unsigned long data_ptr;
+ unsigned data_length;
+ int udp_mgmt_req_valid = 1;
+ CHDLC_MAILBOX_STRUCT *mb = card->mbox;
+ SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
+ chdlc_udp_pkt_t *chdlc_udp_pkt;
+ struct timeval tv;
+ int err;
+ char ut_char;
+
+ chdlc_udp_pkt = (chdlc_udp_pkt_t *) chdlc_priv_area->udp_pkt_data;
+
+ switch(chdlc_udp_pkt->cblock.command) {
+
+ case FT1_MONITOR_STATUS_CTRL:
+ case CPIPE_ENABLE_TRACING:
+ case CPIPE_DISABLE_TRACING:
+ case CPIPE_GET_TRACE_INFO:
+ case SET_FT1_MODE:
+ if(chdlc_priv_area->udp_pkt_src ==
+ UDP_PKT_FRM_NETWORK) {
+ udp_mgmt_req_valid = 0;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if(!udp_mgmt_req_valid) {
+
+ /* set length to 0 */
+ chdlc_udp_pkt->cblock.buffer_length = 0;
+
+ /* set return code */
+ chdlc_udp_pkt->cblock.return_code = 0xCD;
+
+ } else {
+ unsigned long trace_status_cfg_addr = 0;
+ TRACE_STATUS_EL_CFG_STRUCT trace_cfg_struct;
+ TRACE_STATUS_ELEMENT_STRUCT trace_element_struct;
+
+ switch(chdlc_udp_pkt->cblock.command) {
+
+ case CPIPE_ENABLE_TRACING:
+ if (!chdlc_priv_area->TracingEnabled) {
+
+ /* OPERATE_DATALINE_MONITOR */
+
+ mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
+ mb->command = SET_TRACE_CONFIGURATION;
+
+ ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
+ trace_config = TRACE_ACTIVE;
+ /* Trace delay mode is not used because it slows
+ down transfer and results in a standoff situation
+ when there is a lot of data */
+
+ /* Configure the Trace based on user inputs */
+ ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |=
+ chdlc_udp_pkt->data[0];
+
+ ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
+ trace_deactivation_timer = 4000;
+
+
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+ if (err != COMMAND_OK) {
+ chdlc_error(card,err,mb);
+ card->TracingEnabled = 0;
+ chdlc_udp_pkt->cblock.return_code = err;
+ mb->buffer_length = 0;
+ break;
+ }
+
+ /* Get the base address of the trace element list */
+ mb->buffer_length = 0;
+ mb->command = READ_TRACE_CONFIGURATION;
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+
+ if (err != COMMAND_OK) {
+ chdlc_error(card,err,mb);
+ chdlc_priv_area->TracingEnabled = 0;
+ chdlc_udp_pkt->cblock.return_code = err;
+ mb->buffer_length = 0;
+ break;
+ }
+
+ trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *)
+ mb->data) -> ptr_trace_stat_el_cfg_struct;
+
+ sdla_peek(&card->hw, trace_status_cfg_addr,
+ &trace_cfg_struct, sizeof(trace_cfg_struct));
+
+ chdlc_priv_area->start_trace_addr = trace_cfg_struct.
+ base_addr_trace_status_elements;
+
+ chdlc_priv_area->number_trace_elements =
+ trace_cfg_struct.number_trace_status_elements;
+
+ chdlc_priv_area->end_trace_addr = (unsigned long)
+ ((TRACE_STATUS_ELEMENT_STRUCT *)
+ chdlc_priv_area->start_trace_addr +
+ (chdlc_priv_area->number_trace_elements - 1));
+
+ chdlc_priv_area->base_addr_trace_buffer =
+ trace_cfg_struct.base_addr_trace_buffer;
+
+ chdlc_priv_area->end_addr_trace_buffer =
+ trace_cfg_struct.end_addr_trace_buffer;
+
+ chdlc_priv_area->curr_trace_addr =
+ trace_cfg_struct.next_trace_element_to_use;
+
+ chdlc_priv_area->available_buffer_space = 2000 -
+ sizeof(ip_pkt_t) -
+ sizeof(udp_pkt_t) -
+ sizeof(wp_mgmt_t) -
+ sizeof(cblock_t) -
+ sizeof(trace_info_t);
+ }
+ chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
+ mb->buffer_length = 0;
+ chdlc_priv_area->TracingEnabled = 1;
+ break;
+
+
+ case CPIPE_DISABLE_TRACING:
+ if (chdlc_priv_area->TracingEnabled) {
+
+ /* OPERATE_DATALINE_MONITOR */
+ mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
+ mb->command = SET_TRACE_CONFIGURATION;
+ ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
+ trace_config = TRACE_INACTIVE;
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+ }
+
+ chdlc_priv_area->TracingEnabled = 0;
+ chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
+ mb->buffer_length = 0;
+ break;
+
+
+ case CPIPE_GET_TRACE_INFO:
+
+ if (!chdlc_priv_area->TracingEnabled) {
+ chdlc_udp_pkt->cblock.return_code = 1;
+ mb->buffer_length = 0;
+ break;
+ }
+
+ chdlc_udp_pkt->trace_info.ismoredata = 0x00;
+ buffer_length = 0; /* offset of packet already occupied */
+
+ for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){
+
+ trace_pkt_t *trace_pkt = (trace_pkt_t *)
+ &chdlc_udp_pkt->data[buffer_length];
+
+ sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr,
+ (unsigned char *)&trace_element_struct,
+ sizeof(TRACE_STATUS_ELEMENT_STRUCT));
+
+ if (trace_element_struct.opp_flag == 0x00) {
+ break;
+ }
+
+ /* get pointer to real data */
+ data_ptr = trace_element_struct.ptr_data_bfr;
+
+ /* See if there is actual data on the trace buffer */
+ if (data_ptr){
+ data_length = trace_element_struct.trace_length;
+ }else{
+ data_length = 0;
+ chdlc_udp_pkt->trace_info.ismoredata = 0x01;
+ }
+
+ if( (chdlc_priv_area->available_buffer_space - buffer_length)
+ < ( sizeof(trace_pkt_t) + data_length) ) {
+
+ /* indicate there are more frames on board & exit */
+ chdlc_udp_pkt->trace_info.ismoredata = 0x01;
+ break;
+ }
+
+ trace_pkt->status = trace_element_struct.trace_type;
+
+ trace_pkt->time_stamp =
+ trace_element_struct.trace_time_stamp;
+
+ trace_pkt->real_length =
+ trace_element_struct.trace_length;
+
+ /* see if we can fit the frame into the user buffer */
+ real_len = trace_pkt->real_length;
+
+ if (data_ptr == 0) {
+ trace_pkt->data_avail = 0x00;
+ } else {
+ unsigned tmp = 0;
+
+ /* get the data from circular buffer
+ must check for end of buffer */
+ trace_pkt->data_avail = 0x01;
+
+ if ((data_ptr + real_len) >
+ chdlc_priv_area->end_addr_trace_buffer + 1){
+
+ tmp = chdlc_priv_area->end_addr_trace_buffer - data_ptr + 1;
+ sdla_peek(&card->hw, data_ptr,
+ trace_pkt->data,tmp);
+ data_ptr = chdlc_priv_area->base_addr_trace_buffer;
+ }
+
+ sdla_peek(&card->hw, data_ptr,
+ &trace_pkt->data[tmp], real_len - tmp);
+ }
+
+ /* zero the opp flag to show we got the frame */
+ ut_char = 0x00;
+ sdla_poke(&card->hw, chdlc_priv_area->curr_trace_addr, &ut_char, 1);
+
+ /* now move onto the next frame */
+ chdlc_priv_area->curr_trace_addr += sizeof(TRACE_STATUS_ELEMENT_STRUCT);
+
+ /* check if we went over the last address */
+ if ( chdlc_priv_area->curr_trace_addr > chdlc_priv_area->end_trace_addr ) {
+ chdlc_priv_area->curr_trace_addr = chdlc_priv_area->start_trace_addr;
+ }
+
+ if(trace_pkt->data_avail == 0x01) {
+ buffer_length += real_len - 1;
+ }
+
+ /* for the header */
+ buffer_length += sizeof(trace_pkt_t);
+
+ } /* For Loop */
+
+ if (frames == chdlc_priv_area->number_trace_elements){
+ chdlc_udp_pkt->trace_info.ismoredata = 0x01;
+ }
+ chdlc_udp_pkt->trace_info.num_frames = frames;
+
+ mb->buffer_length = buffer_length;
+ chdlc_udp_pkt->cblock.buffer_length = buffer_length;
+
+ chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
+
+ break;
+
+
+ case CPIPE_FT1_READ_STATUS:
+ ((unsigned char *)chdlc_udp_pkt->data )[0] =
+ flags->FT1_info_struct.parallel_port_A_input;
+
+ ((unsigned char *)chdlc_udp_pkt->data )[1] =
+ flags->FT1_info_struct.parallel_port_B_input;
+
+ chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
+ mb->buffer_length = 2;
+ break;
+
+ case CPIPE_ROUTER_UP_TIME:
+ do_gettimeofday( &tv );
+ chdlc_priv_area->router_up_time = tv.tv_sec -
+ chdlc_priv_area->router_start_time;
+ *(unsigned long *)&chdlc_udp_pkt->data =
+ chdlc_priv_area->router_up_time;
+ mb->buffer_length = sizeof(unsigned long);
+ break;
+
+ case FT1_MONITOR_STATUS_CTRL:
+ /* Enable FT1 MONITOR STATUS */
+ if ((chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_STATUS) ||
+ (chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_OP_STATS)) {
+
+ if( rCount++ != 0 ) {
+ chdlc_udp_pkt->cblock.
+ return_code = COMMAND_OK;
+ mb->buffer_length = 1;
+ break;
+ }
+ }
+
+ /* Disable FT1 MONITOR STATUS */
+ if( chdlc_udp_pkt->data[0] == 0) {
+
+ if( --rCount != 0) {
+ chdlc_udp_pkt->cblock.
+ return_code = COMMAND_OK;
+ mb->buffer_length = 1;
+ break;
+ }
+ }
+
+ default:
+ /* it's a board command */
+ mb->command = chdlc_udp_pkt->cblock.command;
+ mb->buffer_length = chdlc_udp_pkt->cblock.buffer_length;
+ if (mb->buffer_length) {
+ memcpy(&mb->data, (unsigned char *) chdlc_udp_pkt->
+ data, mb->buffer_length);
+ }
+ /* run the command on the board */
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+ if (err != COMMAND_OK) {
+ break;
+ }
+
+ /* copy the result back to our buffer */
+ memcpy(&chdlc_udp_pkt->cblock, mb, sizeof(cblock_t));
+
+ if (mb->buffer_length) {
+ memcpy(&chdlc_udp_pkt->data, &mb->data,
+ mb->buffer_length);
+ }
+
+ } /* end of switch */
+ } /* end of else */
+
+ /* Fill UDP TTL */
+ chdlc_udp_pkt->ip_pkt.ttl = card->wandev.ttl;
+
+ len = reply_udp(chdlc_priv_area->udp_pkt_data, mb->buffer_length);
+
+ if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) {
+ if(!chdlc_send(card, chdlc_priv_area->udp_pkt_data, len)) {
+ ++ card->wandev.stats.tx_packets;
+#ifdef LINUX_2_1
+ card->wandev.stats.tx_bytes += len;
+#endif
+ }
+ } else {
+
+ /* Pass it up the stack
+ Allocate socket buffer */
+ if ((new_skb = dev_alloc_skb(len)) != NULL) {
+ /* copy data into new_skb */
+
+ buf = skb_put(new_skb, len);
+ memcpy(buf, chdlc_priv_area->udp_pkt_data, len);
+
+ /* Decapsulate pkt and pass it up the protocol stack */
+ new_skb->protocol = htons(ETH_P_IP);
+ new_skb->dev = dev;
+ new_skb->mac.raw = new_skb->data;
+
+ netif_rx(new_skb);
+ } else {
+
+ printk(KERN_INFO "%s: no socket buffers available!\n",
+ card->devname);
+ }
+ }
+
+ chdlc_priv_area->udp_pkt_lgth = 0;
+
+ return 0;
+}
+
+/*============================================================================
+ * Initialize Receive and Transmit Buffers.
+ */
+
+static void init_chdlc_tx_rx_buff( sdla_t* card, struct net_device *dev )
+{
+ CHDLC_MAILBOX_STRUCT* mb = card->mbox;
+ CHDLC_TX_STATUS_EL_CFG_STRUCT *tx_config;
+ CHDLC_RX_STATUS_EL_CFG_STRUCT *rx_config;
+ char err;
+
+ mb->buffer_length = 0;
+ mb->command = READ_CHDLC_CONFIGURATION;
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+
+ if(err != COMMAND_OK) {
+ chdlc_error(card,err,mb);
+ return;
+ }
+
+ if(card->hw.type == SDLA_S514) {
+ tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
+ (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
+ ptr_CHDLC_Tx_stat_el_cfg_struct));
+ rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
+ (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
+ ptr_CHDLC_Rx_stat_el_cfg_struct));
+
+ /* Setup Head and Tails for buffers */
+ card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
+ tx_config->base_addr_Tx_status_elements);
+ card->u.c.txbuf_last =
+ (CHDLC_DATA_TX_STATUS_EL_STRUCT *)
+ card->u.c.txbuf_base +
+ (tx_config->number_Tx_status_elements - 1);
+
+ card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
+ rx_config->base_addr_Rx_status_elements);
+ card->u.c.rxbuf_last =
+ (CHDLC_DATA_RX_STATUS_EL_STRUCT *)
+ card->u.c.rxbuf_base +
+ (rx_config->number_Rx_status_elements - 1);
+
+ /* Set up next pointer to be used */
+ card->u.c.txbuf = (void *)(card->hw.dpmbase +
+ tx_config->next_Tx_status_element_to_use);
+ card->u.c.rxmb = (void *)(card->hw.dpmbase +
+ rx_config->next_Rx_status_element_to_use);
+ }
+ else {
+ tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
+ (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
+ ptr_CHDLC_Tx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
+
+ rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
+ (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
+ ptr_CHDLC_Rx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
+
+ /* Setup Head and Tails for buffers */
+ card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
+ (tx_config->base_addr_Tx_status_elements % SDLA_WINDOWSIZE));
+ card->u.c.txbuf_last =
+ (CHDLC_DATA_TX_STATUS_EL_STRUCT *)card->u.c.txbuf_base
+ + (tx_config->number_Tx_status_elements - 1);
+ card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
+ (rx_config->base_addr_Rx_status_elements % SDLA_WINDOWSIZE));
+ card->u.c.rxbuf_last =
+ (CHDLC_DATA_RX_STATUS_EL_STRUCT *)card->u.c.rxbuf_base
+ + (rx_config->number_Rx_status_elements - 1);
+
+ /* Set up next pointer to be used */
+ card->u.c.txbuf = (void *)(card->hw.dpmbase +
+ (tx_config->next_Tx_status_element_to_use % SDLA_WINDOWSIZE));
+ card->u.c.rxmb = (void *)(card->hw.dpmbase +
+ (rx_config->next_Rx_status_element_to_use % SDLA_WINDOWSIZE));
+ }
+
+ /* Setup Actual Buffer Start and end addresses */
+ card->u.c.rx_base = rx_config->base_addr_Rx_buffer;
+ card->u.c.rx_top = rx_config->end_addr_Rx_buffer;
+
+}
+
+/*=============================================================================
+ * Perform Interrupt Test by running READ_CHDLC_CODE_VERSION command MAX_INTR
+ * _TEST_COUNTER times.
+ */
+static int intr_test( sdla_t* card, struct net_device *dev )
+{
+ CHDLC_MAILBOX_STRUCT* mb = card->mbox;
+ int err,i;
+
+ Intr_test_counter = 0;
+
+ /* The critical flag is unset because during intialization (if_open)
+ * we want the interrupts to be enabled so that when the wpc_isr is
+ * called it does not exit due to critical flag set.
+ */
+
+ clear_bit(1, (void*)&card->wandev.critical);
+ err = chdlc_set_intr_mode(card, APP_INT_ON_COMMAND_COMPLETE);
+
+ if (err == CMD_OK) {
+ for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) {
+ mb->buffer_length = 0;
+ mb->command = READ_CHDLC_CODE_VERSION;
+ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
+ if (err != CMD_OK)
+ chdlc_error(card, err, mb);
+ }
+ }
+ else {
+ return err;
+ }
+
+ err = chdlc_set_intr_mode(card, 0);
+ set_bit(1, (void*)&card->wandev.critical);
+
+
+ if (err != CMD_OK)
+ return err;
+
+ return 0;
+}
+
+/*==============================================================================
+ * Determine what type of UDP call it is. CPIPEAB ?
+ */
+static int udp_pkt_type(struct sk_buff *skb, sdla_t* card)
+{
+ chdlc_udp_pkt_t *chdlc_udp_pkt = (chdlc_udp_pkt_t *)skb->data;
+
+ if (!strncmp(chdlc_udp_pkt->wp_mgmt.signature,UDPMGMT_SIGNATURE,8) &&
+ (chdlc_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) &&
+ (chdlc_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) &&
+ (chdlc_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) {
+ return UDP_CPIPE_TYPE;
+ }
+ else return UDP_INVALID_TYPE;
+}
+
+/*============================================================================
+ * Set PORT state.
+ */
+static void port_set_state (sdla_t *card, int state)
+{
+ if (card->u.c.state != state)
+ {
+ switch (state)
+ {
+ case WAN_CONNECTED:
+ printk (KERN_INFO "%s: Link connected!\n",
+ card->devname);
+ break;
+
+ case WAN_CONNECTING:
+ printk (KERN_INFO "%s: Link connecting...\n",
+ card->devname);
+ break;
+
+ case WAN_DISCONNECTED:
+ printk (KERN_INFO "%s: Link disconnected!\n",
+ card->devname);
+ break;
+ }
+
+ card->wandev.state = card->u.c.state = state;
+ }
+}
+
+void s508_lock (sdla_t *card, unsigned long *smp_flags)
+{
+#ifdef __SMP__
+ spin_lock_irqsave(&card->lock, *smp_flags);
+ if (card->next){
+ spin_lock(&card->next->lock);
+ }
+#else
+ disable_irq(card->hw.irq);
+#endif
+}
+
+void s508_unlock (sdla_t *card, unsigned long *smp_flags)
+{
+#ifdef __SMP__
+ if (card->next){
+ spin_unlock(&card->next->lock);
+ }
+ spin_unlock_irqrestore(&card->lock, *smp_flags);
+#else
+ enable_irq(card->hw.irq);
+#endif
+}
+
+/****** End ****************************************************************/
diff --git a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c
index 6b2201a81..0c7f7e8f0 100644
--- a/drivers/net/wan/sdla_fr.c
+++ b/drivers/net/wan/sdla_fr.c
@@ -1,16 +1,38 @@
/*****************************************************************************
* sdla_fr.c WANPIPE(tm) Multiprotocol WAN Link Driver. Frame relay module.
*
-* Author(s): Gene Kozin
-* Jaspreet Singh <jaspreet@sangoma.com>
+* Author(s): Nenad Corbic <ncorbic@sangoma.com>
+* Gideon Hack
*
-* Copyright: (c) 1995-1997 Sangoma Technologies Inc.
+* Copyright: (c) 1995-1999 Sangoma Technologies 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.
* ============================================================================
+* Nov 08, 1999 Nenad Corbic o Combined all debug UDP calls into one function
+* o Removed the ARP support. This has to be done
+* in the next version.
+* o Only a Node can implement NO signalling.
+* Initialize DLCI during if_open() if NO
+* signalling.
+* o Took out IPX support, implement in next
+* version
+* Sep 29, 1999 Nenad Corbic o Added SMP support and changed the update
+* function to use timer interrupt.
+* o Fixed the CIR bug: Set the value of BC
+* to CIR when the CIR is enabled.
+* o Updated comments, statistics and tracing.
+* Jun 02, 1999 Gideon Hack o Updated for S514 support.
+* Sep 18, 1998 Jaspreet Singh o Updated for 2.2.X kernels.
+* Jul 31, 1998 Jaspreet Singh o Removed wpf_poll routine. The channel/DLCI
+* status is received through an event interrupt.
+* Jul 08, 1998 David Fong o Added inverse ARP support.
+* Mar 26, 1997 Jaspreet Singh o Returning return codes for failed UDP cmds.
+* Jan 28, 1997 Jaspreet Singh o Improved handling of inactive DLCIs.
+* Dec 30, 1997 Jaspreet Singh o Replaced dev_tint() with mark_bh(NET_BH)
+* Dec 16, 1997 Jaspreet Singh o Implemented Multiple IPX support.
* Nov 26, 1997 Jaspreet Singh o Improved load sharing with multiple boards
* o Added Cli() to protect enabling of interrupts
* while polling is called.
@@ -42,7 +64,8 @@
* o Added ability to discard multicast and
* broadcast source addressed packets
* Jun 27, 1997 Jaspreet Singh o Added FT1 monitor capabilities
-* New case (0x44) statement in if_send routine * Added a global variable rCount to keep track
+* New case (0x44) statement in if_send routine
+* Added a global variable rCount to keep track
* of FT1 status enabled on the board.
* May 29, 1997 Jaspreet Singh o Fixed major Flow Control Problem
* With multiple boards a problem was seen where
@@ -50,13 +73,15 @@
* packet after running for a while. The code
* got into a stage where the interrupts were
* disabled and dev->tbusy was set to 1.
-* This caused the If_send() routine to get into* the if clause for it(0,dev->tbusy)
+* This caused the If_send() routine to get into
+* the if clause for it(0,dev->tbusy)
* forever.
* The code got into this stage due to an
-* interrupt occurring within the if clause for
+* interrupt occuring within the if clause for
* set_bit(0,dev->tbusy). Since an interrupt
* disables furhter transmit interrupt and
-* makes dev->tbusy = 0, this effect was undone * by making dev->tbusy = 1 in the if clause.
+* makes dev->tbusy = 0, this effect was undone
+* by making dev->tbusy = 1 in the if clause.
* The Fix checks to see if Transmit interrupts
* are disabled then do not make dev->tbusy = 1
* Introduced a global variable: int_occur and
@@ -83,6 +108,7 @@
* Jan 02, 1997 Gene Kozin Initial version.
*****************************************************************************/
+#include <linux/version.h>
#include <linux/kernel.h> /* printk(), and other useful stuff */
#include <linux/stddef.h> /* offsetof(), etc. */
#include <linux/errno.h> /* return codes */
@@ -93,140 +119,133 @@
#include <linux/if_arp.h> /* ARPHRD_* defines */
#include <asm/byteorder.h> /* htons(), etc. */
#include <asm/io.h> /* for inb(), outb(), etc. */
-#include <linux/time.h> /* for do_gettimeofday */
-#define _GNUC_
-#include <linux/sdla_fr.h> /* frame relay firmware API definitions */
+#include <linux/time.h> /* for do_gettimeofday */
+#include <linux/in.h> /* sockaddr_in */
+#include <linux/inet.h> /* in_ntoa(), etc... */
#include <asm/uaccess.h>
+#include <linux/inetdevice.h>
+#include <linux/ip.h>
+#include <net/route.h> /* Dynamic Route Creation */
+#include <linux/if.h>
+#include <linux/sdla_fr.h> /* frame relay firmware API definitions */
+#if LINUX_VERSION_CODE < 0x020125
+#define test_and_set_bit set_bit
+#endif
+
/****** Defines & Macros ****************************************************/
-#define MAX_CMD_RETRY 10 /* max number of firmware retries */
-#define FR_HEADER_LEN 8 /* max encapsulation header size */
-#define FR_CHANNEL_MTU 1500 /* unfragmented logical channel MTU */
+#define MAX_CMD_RETRY 10 /* max number of firmware retries */
-/* Q.922 frame types */
+#define FR_HEADER_LEN 8 /* max encapsulation header size */
+#define FR_CHANNEL_MTU 1500 /* unfragmented logical channel MTU */
-#define Q922_UI 0x03 /* Unnumbered Info frame */
-#define Q922_XID 0xAF /* ??? */
+/* Q.922 frame types */
+#define Q922_UI 0x03 /* Unnumbered Info frame */
+#define Q922_XID 0xAF
/* DLCI configured or not */
-
#define DLCI_NOT_CONFIGURED 0x00
#define DLCI_CONFIG_PENDING 0x01
#define DLCI_CONFIGURED 0x02
/* CIR enabled or not */
-
#define CIR_ENABLED 0x00
#define CIR_DISABLED 0x01
-/* Interrupt mode for DLCI = 0 */
-
-#define BUFFER_INTR_MODE 0x00
-#define DLCI_LIST_INTR_MODE 0x01
-
-/* Transmit Interrupt Status */
-
-#define DISABLED 0x00
-#define WAITING_TO_BE_ENABLED 0x01
+#define WANPIPE 0x00
+#define API 0x01
+#define FRAME_RELAY_API 1
/* For handle_IPXWAN() */
-
#define CVHexToAscii(b) (((unsigned char)(b) > (unsigned char)9) ? ((unsigned char)'A' + ((unsigned char)(b) - (unsigned char)10)) : ((unsigned char)'0' + (unsigned char)(b)))
-
+
/****** Data Structures *****************************************************/
/* This is an extention of the 'struct net_device' we create for each network
* interface to keep the rest of channel-specific data.
*/
-typedef struct fr_channel {
- char name[WAN_IFNAME_SZ + 1]; /* interface name, ASCIIZ */
- unsigned dlci_configured; /* check whether configured or not */
- unsigned cir_status; /* check whether CIR enabled or not */
- unsigned dlci; /* logical channel number */
- unsigned cir; /* committed information rate */
- unsigned bc; /* committed burst size */
- unsigned be; /* excess burst size */
- unsigned mc; /* multicast support on or off */
- unsigned tx_int_status; /* Transmit Interrupt Status */
+typedef struct fr_channel
+{
+ char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
+ unsigned dlci_configured ; /* check whether configured or not */
+ unsigned cir_status; /* check whether CIR enabled or not */
+ unsigned dlci; /* logical channel number */
+ unsigned cir; /* committed information rate */
+ unsigned bc; /* committed burst size */
+ unsigned be; /* excess burst size */
+ unsigned mc; /* multicast support on or off */
+ unsigned tx_int_status; /* Transmit Interrupt Status */
unsigned short pkt_length; /* Packet Length */
- unsigned long router_start_time; /* Router start time in seconds */
+ unsigned long router_start_time;/* Router start time in seconds */
unsigned long tick_counter; /* counter for transmit time out */
char dev_pending_devtint; /* interface pending dev_tint() */
- char state; /* channel state */
- void *dlci_int_interface; /* pointer to the DLCI Interface */
- unsigned long IB_addr; /* physical address of Interface Byte */
+ char state; /* channel state */
+ void *dlci_int_interface; /* pointer to the DLCI Interface */
+ unsigned long IB_addr; /* physical address of Interface Byte */
unsigned long state_tick; /* time of the last state change */
- sdla_t *card; /* -> owner */
- struct net_device_stats ifstats; /* interface statistics */
- unsigned long if_send_entry;
- unsigned long if_send_skb_null;
- unsigned long if_send_broadcast;
- unsigned long if_send_multicast;
- unsigned long if_send_critical_ISR;
- unsigned long if_send_critical_non_ISR;
- unsigned long if_send_busy;
- unsigned long if_send_busy_timeout;
- unsigned long if_send_FPIPE_request;
- unsigned long if_send_DRVSTATS_request;
- unsigned long if_send_wan_disconnected;
- unsigned long if_send_dlci_disconnected;
- unsigned long if_send_no_bfrs;
- unsigned long if_send_adptr_bfrs_full;
- unsigned long if_send_bfrs_passed_to_adptr;
- unsigned long rx_intr_no_socket;
- unsigned long rx_intr_dev_not_started;
- unsigned long rx_intr_FPIPE_request;
- unsigned long rx_intr_DRVSTATS_request;
- unsigned long rx_intr_bfr_not_passed_to_stack;
- unsigned long rx_intr_bfr_passed_to_stack;
- unsigned long UDP_FPIPE_mgmt_kmalloc_err;
- unsigned long UDP_FPIPE_mgmt_direction_err;
- unsigned long UDP_FPIPE_mgmt_adptr_type_err;
- unsigned long UDP_FPIPE_mgmt_adptr_cmnd_OK;
- unsigned long UDP_FPIPE_mgmt_adptr_cmnd_timeout;
- unsigned long UDP_FPIPE_mgmt_adptr_send_passed;
- unsigned long UDP_FPIPE_mgmt_adptr_send_failed;
- unsigned long UDP_FPIPE_mgmt_not_passed_to_stack;
- unsigned long UDP_FPIPE_mgmt_passed_to_stack;
- unsigned long UDP_FPIPE_mgmt_no_socket;
- unsigned long UDP_DRVSTATS_mgmt_kmalloc_err;
- unsigned long UDP_DRVSTATS_mgmt_adptr_cmnd_OK;
- unsigned long UDP_DRVSTATS_mgmt_adptr_cmnd_timeout;
- unsigned long UDP_DRVSTATS_mgmt_adptr_send_passed;
- unsigned long UDP_DRVSTATS_mgmt_adptr_send_failed;
- unsigned long UDP_DRVSTATS_mgmt_not_passed_to_stack;
- unsigned long UDP_DRVSTATS_mgmt_passed_to_stack;
- unsigned long UDP_DRVSTATS_mgmt_no_socket;
+ unsigned char enable_IPX; /* Enable/Disable the use of IPX */
+ unsigned long network_number; /* Internal Network Number for IPX*/
+ sdla_t *card; /* -> owner */
+ unsigned route_flag; /* Add/Rem dest addr in route tables */
+ unsigned inarp; /* Inverse Arp Request status */
+ int inarp_interval; /* Time between InArp Requests */
+ unsigned long inarp_tick; /* InArp jiffies tick counter */
+ struct net_device_stats ifstats; /* interface statistics */
+ if_send_stat_t drvstats_if_send;
+ rx_intr_stat_t drvstats_rx_intr;
+ pipe_mgmt_stat_t drvstats_gen;
+
+ unsigned char usedby; /* Used by WANPIPE or API */
+
unsigned long router_up_time;
+
+ unsigned short transmit_length;
+ char transmit_buffer[FR_MAX_NO_DATA_BYTES_IN_FRAME];
} fr_channel_t;
-typedef struct dlci_status {
- unsigned short dlci PACKED;
- unsigned char state PACKED;
+/* Route Flag options */
+#define NO_ROUTE 0x00
+#define ADD_ROUTE 0x01
+#define ROUTE_ADDED 0x02
+#define REMOVE_ROUTE 0x03
+
+/* inarp options */
+#define INARP_NONE 0x00
+#define INARP_REQUEST 0x01
+#define INARP_CONFIGURED 0x02
+
+/* reasons for enabling the timer interrupt on the adapter */
+#define TMR_INT_ENABLED_UDP 0x01
+#define TMR_INT_ENABLED_UPDATE 0x02
+
+
+typedef struct dlci_status
+{
+ unsigned short dlci PACKED;
+ unsigned char state PACKED;
} dlci_status_t;
-typedef struct dlci_IB_mapping {
- unsigned short dlci PACKED;
- unsigned long addr_value PACKED;
+typedef struct dlci_IB_mapping
+{
+ unsigned short dlci PACKED;
+ unsigned long addr_value PACKED;
} dlci_IB_mapping_t;
/* This structure is used for DLCI list Tx interrupt mode. It is used to
enable interrupt bit and set the packet length for transmission
*/
+typedef struct fr_dlci_interface
+{
+ unsigned char gen_interrupt PACKED;
+ unsigned short packet_length PACKED;
+ unsigned char reserved PACKED;
+} fr_dlci_interface_t;
-typedef struct fr_dlci_interface {
- unsigned char gen_interrupt PACKED;
- unsigned short packet_length PACKED;
- unsigned char reserved PACKED;
-} fr_dlci_interface_t;
-
-static unsigned short num_frames;
-static unsigned long curr_trace_addr;
-static unsigned long start_trace_addr;
-static unsigned short available_buffer_space;
-static char TracingEnabled; /* variable for keeping track of enabling/disabling FT1 monitor status */
+/* variable for keeping track of enabling/disabling FT1 monitor status */
static int rCount = 0;
+
+extern int ip_rt_ioctl(unsigned int, void *);
extern void disable_irq(unsigned int);
extern void enable_irq(unsigned int);
@@ -234,70 +253,96 @@ extern void enable_irq(unsigned int);
* interrupt test routine
*/
static int Intr_test_counter;
-
/****** Function Prototypes *************************************************/
/* WAN link driver entry points. These are called by the WAN router module. */
-static int update(wan_device_t * wandev);
-static int new_if(wan_device_t * wandev, struct net_device *dev,
- wanif_conf_t * conf);
-static int del_if(wan_device_t * wandev, struct net_device *dev);
+static int update(wan_device_t *wandev);
+static int new_if(wan_device_t *wandev, struct net_device *dev, wanif_conf_t *conf);
+static int del_if(wan_device_t *wandev, struct net_device *dev);
+
/* WANPIPE-specific entry points */
static int wpf_exec(struct sdla *card, void *u_cmd, void *u_data);
+
/* Network device interface */
static int if_init(struct net_device *dev);
static int if_open(struct net_device *dev);
static int if_close(struct net_device *dev);
-static int if_header(struct sk_buff *skb, struct net_device *dev,
- unsigned short type, void *daddr, void *saddr, unsigned len);
+static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len);
static int if_rebuild_hdr(struct sk_buff *skb);
static int if_send(struct sk_buff *skb, struct net_device *dev);
+static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev,
+ struct sk_buff *skb);
static struct net_device_stats *if_stats(struct net_device *dev);
+
/* Interrupt handlers */
-static void fr502_isr(sdla_t * card);
-static void fr508_isr(sdla_t * card);
-static void fr502_rx_intr(sdla_t * card);
-static void fr508_rx_intr(sdla_t * card);
-static void tx_intr(sdla_t * card);
-static void spur_intr(sdla_t * card);
-/* Background polling routines */
-static void wpf_poll(sdla_t * card);
+static void fr_isr(sdla_t *card);
+static void rx_intr(sdla_t *card);
+static void tx_intr(sdla_t *card);
+static void timer_intr(sdla_t *card);
+static void spur_intr(sdla_t *card);
+
/* Frame relay firmware interface functions */
-static int fr_read_version(sdla_t * card, char *str);
-static int fr_configure(sdla_t * card, fr_conf_t * conf);
-static int fr_dlci_configure(sdla_t * card, fr_dlc_conf_t * conf, unsigned dlci);
-static int fr_set_intr_mode(sdla_t * card, unsigned mode, unsigned mtu);
-static int fr_comm_enable(sdla_t * card);
-static int fr_comm_disable(sdla_t * card);
-static int fr_get_err_stats(sdla_t * card);
-static int fr_get_stats(sdla_t * card);
-static int fr_add_dlci(sdla_t * card, int dlci, int num);
-static int fr_activate_dlci(sdla_t * card, int dlci, int num);
-static int fr_issue_isf(sdla_t * card, int isf);
-static int fr502_send(sdla_t * card, int dlci, int attr, int len, void *buf);
-static int fr508_send(sdla_t * card, int dlci, int attr, int len, void *buf);
+static int fr_read_version(sdla_t *card, char *str);
+static int fr_configure(sdla_t *card, fr_conf_t *conf);
+static int fr_dlci_configure(sdla_t *card, fr_dlc_conf_t *conf, unsigned dlci);
+static int fr_init_dlci (sdla_t *card, fr_channel_t *chan);
+static int fr_set_intr_mode (sdla_t *card, unsigned mode, unsigned mtu, unsigned short timeout);
+static int fr_comm_enable(sdla_t *card);
+static int fr_comm_disable(sdla_t *card);
+static int fr_get_err_stats(sdla_t *card);
+static int fr_get_stats(sdla_t *card);
+static int fr_add_dlci(sdla_t *card, int dlci);
+static int fr_activate_dlci(sdla_t *card, int dlci);
+static int fr_delete_dlci (sdla_t* card, int dlci);
+static int fr_issue_isf(sdla_t *card, int isf);
+static int fr_send(sdla_t *card, int dlci, unsigned char attr, int len,
+ void *buf);
+
/* Firmware asynchronous event handlers */
-static int fr_event(sdla_t * card, int event, fr_mbox_t * mbox);
-static int fr_modem_failure(sdla_t * card, fr_mbox_t * mbox);
-static int fr_dlci_change(sdla_t * card, fr_mbox_t * mbox);
+static int fr_event(sdla_t *card, int event, fr_mbox_t *mbox);
+static int fr_modem_failure(sdla_t *card, fr_mbox_t *mbox);
+static int fr_dlci_change(sdla_t *card, fr_mbox_t *mbox);
+
/* Miscellaneous functions */
static int update_chan_state(struct net_device *dev);
static void set_chan_state(struct net_device *dev, int state);
-static struct net_device *find_channel(sdla_t * card, unsigned dlci);
-static int is_tx_ready(sdla_t * card, fr_channel_t * chan);
+static struct net_device *find_channel(sdla_t *card, unsigned dlci);
+static int is_tx_ready(sdla_t *card, fr_channel_t *chan);
static unsigned int dec_to_uint(unsigned char *str, int len);
-static int reply_udp(unsigned char *data, unsigned int mbox_len);
-static int intr_test(sdla_t * card);
-static void init_chan_statistics(fr_channel_t * chan);
-static void init_global_statistics(sdla_t * card);
-static void read_DLCI_IB_mapping(sdla_t * card, fr_channel_t * chan);
+static int reply_udp( unsigned char *data, unsigned int mbox_len );
+
+static int intr_test( sdla_t* card );
+static void init_chan_statistics( fr_channel_t* chan );
+static void init_global_statistics( sdla_t* card );
+static void read_DLCI_IB_mapping( sdla_t* card, fr_channel_t* chan );
+static void setup_for_delayed_transmit(struct net_device* dev, void* buf,
+ unsigned len);
+
+
+/* Inverse ARP and Dynamic routing functions */
+int process_ARP(arphdr_1490_t *ArpPacket, sdla_t *card, struct net_device *dev);
+int is_arp(void *buf);
+int send_inarp_request(sdla_t *card, struct net_device *dev);
+
/* Udp management functions */
-static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan);
-static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan);
-static int udp_pkt_type(struct sk_buff *skb, sdla_t * card);
+static int process_udp_mgmt_pkt(sdla_t *card);
+static int udp_pkt_type( struct sk_buff *skb, sdla_t *card );
+static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t* card,
+ struct sk_buff *skb, int dlci);
+
/* IPX functions */
-static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming);
-static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number);
+static void switch_net_numbers(unsigned char *sendpacket,
+ unsigned long network_number, unsigned char incoming);
+
+static int handle_IPXWAN(unsigned char *sendpacket, char *devname,
+ unsigned char enable_IPX, unsigned long network_number);
+
+/* Lock Functions: SMP supported */
+void s508_s514_unlock(sdla_t *card, unsigned long *smp_flags);
+void s508_s514_lock(sdla_t *card, unsigned long *smp_flags);
+
+unsigned short calc_checksum (char *, int);
+
/****** Public Functions ****************************************************/
@@ -313,154 +358,251 @@ static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char
* Return: 0 o.k.
* < 0 failure.
*/
-int wpf_init(sdla_t * card, wandev_conf_t * conf)
+int wpf_init(sdla_t *card, wandev_conf_t *conf)
{
- union {
+
+ int err;
+
+ union
+ {
char str[80];
fr_conf_t cfg;
} u;
+ fr_buf_info_t* buf_info;
int i;
+
/* Verify configuration ID */
- if (conf->config_id != WANCONFIG_FR)
- {
+ if (conf->config_id != WANCONFIG_FR) {
+
printk(KERN_INFO "%s: invalid configuration ID %u!\n",
- card->devname, conf->config_id);
+ card->devname, conf->config_id);
return -EINVAL;
+
}
+
/* Initialize protocol-specific fields of adapter data space */
- switch (card->hw.fwid)
- {
- case SFID_FR502:
- card->mbox = (void *) (card->hw.dpmbase + FR502_MBOX_OFFS);
- card->rxmb = (void *) (card->hw.dpmbase + FR502_RXMB_OFFS);
- card->flags = (void *) (card->hw.dpmbase + FR502_FLAG_OFFS);
- card->isr = &fr502_isr;
- break;
+ switch (card->hw.fwid) {
+
case SFID_FR508:
- card->mbox = (void *) (card->hw.dpmbase + FR508_MBOX_OFFS);
- card->flags = (void *) (card->hw.dpmbase + FR508_FLAG_OFFS);
- card->isr = &fr508_isr;
+ card->mbox = (void*)(card->hw.dpmbase +
+ FR508_MBOX_OFFS);
+ card->flags = (void*)(card->hw.dpmbase +
+ FR508_FLAG_OFFS);
+ if(card->hw.type == SDLA_S514) {
+ card->mbox += FR_MB_VECTOR;
+ card->flags += FR_MB_VECTOR;
+ }
+ card->isr = &fr_isr;
break;
+
default:
return -EINVAL;
}
+
/* Read firmware version. Note that when adapter initializes, it
* clears the mailbox, so it may appear that the first command was
* executed successfully when in fact it was merely erased. To work
* around this, we execute the first command twice.
*/
+
if (fr_read_version(card, NULL) || fr_read_version(card, u.str))
return -EIO;
+
printk(KERN_INFO "%s: running frame relay firmware v%s\n",
- card->devname, u.str);
+ card->devname, u.str);
+
/* Adjust configuration */
- conf->mtu = max(min(conf->mtu, 4080), FR_CHANNEL_MTU + FR_HEADER_LEN);
+ conf->mtu += FR_HEADER_LEN;
+ conf->mtu = (conf->mtu >= MIN_LGTH_FR_DATA_CFG) ?
+ min(conf->mtu, FR_MAX_NO_DATA_BYTES_IN_FRAME) :
+ FR_CHANNEL_MTU + FR_HEADER_LEN;
+
conf->bps = min(conf->bps, 2048000);
- /* Configure adapter firmware */
+
+ /* Initialze the configuration structure sent to the board to zero */
memset(&u.cfg, 0, sizeof(u.cfg));
- u.cfg.mtu = conf->mtu;
- u.cfg.kbps = conf->bps / 1000;
- u.cfg.cir_fwd = u.cfg.cir_bwd = 16;
- u.cfg.bc_fwd = u.cfg.bc_bwd = 16;
- if (conf->station == WANOPT_CPE)
- {
- u.cfg.options = 0x0080;
- printk(KERN_INFO "%s: Global CIR enabled by Default\n", card->devname);
- }
- else
- {
- u.cfg.options = 0x0081;
- }
- switch (conf->u.fr.signalling)
- {
- case WANOPT_FR_Q933:
- u.cfg.options |= 0x0200;
+
+ memset(card->u.f.dlci_to_dev_map, 0, sizeof(card->u.f.dlci_to_dev_map));
+
+ /* Configure adapter firmware */
+
+ u.cfg.mtu = conf->mtu;
+ u.cfg.kbps = conf->bps / 1000;
+
+ u.cfg.cir_fwd = u.cfg.cir_bwd = 16;
+ u.cfg.bc_fwd = u.cfg.bc_bwd = 16;
+
+ u.cfg.options = 0x0000;
+ printk(KERN_INFO "%s: Global CIR enabled by Default\n", card->devname);
+
+ switch (conf->u.fr.signalling) {
+
+ case WANOPT_FR_ANSI:
+ u.cfg.options = 0x0000;
+ break;
+
+ case WANOPT_FR_Q933:
+ u.cfg.options |= 0x0200;
+ break;
+
+ case WANOPT_FR_LMI:
+ u.cfg.options |= 0x0400;
break;
- case WANOPT_FR_LMI:
- u.cfg.options |= 0x0400;
+
+ case WANOPT_NO:
+ u.cfg.options |= 0x0800;
break;
+ default:
+ printk(KERN_INFO "%s: Illegal Signalling option\n",
+ card->wandev.name);
+ return -EINVAL;
}
- if (conf->station == WANOPT_CPE)
- {
+
+
+ card->wandev.signalling = conf->u.fr.signalling;
+
+ if (conf->station == WANOPT_CPE) {
+
+
+ if (conf->u.fr.signalling == WANOPT_NO){
+ printk(KERN_INFO
+ "%s: ERROR - For NO signalling, station must be set to Node!",
+ card->devname);
+ return -EINVAL;
+ }
+
+ u.cfg.station = 0;
u.cfg.options |= 0x8000; /* auto config DLCI */
- card->u.f.dlci_num = 0;
- }
- else
- {
+ card->u.f.dlci_num = 0;
+
+ } else {
+
u.cfg.station = 1; /* switch emulation mode */
+
/* For switch emulation we have to create a list of dlci(s)
* that will be sent to be global SET_DLCI_CONFIGURATION
* command in fr_configure() routine.
*/
- card->u.f.dlci_num = min(max(conf->u.fr.dlci_num, 1), 100);
- for (i = 0; i < card->u.f.dlci_num; i++)
- {
- card->u.f.node_dlci[i] = (unsigned short)
- conf->u.fr.dlci[i] ? conf->u.fr.dlci[i] : 16;
+
+ card->u.f.dlci_num = min(max(conf->u.fr.dlci_num, 1), 100);
+
+ for ( i = 0; i < card->u.f.dlci_num; i++) {
+
+ card->u.f.node_dlci[i] = (unsigned short)
+ conf->u.fr.dlci[i] ? conf->u.fr.dlci[i] : 16;
+
}
}
+
if (conf->clocking == WANOPT_INTERNAL)
u.cfg.port |= 0x0001;
+
if (conf->interface == WANOPT_RS232)
u.cfg.port |= 0x0002;
+
if (conf->u.fr.t391)
u.cfg.t391 = min(conf->u.fr.t391, 30);
else
u.cfg.t391 = 5;
+
if (conf->u.fr.t392)
u.cfg.t392 = min(conf->u.fr.t392, 30);
else
u.cfg.t392 = 15;
+
if (conf->u.fr.n391)
u.cfg.n391 = min(conf->u.fr.n391, 255);
else
u.cfg.n391 = 2;
+
if (conf->u.fr.n392)
u.cfg.n392 = min(conf->u.fr.n392, 10);
else
- u.cfg.n392 = 3;
+ u.cfg.n392 = 3;
+
if (conf->u.fr.n393)
u.cfg.n393 = min(conf->u.fr.n393, 10);
else
u.cfg.n393 = 4;
+
if (fr_configure(card, &u.cfg))
return -EIO;
- if (card->hw.fwid == SFID_FR508)
- {
- fr_buf_info_t *buf_info =
- (void *) (card->hw.dpmbase + FR508_RXBC_OFFS);
- card->rxmb = (void *) (buf_info->rse_next - FR_MB_VECTOR + card->hw.dpmbase);
- card->u.f.rxmb_base = (void *) (buf_info->rse_base - FR_MB_VECTOR + card->hw.dpmbase);
- card->u.f.rxmb_last = (void *) (buf_info->rse_base + (buf_info->rse_num - 1) *
- sizeof(fr_buf_ctl_t) - FR_MB_VECTOR + card->hw.dpmbase);
- card->u.f.rx_base = buf_info->buf_base;
- card->u.f.rx_top = buf_info->buf_top;
- }
- card->wandev.mtu = conf->mtu;
- card->wandev.bps = conf->bps;
- card->wandev.interface = conf->interface;
- card->wandev.clocking = conf->clocking;
- card->wandev.station = conf->station;
- card->poll = &wpf_poll;
- card->exec = &wpf_exec;
- card->wandev.update = &update;
- card->wandev.new_if = &new_if;
- card->wandev.del_if = &del_if;
- card->wandev.state = WAN_DISCONNECTED;
- card->wandev.ttl = conf->ttl;
- card->wandev.udp_port = conf->udp_port;
- card->wandev.enable_tx_int = 0;
- card->irq_dis_if_send_count = 0;
- card->irq_dis_poll_count = 0;
- card->wandev.enable_IPX = conf->enable_IPX;
- if (conf->network_number)
- card->wandev.network_number = conf->network_number;
- else
- card->wandev.network_number = 0xDEADBEEF;
+
+ if (card->hw.type == SDLA_S514) {
+
+ buf_info = (void*)(card->hw.dpmbase + FR_MB_VECTOR +
+ FR508_RXBC_OFFS);
+
+ card->rxmb = (void*)(buf_info->rse_next + card->hw.dpmbase);
+
+ card->u.f.rxmb_base =
+ (void*)(buf_info->rse_base + card->hw.dpmbase);
+
+ card->u.f.rxmb_last =
+ (void*)(buf_info->rse_base +
+ (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) +
+ card->hw.dpmbase);
+ }
+
+ else {
+ buf_info = (void*)(card->hw.dpmbase + FR508_RXBC_OFFS);
+
+ card->rxmb = (void*)(buf_info->rse_next -
+ FR_MB_VECTOR + card->hw.dpmbase);
+
+ card->u.f.rxmb_base =
+ (void*)(buf_info->rse_base -
+ FR_MB_VECTOR + card->hw.dpmbase);
+
+ card->u.f.rxmb_last =
+ (void*)(buf_info->rse_base +
+ (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) -
+ FR_MB_VECTOR + card->hw.dpmbase);
+ }
+
+ card->u.f.rx_base = buf_info->buf_base;
+ card->u.f.rx_top = buf_info->buf_top;
+
+ card->u.f.tx_interrupts_pending = 0;
+
+ card->wandev.mtu = conf->mtu;
+ card->wandev.bps = conf->bps;
+ card->wandev.interface = conf->interface;
+ card->wandev.clocking = conf->clocking;
+ card->wandev.station = conf->station;
+ card->poll = NULL;
+ card->exec = &wpf_exec;
+ card->wandev.update = &update;
+ card->wandev.new_if = &new_if;
+ card->wandev.del_if = &del_if;
+ card->wandev.state = WAN_DISCONNECTED;
+ card->wandev.ttl = conf->ttl;
+ card->wandev.udp_port = conf->udp_port;
+
/* Intialize global statistics for a card */
- init_global_statistics(card);
- TracingEnabled = 0;
- return 0;
+ init_global_statistics( card );
+
+ card->TracingEnabled = 0;
+
+ /* Interrupt Test */
+ Intr_test_counter = 0;
+ card->intr_mode = INTR_TEST_MODE;
+ err = intr_test( card );
+
+ if (err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) {
+ printk(
+ "%s: Interrupt Test Failed, Counter: %i\n",
+ card->devname, Intr_test_counter);
+ printk( "Please choose another interrupt\n");
+ err = -EIO;
+ return err;
+ }
+
+ printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n",
+ card->devname, Intr_test_counter);
+
+
+ return 0;
}
/******* WAN Device Driver Entry Points *************************************/
@@ -468,21 +610,38 @@ int wpf_init(sdla_t * card, wandev_conf_t * conf)
/*============================================================================
* Update device status & statistics.
*/
-
-static int update(wan_device_t * wandev)
+static int update (wan_device_t* wandev)
{
- sdla_t *card;
+ volatile sdla_t* card;
+ unsigned long timeout;
+ fr508_flags_t* flags;
+
/* sanity checks */
if ((wandev == NULL) || (wandev->private == NULL))
return -EFAULT;
+
if (wandev->state == WAN_UNCONFIGURED)
return -ENODEV;
- if (test_and_set_bit(0, (void *) &wandev->critical))
+
+ if (test_bit(1, (void*)&wandev->critical))
return -EAGAIN;
+
card = wandev->private;
- fr_get_err_stats(card);
- fr_get_stats(card);
- wandev->critical = 0;
+ flags = card->flags;
+
+
+ card->u.f.update_comms_stats = 1;
+ card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UPDATE;
+ flags->imask |= FR_INTR_TIMER;
+ timeout = jiffies;
+ for(;;) {
+ if(card->u.f.update_comms_stats == 0)
+ break;
+ if ((jiffies - timeout) > (1 * HZ)){
+ card->u.f.update_comms_stats = 0;
+ return -EAGAIN;
+ }
+ }
return 0;
}
@@ -498,85 +657,216 @@ static int update(wan_device_t * wandev)
* Return: 0 o.k.
* < 0 failure (channel will not be created)
*/
-
-static int new_if(wan_device_t * wandev, struct net_device *dev, wanif_conf_t * conf)
+static int new_if (wan_device_t* wandev, struct net_device* dev, wanif_conf_t* conf)
{
- sdla_t *card = wandev->private;
- fr_channel_t *chan;
+ sdla_t* card = wandev->private;
+ fr_channel_t* chan;
+ int dlci = 0;
int err = 0;
- if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ))
- {
+
+ if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) {
+
printk(KERN_INFO "%s: invalid interface name!\n",
- card->devname);
+ card->devname);
return -EINVAL;
}
+
/* allocate and initialize private data */
chan = kmalloc(sizeof(fr_channel_t), GFP_KERNEL);
+
if (chan == NULL)
return -ENOMEM;
+
memset(chan, 0, sizeof(fr_channel_t));
strcpy(chan->name, conf->name);
chan->card = card;
+
/* verify media address */
- if (is_digit(conf->addr[0]))
- {
- int dlci = dec_to_uint(conf->addr, 0);
- if (dlci && (dlci <= 4095))
- {
+ if (is_digit(conf->addr[0])) {
+
+ dlci = dec_to_uint(conf->addr, 0);
+
+ if (dlci && (dlci <= HIGHEST_VALID_DLCI)) {
+
chan->dlci = dlci;
- }
- else
- {
- printk(KERN_ERR "%s: invalid DLCI %u on interface %s!\n",
- wandev->name, dlci, chan->name);
+
+ } else {
+
+ printk(KERN_ERR
+ "%s: invalid DLCI %u on interface %s!\n",
+ wandev->name, dlci, chan->name);
err = -EINVAL;
}
- }
- else
- {
- printk(KERN_ERR "%s: invalid media address on interface %s!\n",
- wandev->name, chan->name);
+
+ } else {
+ printk(KERN_ERR
+ "%s: invalid media address on interface %s!\n",
+ wandev->name, chan->name);
err = -EINVAL;
}
- if (err)
- {
+
+ /* Setup wanpipe as a router (WANPIPE) or as an API */
+ if(strcmp(conf->usedby, "WANPIPE") == 0){
+ printk(KERN_INFO "%s: Running in WANPIPE mode %s\n",
+ wandev->name, chan->name);
+ chan->usedby = WANPIPE;
+
+ } else if(strcmp(conf->usedby, "API") == 0){
+
+#ifdef FRAME_RELAY_API
+ chan->usedby = API;
+ printk(KERN_INFO "%s: Running in API mode %s\n",
+ wandev->name, chan->name);
+#else
+ printk(KERN_INFO "%s: API Mode is not supported !\n",
+ wandev->name);
+ printk(KERN_INFO
+ "%s: API patch can be obtained from Sangoma Tech.\n",
+ wandev->name);
+ err = -EINVAL;
+#endif
+ }
+
+ if (err) {
+
kfree(chan);
return err;
}
+
+ card->u.f.dlci_to_dev_map[dlci] = dev;
+
/* place cir,be,bc and other channel specific information into the
* chan structure
- */
- if (conf->cir)
- {
- chan->cir = max(1, min(conf->cir, 512));
- chan->cir_status = CIR_ENABLED;
- if (conf->bc)
- chan->bc = max(1, min(conf->bc, 512));
- if (conf->be)
- chan->be = max(0, min(conf->be, 511));
- }
- else
+ */
+ if (conf->cir) {
+
+ chan->cir = max( 1, min( conf->cir, 512 ) );
+ chan->cir_status = CIR_ENABLED;
+
+
+ /* If CIR is enabled, force BC to equal CIR
+ * this solves number of potential problems if CIR is
+ * set and BC is not
+ */
+ chan->bc = chan->cir;
+
+ if (conf->be){
+ chan->be = max( 0, min( conf->be, 511) );
+ }else{
+ conf->be = 0;
+ }
+
+ printk (KERN_INFO "%s: CIR enabled for DLCI %i \n",
+ wandev->name,chan->dlci);
+ printk (KERN_INFO "%s: CIR = %i ; BC = %i ; BE = %i\n",
+ wandev->name,chan->cir,chan->bc,chan->be);
+
+
+ }else{
chan->cir_status = CIR_DISABLED;
+ printk (KERN_INFO "%s: CIR disabled for DLCI %i\n",
+ wandev->name,chan->dlci);
+ }
+
chan->mc = conf->mc;
- chan->dlci_configured = DLCI_NOT_CONFIGURED;
- chan->tx_int_status = DISABLED;
+
+ /* FIXME: ARP is not supported by this frame relay verson */
+ if (conf->inarp == WANOPT_YES){
+ printk(KERN_INFO "%s: ERROR - This version of WANPIPE doesn't support ARPs\n",
+ card->devname);
+
+ //chan->inarp = conf->inarp ? INARP_REQUEST : INARP_NONE;
+ //chan->inarp_interval = conf->inarp_interval ? conf->inarp_interval : 10;
+ kfree(chan);
+ return -EINVAL;
+ }else{
+ chan->inarp = INARP_NONE;
+ chan->inarp_interval = 10;
+ }
+
+ chan->dlci_configured = DLCI_NOT_CONFIGURED;
+
+
+ /*FIXME: IPX disabled in this WANPIPE version */
+ if (conf->enable_IPX == WANOPT_YES){
+ printk(KERN_INFO "%s: ERROR - This version of WANPIPE doesn't support IPX\n",
+ card->devname);
+ kfree(chan);
+ return -EINVAL;
+ }else{
+ chan->enable_IPX = WANOPT_NO;
+ }
+
+ if (conf->network_number){
+ chan->network_number = conf->network_number;
+ }else{
+ chan->network_number = 0xDEADBEEF;
+ }
+
+ chan->route_flag = NO_ROUTE;
+
init_chan_statistics(chan);
+
+ chan->transmit_length = 0;
+
/* prepare network device data space for registration */
dev->name = chan->name;
dev->init = &if_init;
dev->priv = chan;
+
+
+ /* Enable Interrupts and Communications */
+ if (!wandev->new_if_cnt){
+ fr508_flags_t* flags = card->flags;
+
+ wandev->new_if_cnt++;
+
+ /*
+ If you enable comms and then set ints, you get a Tx int as you
+ perform the SET_INT_TRIGGERS command. So, we only set int
+ triggers and then adjust the interrupt mask (to disable Tx ints)
+ before enabling comms.
+ */
+ if (fr_set_intr_mode(card, (FR_INTR_RXRDY | FR_INTR_TXRDY |
+ FR_INTR_DLC | FR_INTR_TIMER | FR_INTR_TX_MULT_DLCIs) ,
+ card->wandev.mtu, 0)) {
+ kfree(chan);
+ return -EIO;
+ }
+
+ flags->imask &= ~(FR_INTR_TXRDY | FR_INTR_TIMER);
+
+ if (fr_comm_enable(card)) {
+ kfree(chan);
+ return -EIO;
+ }
+ wanpipe_set_state(card, WAN_CONNECTED);
+ }
+
return 0;
}
+
/*============================================================================
* Delete logical channel.
*/
-static int del_if(wan_device_t * wandev, struct net_device *dev)
+static int del_if (wan_device_t* wandev, struct net_device* dev)
{
- if (dev->priv)
- {
+ sdla_t *card = wandev->private;
+
+ /* Execute shutdown very first time we enter del_if */
+
+ if (!wandev->del_if_cnt) {
+ wandev->del_if_cnt++;
+ wanpipe_set_state(card, WAN_DISCONNECTED);
+ fr_set_intr_mode(card, 0, 0, 0);
+ fr_comm_disable(card);
+ }
+
+ if (dev->priv) {
kfree(dev->priv);
dev->priv = NULL;
}
+
return 0;
}
@@ -585,41 +875,47 @@ static int del_if(wan_device_t * wandev, struct net_device *dev)
/*============================================================================
* Execute adapter interface command.
*/
-static int wpf_exec(struct sdla *card, void *u_cmd, void *u_data)
+static int wpf_exec (struct sdla* card, void* u_cmd, void* u_data)
{
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox;
int retry = MAX_CMD_RETRY;
int err, len;
fr_cmd_t cmd;
- if(copy_from_user((void *) &cmd, u_cmd, sizeof(cmd)))
- return -EFAULT;
+
+ if(copy_from_user((void*)&cmd, u_cmd, sizeof(cmd)))
+ return -EFAULT;
+
/* execute command */
- do
+ do
{
memcpy(&mbox->cmd, &cmd, sizeof(cmd));
- if (cmd.length)
- {
- if(copy_from_user((void *) &mbox->data, u_data, cmd.length))
+
+ if (cmd.length){
+ if( copy_from_user((void*)&mbox->data, u_data, cmd.length))
return -EFAULT;
}
+
if (sdla_exec(mbox))
err = mbox->cmd.result;
- else
- return -EIO;
- }
- while (err && retry-- && fr_event(card, err, mbox));
- /* return result */
+ else return -EIO;
+
+ } while (err && retry-- && fr_event(card, err, mbox));
- if(copy_to_user(u_cmd, (void *) &mbox->cmd, sizeof(fr_cmd_t)))
+ /* return result */
+ if (copy_to_user(u_cmd, (void*)&mbox->cmd, sizeof(fr_cmd_t)))
return -EFAULT;
+
len = mbox->cmd.length;
- if (len && u_data && copy_to_user(u_data, (void *) &mbox->data, len))
+
+ if (len && u_data && !copy_to_user(u_data, (void*)&mbox->data, len))
return -EFAULT;
return 0;
+
}
/****** Network Device Interface ********************************************/
+
/*============================================================================
* Initialize Linux network interface.
*
@@ -627,35 +923,55 @@ static int wpf_exec(struct sdla *card, void *u_cmd, void *u_data)
* interface registration. Returning anything but zero will fail interface
* registration.
*/
-static int if_init(struct net_device *dev)
+static int if_init (struct net_device* dev)
{
- fr_channel_t *chan = dev->priv;
- sdla_t *card = chan->card;
- wan_device_t *wandev = &card->wandev;
+ fr_channel_t* chan = dev->priv;
+ sdla_t* card = chan->card;
+ wan_device_t* wandev = &card->wandev;
/* Initialize device driver entry points */
- dev->open = &if_open;
- dev->stop = &if_close;
- dev->hard_header = &if_header;
- dev->rebuild_header = &if_rebuild_hdr;
- dev->hard_start_xmit = &if_send;
- dev->get_stats = &if_stats;
+ dev->open = &if_open;
+ dev->stop = &if_close;
+ dev->hard_header = &if_header;
+ dev->rebuild_header = &if_rebuild_hdr;
+ dev->hard_start_xmit = &if_send;
+ dev->get_stats = &if_stats;
+
/* Initialize media-specific parameters */
- dev->type = ARPHRD_DLCI; /* ARP h/w type */
- dev->mtu = FR_CHANNEL_MTU;
- dev->hard_header_len = FR_HEADER_LEN; /* media header length */
- dev->addr_len = 2; /* hardware address length */
- *(unsigned short *) dev->dev_addr = htons(chan->dlci);
+ dev->type = ARPHRD_DLCI; /* ARP h/w type */
+ dev->flags |= IFF_POINTOPOINT;
+
+ /* Enable Multicast addressing */
+ if (chan->mc == WANOPT_YES){
+ dev->flags |= IFF_MULTICAST;
+ }
+
+ dev->mtu = wandev->mtu - FR_HEADER_LEN;
+ /* For an API, the maximum number of bytes that the stack will pass
+ to the driver is (dev->mtu + dev->hard_header_len). So, adjust the
+ mtu so that a frame of maximum size can be transmitted by the API.
+ */
+ if(chan->usedby == API) {
+ dev->mtu += (sizeof(api_tx_hdr_t) - FR_HEADER_LEN);
+ }
+
+ dev->hard_header_len = FR_HEADER_LEN;/* media header length */
+ dev->addr_len = 2; /* hardware address length */
+ *(unsigned short*)dev->dev_addr = htons(chan->dlci);
+
/* Initialize hardware parameters (just for reference) */
- dev->irq = wandev->irq;
- dev->dma = wandev->dma;
- dev->base_addr = wandev->ioport;
- dev->mem_start = (unsigned long)wandev->maddr;
- dev->mem_end = dev->mem_start + wandev->msize - 1;
- /* Set transmit buffer queue length */
- dev->tx_queue_len = 10;
+ dev->irq = wandev->irq;
+ dev->dma = wandev->dma;
+ dev->base_addr = wandev->ioport;
+ dev->mem_start = wandev->maddr;
+ dev->mem_end = wandev->maddr + wandev->msize - 1;
+
+ /* Set transmit buffer queue length */
+ dev->tx_queue_len = 100;
+
/* Initialize socket buffers */
dev_init_buffers(dev);
+
set_chan_state(dev, WAN_DISCONNECTED);
return 0;
}
@@ -667,127 +983,62 @@ static int if_init(struct net_device *dev)
*
* Return 0 if O.k. or errno.
*/
-
-static int if_open(struct net_device *dev)
+static int if_open (struct net_device* dev)
{
- fr_channel_t *chan = dev->priv;
- sdla_t *card = chan->card;
- struct net_device *dev2;
+ fr_channel_t* chan = dev->priv;
+ sdla_t* card = chan->card;
int err = 0;
- fr508_flags_t *flags = card->flags;
struct timeval tv;
+
if (dev->start)
- return -EBUSY; /* only one open is allowed */
- if (test_and_set_bit(0, (void *) &card->wandev.critical))
+ return -EBUSY; /* only one open is allowed */
+
+ if (test_and_set_bit(1, (void*)&card->wandev.critical))
return -EAGAIN;
- if (!card->open_cnt)
- {
- Intr_test_counter = 0;
- card->intr_mode = INTR_TEST_MODE;
- err = intr_test(card);
- if ((err) || (Intr_test_counter != (MAX_INTR_TEST_COUNTER + 1))) {
- printk(KERN_INFO
- "%s: Interrupt Test Failed, Counter: %i\n",
- card->devname, Intr_test_counter);
- err = -EIO;
- card->wandev.critical = 0;
- return err;
- }
- printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n"
- ,card->devname, Intr_test_counter);
- /* The following allocates and intializes a circular
- * link list of interfaces per card.
- */
- card->devs_struct = kmalloc(sizeof(load_sharing_t), GFP_KERNEL);
- if (card->devs_struct == NULL)
- return -ENOMEM;
- card->dev_to_devtint_next = card->devs_struct;
- for (dev2 = card->wandev.dev; dev2; dev2 = dev2->slave) {
- (card->devs_struct)->dev_ptr = dev2;
- if (dev2->slave == NULL)
- (card->devs_struct)->next = card->dev_to_devtint_next;
- else {
- (card->devs_struct)->next = kmalloc(
- sizeof(load_sharing_t), GFP_KERNEL);
- if ((card->devs_struct)->next == NULL)
- return -ENOMEM;
- card->devs_struct = (card->devs_struct)->next;
- }
- }
- card->devs_struct = card->dev_to_devtint_next;
- card->intr_mode = BUFFER_INTR_MODE;
- /*
- check all the interfaces for the device to see if CIR has
- been enabled for any DLCI(s). If so then use the DLCI list
- Interrupt mode for fr_set_intr_mode(), otherwise use the default global interrupt mode
- */
- for (dev2 = card->wandev.dev; dev2; dev2 = dev2->slave) {
- if (((fr_channel_t *) dev2->priv)->cir_status
- == CIR_ENABLED) {
- card->intr_mode = DLCI_LIST_INTR_MODE;
- break;
- }
- }
- /*
- If you enable comms and then set ints, you get a Tx int as you
- perform the SET_INT_TRIGGERS command. So, we only set int
- triggers and then adjust the interrupt mask (to disable Tx ints) before enabling comms.
- */
- if (card->intr_mode == BUFFER_INTR_MODE) {
- if (fr_set_intr_mode(card, 0x03, card->wandev.mtu)) {
- err = -EIO;
- card->wandev.critical = 0;
- return err;
- }
- printk(KERN_INFO
- "%s: Global Buffering Tx Interrupt Mode\n"
- ,card->devname);
- } else if (card->intr_mode == DLCI_LIST_INTR_MODE) {
- if (fr_set_intr_mode(card, 0x83, card->wandev.mtu)) {
- err = -EIO;
- card->wandev.critical = 0;
- return err;
- }
- printk(KERN_INFO
- "%s: DLCI list Tx Interrupt Mode\n",
- card->devname);
- }
- flags->imask &= ~0x02;
- if (fr_comm_enable(card)) {
- err = -EIO;
- card->wandev.critical = 0;
- return err;
- }
- wanpipe_set_state(card, WAN_CONNECTED);
- if (card->wandev.station == WANOPT_CPE) {
- /* CPE: issue full status enquiry */
- fr_issue_isf(card, FR_ISF_FSE);
- } else { /* FR switch: activate DLCI(s) */
- /* For Switch emulation we have to ADD and ACTIVATE
- * the DLCI(s) that were configured with the SET_DLCI_
- * CONFIGURATION command. Add and Activate will fail if
- * DLCI specified is not included in the list.
- *
- * Also If_open is called once for each interface. But
- * it does not get in here for all the interface. So
- * we have to pass the entire list of DLCI(s) to add
- * activate routines.
- */
- fr_add_dlci(card,
- card->u.f.node_dlci[0], card->u.f.dlci_num);
- fr_activate_dlci(card,
- card->u.f.node_dlci[0], card->u.f.dlci_num);
+
+
+ /* If signalling is set to NO, then setup
+ * DLCI addresses right away. Don't have to wait for
+ * link to connect.
+ */
+ if (card->wandev.signalling == WANOPT_NO){
+ printk(KERN_INFO "%s: Signalling set to NO: Mapping DLCI's\n",
+ card->wandev.name);
+ if (fr_init_dlci(card,chan)){
+ return -EAGAIN;
}
}
- dev->mtu = min(dev->mtu, card->wandev.mtu - FR_HEADER_LEN);
+
+ if (card->wandev.station == WANOPT_CPE) {
+
+ /* CPE: issue full status enquiry */
+ fr_issue_isf(card, FR_ISF_FSE);
+
+ } else { /* FR switch: activate DLCI(s) */
+
+ /* For Switch emulation we have to ADD and ACTIVATE
+ * the DLCI(s) that were configured with the SET_DLCI_
+ * CONFIGURATION command. Add and Activate will fail if
+ * DLCI specified is not included in the list.
+ *
+ * Also If_open is called once for each interface. But
+ * it does not get in here for all the interface. So
+ * we have to pass the entire list of DLCI(s) to add
+ * activate routines.
+ */
+
+ fr_add_dlci(card, chan->dlci);
+ fr_activate_dlci(card, chan->dlci);
+ }
+
dev->interrupt = 0;
dev->tbusy = 0;
dev->start = 1;
wanpipe_open(card);
update_chan_state(dev);
- do_gettimeofday(&tv);
+ do_gettimeofday( &tv );
chan->router_start_time = tv.tv_sec;
- card->wandev.critical = 0;
+ clear_bit(1, (void*)&card->wandev.critical);
return err;
}
@@ -796,22 +1047,21 @@ static int if_open(struct net_device *dev)
* o if this is the last open, then disable communications and interrupts.
* o reset flags.
*/
-
-static int if_close(struct net_device *dev)
+static int if_close (struct net_device* dev)
{
- fr_channel_t *chan = dev->priv;
- sdla_t *card = chan->card;
- if (test_and_set_bit(0, (void *) &card->wandev.critical))
+ fr_channel_t* chan = dev->priv;
+ sdla_t* card = chan->card;
+
+ if (test_and_set_bit(1, (void*)&card->wandev.critical))
return -EAGAIN;
+
dev->start = 0;
wanpipe_close(card);
- if (!card->open_cnt)
- {
- wanpipe_set_state(card, WAN_DISCONNECTED);
- fr_set_intr_mode(card, 0, 0);
- fr_comm_disable(card);
+ if (card->wandev.station == WANOPT_NODE) {
+ fr_delete_dlci (card,chan->dlci);
}
- card->wandev.critical = 0;
+
+ clear_bit(1, (void*)&card->wandev.critical);
return 0;
}
@@ -825,15 +1075,15 @@ static int if_close(struct net_device *dev)
*
* Return: media header length.
*/
-
-static int if_header(struct sk_buff *skb, struct net_device *dev,
- unsigned short type, void *daddr, void *saddr, unsigned len)
+static int if_header (struct sk_buff* skb, struct net_device* dev,
+ unsigned short type, void* daddr, void* saddr, unsigned len)
{
int hdr_len = 0;
+
skb->protocol = type;
hdr_len = wanrouter_encapsulate(skb, dev);
- if (hdr_len < 0)
- {
+
+ if (hdr_len < 0) {
hdr_len = 0;
skb->protocol = 0;
}
@@ -849,14 +1099,14 @@ static int if_header(struct sk_buff *skb, struct net_device *dev,
* Return: 1 physical address resolved.
* 0 physical address not resolved
*/
-
-static int if_rebuild_hdr(struct sk_buff *skb)
+static int if_rebuild_hdr (struct sk_buff* skb)
{
- struct net_device *dev=skb->dev;
- fr_channel_t *chan = dev->priv;
- sdla_t *card = chan->card;
+ struct net_device *dev = skb->dev;
+ fr_channel_t* chan = dev->priv;
+ sdla_t* card = chan->card;
+
printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n",
- card->devname, dev->name);
+ card->devname, dev->name);
return 1;
}
@@ -864,6 +1114,7 @@ static int if_rebuild_hdr(struct sk_buff *skb)
* Send a packet on a network interface.
* o set tbusy flag (marks start of the transmission) to block a timer-based
* transmit from overlapping.
+ * o set critical flag when accessing board.
* o check link state. If link is not up, then drop the packet.
* o check channel status. If it's down then initiate a call.
* o pass a packet to corresponding WAN device.
@@ -878,876 +1129,951 @@ static int if_rebuild_hdr(struct sk_buff *skb)
* 2. Setting tbusy flag will inhibit further transmit requests from the
* protocol stack and can be used for flow control with protocol layer.
*/
-
-static int if_send(struct sk_buff *skb, struct net_device *dev)
+static int if_send (struct sk_buff* skb, struct net_device* dev)
{
- fr_channel_t *chan = dev->priv;
- sdla_t *card = chan->card;
- int retry = 0, err;
- unsigned char *sendpacket;
- struct net_device *dev2;
- unsigned long check_braddr, check_mcaddr;
- fr508_flags_t *adptr_flags = card->flags;
+ fr_channel_t* chan = dev->priv;
+ sdla_t* card = chan->card;
+ int err;
+ unsigned char *sendpacket;
+ fr508_flags_t* adptr_flags = card->flags;
int udp_type, send_data;
- fr_dlci_interface_t *dlci_interface = chan->dlci_int_interface;
- unsigned long host_cpu_flags;
- ++chan->if_send_entry;
+ unsigned long smp_flags=0;
+ void* data;
+ unsigned len;
- if (dev->tbusy)
- {
- /* If our device stays busy for at least 5 seconds then we will
- * kick start the device by making dev->tbusy = 0. We expect
- * that our device never stays busy more than 5 seconds. So this * is only used as a last resort.
+ chan->drvstats_if_send.if_send_entry++;
+
+ if (skb == NULL) {
+ /* if we get here, some higher layer thinks we've missed an
+ * tx-done interrupt.
*/
- ++chan->if_send_busy;
+ printk(KERN_INFO "%s: interface %s got kicked!\n",
+ card->devname, dev->name);
+ chan->drvstats_if_send.if_send_skb_null ++;
+ mark_bh(NET_BH);
+ return 0;
+ }
+
+ /* We must set the 'tbusy' flag if we already have a packet queued for
+ transmission in the transmit interrupt handler. However, we must
+ ensure that the transmit interrupt does not reset the 'tbusy' flag
+ just before we set it, as this will result in a "transmit timeout".
+ */
+ set_bit(2, (void*)&card->wandev.critical);
+ if(chan->transmit_length) {
+ dev->tbusy = 1;
+ chan->tick_counter = jiffies;
+ clear_bit(2, (void*)&card->wandev.critical);
+ return 1;
+ }
+ clear_bit(2, (void*)&card->wandev.critical);
+
+ if (dev->tbusy) {
+
+ /* If our device stays busy for at least 5 seconds then we will
+ * kick start the device by making dev->tbusy = 0. We expect
+ * that our device never stays busy more than 5 seconds. So this
+ * is only used as a last resort.
+ */
+
+ chan->drvstats_if_send.if_send_tbusy++;
++chan->ifstats.collisions;
- if ((jiffies - chan->tick_counter) < (5 * HZ))
+
+ if ((jiffies - chan->tick_counter) < (5 * HZ)) {
return 1;
+ }
printk(KERN_INFO "%s: Transmit timed out\n", chan->name);
- ++chan->if_send_busy_timeout;
- /* unbusy all the interfaces on the card */
- for (dev2 = card->wandev.dev; dev2; dev2 = dev2->slave)
- dev2->tbusy = 0;
- }
+ chan->drvstats_if_send.if_send_tbusy_timeout ++;
+ dev->tbusy = 0;
+ }
+
+ data = skb->data;
sendpacket = skb->data;
+ len = skb->len;
+
udp_type = udp_pkt_type(skb, card);
- if (udp_type == UDP_DRVSTATS_TYPE)
- {
- ++chan->if_send_DRVSTATS_request;
- process_udp_driver_call(UDP_PKT_FRM_STACK, card, skb, dev, 0,
- chan);
- dev_kfree_skb(skb);
- return 0;
- }
- else if (udp_type == UDP_FPIPE_TYPE)
- ++chan->if_send_FPIPE_request;
- /* retreive source address in two forms: broadcast & multicast */
- check_braddr = sendpacket[17];
- check_mcaddr = sendpacket[14];
- check_braddr = check_braddr << 8;
- check_mcaddr = check_mcaddr << 8;
- check_braddr |= sendpacket[16];
- check_mcaddr |= sendpacket[15];
- check_braddr = check_braddr << 8;
- check_mcaddr = check_mcaddr << 8;
- check_braddr |= sendpacket[15];
- check_mcaddr |= sendpacket[16];
- check_braddr = check_braddr << 8;
- check_mcaddr = check_mcaddr << 8;
- check_braddr |= sendpacket[14];
- check_mcaddr |= sendpacket[17];
- /* if the Source Address is a Multicast address */
- if ((chan->mc == WANOPT_NO) && (check_mcaddr >= 0xE0000001) &&
- (check_mcaddr <= 0xFFFFFFFE))
- {
- printk(KERN_INFO "%s: Multicast Src. Addr. silently discarded\n"
- ,card->devname);
- dev_kfree_skb(skb);
- ++chan->ifstats.tx_dropped;
- ++chan->if_send_multicast;
+
+ if(udp_type != UDP_INVALID_TYPE) {
+ if(store_udp_mgmt_pkt(udp_type, UDP_PKT_FRM_STACK, card, skb,
+ chan->dlci)) {
+ adptr_flags->imask |= FR_INTR_TIMER;
+ if (udp_type == UDP_FPIPE_TYPE){
+ chan->drvstats_if_send.
+ if_send_PIPE_request ++;
+ }
+ }
return 0;
}
- disable_irq(card->hw.irq);
- ++card->irq_dis_if_send_count;
- if (test_and_set_bit(0, (void *) &card->wandev.critical))
- {
- if (card->wandev.critical == CRITICAL_IN_ISR)
- {
- ++chan->if_send_critical_ISR;
- if (card->intr_mode == DLCI_LIST_INTR_MODE)
- {
- /* The enable_tx_int flag is set here so that if
- * the critical flag is set due to an interrupt
- * then we want to enable transmit interrupts
- * again.
- */
- card->wandev.enable_tx_int = 1;
- /* Setting this flag to WAITING_TO_BE_ENABLED
- * specifies that interrupt bit has to be
- * enabled for that particular interface.
- * (delayed interrupt)
- */
- chan->tx_int_status = WAITING_TO_BE_ENABLED;
- /* This is used for enabling dynamic calculation
- * of CIRs relative to the packet length.
- */
- chan->pkt_length = skb->len;
- dev->tbusy = 1;
- chan->tick_counter = jiffies;
- }
- else
- {
- card->wandev.enable_tx_int = 1;
- dev->tbusy = 1;
- chan->tick_counter = jiffies;
- }
- save_flags(host_cpu_flags);
- cli();
- if ((!(--card->irq_dis_if_send_count)) &&
- (!card->irq_dis_poll_count))
- enable_irq(card->hw.irq);
- restore_flags(host_cpu_flags);
- return 1;
- }
- ++chan->if_send_critical_non_ISR;
- ++chan->ifstats.tx_dropped;
+
+ if((chan->usedby == API) && (len <= sizeof(api_tx_hdr_t))) {
+ //FIXME: increment some error statistic
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ //FIXME: can we do better than sendpacket[2]?
+ if ((chan->usedby == WANPIPE) && (sendpacket[2] == 0x45)) {
+ /* check to see if the source IP address is a broadcast or */
+ /* multicast IP address */
+ if(chk_bcast_mcast_addr(card, dev, skb))
+ return 0;
+ }
+
+ /* Lock the 508 card: SMP Supported */
+ s508_s514_lock(card,&smp_flags);
+
+ if (test_and_set_bit(0, (void*)&card->wandev.critical)) {
+ chan->drvstats_if_send.if_send_critical_non_ISR ++;
+ chan->ifstats.tx_dropped ++;
+ printk(KERN_INFO "%s Critical in IF_SEND %02X\n",
+ card->devname, card->wandev.critical);
dev_kfree_skb(skb);
- save_flags(host_cpu_flags);
- cli();
- if ((!(--card->irq_dis_if_send_count)) &&
- (!card->irq_dis_poll_count))
- enable_irq(card->hw.irq);
- restore_flags(host_cpu_flags);
+ /* Unlock the 508 card */
+ s508_s514_unlock(card,&smp_flags);
return 0;
}
- card->wandev.critical = 0x21;
- if (udp_type == UDP_FPIPE_TYPE)
- {
- err = process_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb,
- dev, 0, chan);
- }
- else if (card->wandev.state != WAN_CONNECTED)
- {
- ++chan->if_send_wan_disconnected;
+
+ if (card->wandev.state != WAN_CONNECTED) {
+ chan->drvstats_if_send.if_send_wan_disconnected ++;
++chan->ifstats.tx_dropped;
- ++card->wandev.stats.tx_dropped;
- }
- else if (chan->state != WAN_CONNECTED)
- {
- ++chan->if_send_dlci_disconnected;
+ ++card->wandev.stats.tx_dropped;
+
+ } else if (chan->state != WAN_CONNECTED) {
+ chan->drvstats_if_send.if_send_dlci_disconnected ++;
+ /* Critical area on 514, since disabl_irq is not used
+ * thus, interrupt would execute a command at
+ * the same time as if_send.
+ */
+ set_bit(1, (void*)&card->wandev.critical);
update_chan_state(dev);
- ++chan->ifstats.tx_dropped;
- ++card->wandev.stats.tx_dropped;
- }
- else if (!is_tx_ready(card, chan))
- {
- if (card->intr_mode == DLCI_LIST_INTR_MODE)
- {
- dlci_interface->gen_interrupt |= 0x40;
- dlci_interface->packet_length = skb->len;
- }
- dev->tbusy = 1;
- chan->tick_counter = jiffies;
- adptr_flags->imask |= 0x02;
- ++chan->if_send_no_bfrs;
- retry = 1;
- }
- else
- {
+ clear_bit(1, (void*)&card->wandev.critical);
+ ++chan->ifstats.tx_dropped;
+ ++card->wandev.stats.tx_dropped;
+
+ } else if (!is_tx_ready(card, chan)) {
+ setup_for_delayed_transmit(dev, data, len);
+ chan->drvstats_if_send.if_send_no_bfrs++;
+ } else {
send_data = 1;
- /* If it's an IPX packet */
- if (sendpacket[1] == 0x00 &&
- sendpacket[2] == 0x80 &&
- sendpacket[6] == 0x81 &&
- sendpacket[7] == 0x37)
- {
- if (card->wandev.enable_IPX)
- {
- switch_net_numbers(sendpacket,
- card->wandev.network_number, 0);
- }
- else
- {
- /* increment some statistic here! */
+ //FIXME: IPX is not implemented in this version of Frame Relay ?
+ if((chan->usedby == WANPIPE) &&
+ sendpacket[1] == 0x00 &&
+ sendpacket[2] == 0x80 &&
+ sendpacket[6] == 0x81 &&
+ sendpacket[7] == 0x37) {
+
+ if( chan->enable_IPX ) {
+ switch_net_numbers(sendpacket,
+ chan->network_number, 0);
+ } else {
+ //FIXME: Take this out when IPX is fixed
+ printk(KERN_INFO
+ "%s: WARNING: Unsupported IPX data in send, packet dropped\n",
+ card->devname);
send_data = 0;
}
}
- if (send_data)
- {
- err = (card->hw.fwid == SFID_FR508) ?
- fr508_send(card, chan->dlci, 0, skb->len, skb->data) :
- fr502_send(card, chan->dlci, 0, skb->len, skb->data);
- if (err)
- {
- if (card->intr_mode == DLCI_LIST_INTR_MODE)
- {
- dlci_interface->gen_interrupt |= 0x40;
- dlci_interface->packet_length = skb->len;
- }
- dev->tbusy = 1;
- chan->tick_counter = jiffies;
- adptr_flags->imask |= 0x02;
- retry = 1;
- ++chan->if_send_adptr_bfrs_full;
- ++chan->ifstats.tx_errors;
- ++card->wandev.stats.tx_errors;
+
+ if (send_data) {
+ unsigned char attr = 0;
+
+ /* For an API transmission, get rid of the API header */
+ if (chan->usedby == API) {
+ api_tx_hdr_t* api_tx_hdr;
+ api_tx_hdr = (api_tx_hdr_t*)&skb->data[0x00];
+ attr = api_tx_hdr->attr;
+ data += sizeof(api_tx_hdr_t);
+ len -= sizeof(api_tx_hdr_t);
}
- else
- {
- ++chan->if_send_bfrs_passed_to_adptr;
+
+ err = fr_send(card, chan->dlci, attr, len, data);
+ if (err) {
+ switch(err) {
+ case FRRES_CIR_OVERFLOW:
+ case FRRES_BUFFER_OVERFLOW:
+ setup_for_delayed_transmit(dev, data,
+ len);
+ chan->drvstats_if_send.
+ if_send_adptr_bfrs_full ++;
+ break;
+ default:
+ chan->drvstats_if_send.
+ if_send_dlci_disconnected ++;
+ ++chan->ifstats.tx_dropped;
+ ++card->wandev.stats.tx_dropped;
+ break;
+ }
+ } else {
+ chan->drvstats_if_send.
+ if_send_bfr_passed_to_adptr++;
++chan->ifstats.tx_packets;
++card->wandev.stats.tx_packets;
- chan->ifstats.tx_bytes += skb->len;
- card->wandev.stats.tx_bytes += skb->len;
+ chan->ifstats.tx_bytes += len;
+ card->wandev.stats.tx_bytes += len;
}
}
}
- if (!retry)
+
+ if (!dev->tbusy) {
dev_kfree_skb(skb);
+ }
- card->wandev.critical = 0;
- save_flags(host_cpu_flags);
- cli();
- if ((!(--card->irq_dis_if_send_count)) && (!card->irq_dis_poll_count))
- enable_irq(card->hw.irq);
- restore_flags(host_cpu_flags);
- return retry;
+ clear_bit(0, (void*)&card->wandev.critical);
+
+ s508_s514_unlock(card,&smp_flags);
+
+ return (dev->tbusy);
+}
+
+
+
+/*============================================================================
+ * Setup so that a frame can be transmitted on the occurence of a transmit
+ * interrupt.
+ */
+static void setup_for_delayed_transmit (struct net_device* dev, void* buf,
+ unsigned len)
+{
+ fr_channel_t* chan = dev->priv;
+ sdla_t* card = chan->card;
+ fr508_flags_t* adptr_flags = card->flags;
+ fr_dlci_interface_t* dlci_interface = chan->dlci_int_interface;
+
+ if(chan->transmit_length) {
+ printk(KERN_INFO "%s: Big mess in setup_for_del...\n",
+ card->devname);
+ return;
+ }
+
+ if(len > FR_MAX_NO_DATA_BYTES_IN_FRAME) {
+ //FIXME: increment some statistic */
+ return;
+ }
+
+ chan->transmit_length = len;
+ memcpy(chan->transmit_buffer, buf, len);
+
+ dlci_interface->gen_interrupt |= FR_INTR_TXRDY;
+ dlci_interface->packet_length = len;
+ adptr_flags->imask |= FR_INTR_TXRDY;
+
+ card->u.f.tx_interrupts_pending ++;
+}
+
+
+/*============================================================================
+ * Check to see if the packet to be transmitted contains a broadcast or
+ * multicast source IP address.
+ * Return 0 if not broadcast/multicast address, otherwise return 1.
+ */
+
+static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev,
+ struct sk_buff *skb)
+{
+ u32 src_ip_addr;
+ u32 broadcast_ip_addr = 0;
+ struct in_device *in_dev;
+ fr_channel_t* chan = dev->priv;
+
+ /* read the IP source address from the outgoing packet */
+ src_ip_addr = *(u32 *)(skb->data + 14);
+
+ /* read the IP broadcast address for the device */
+ in_dev = dev->ip_ptr;
+ if(in_dev != NULL) {
+ struct in_ifaddr *ifa= in_dev->ifa_list;
+ if(ifa != NULL)
+ broadcast_ip_addr = ifa->ifa_broadcast;
+ else
+ return 0;
+ }
+
+ /* check if the IP Source Address is a Broadcast address */
+ if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) { printk(KERN_INFO
+ "%s: Broadcast Source Address silently discarded\n",
+ card->devname);
+ dev_kfree_skb(skb);
+ ++ chan->ifstats.tx_dropped;
+ return 1;
+ }
+
+ /* check if the IP Source Address is a Multicast address */
+ if((chan->mc == WANOPT_NO) && (ntohl(src_ip_addr) >= 0xE0000001) &&
+ (ntohl(src_ip_addr) <= 0xFFFFFFFE)) {
+ printk(KERN_INFO
+ "%s: Multicast Source Address silently discarded\n",
+ card->devname);
+ dev_kfree_skb(skb);
+ ++ chan->ifstats.tx_dropped;
+ return 1;
+ }
+
+ return 0;
}
/*============================================================================
* Reply to UDP Management system.
* Return nothing.
*/
-
-static int reply_udp(unsigned char *data, unsigned int mbox_len)
+static int reply_udp( unsigned char *data, unsigned int mbox_len )
{
- unsigned short len, udp_length, temp, i, ip_length;
- unsigned long sum;
+ unsigned short len, udp_length, temp, ip_length;
+ unsigned long ip_temp;
+ int even_bound = 0;
+
+
+ fr_udp_pkt_t *fr_udp_pkt = (fr_udp_pkt_t *)data;
+
/* Set length of packet */
- len = mbox_len + 62;
+ len = sizeof(fr_encap_hdr_t)+
+ sizeof(ip_pkt_t)+
+ sizeof(udp_pkt_t)+
+ sizeof(wp_mgmt_t)+
+ sizeof(cblock_t)+
+ mbox_len;
+
+
/* fill in UDP reply */
- data[38] = 0x02;
+ fr_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY;
+
/* fill in UDP length */
- udp_length = mbox_len + 40;
+ udp_length = sizeof(udp_pkt_t)+
+ sizeof(wp_mgmt_t)+
+ sizeof(cblock_t)+
+ mbox_len;
+
+
/* put it on an even boundary */
- if (udp_length & 0x0001)
- {
+ if ( udp_length & 0x0001 ) {
udp_length += 1;
len += 1;
+ even_bound = 1;
}
- temp = (udp_length << 8) | (udp_length >> 8);
- memcpy(&data[26], &temp, 2);
+
+ temp = (udp_length<<8)|(udp_length>>8);
+ fr_udp_pkt->udp_pkt.udp_length = temp;
+
/* swap UDP ports */
- memcpy(&temp, &data[22], 2);
- memcpy(&data[22], &data[24], 2);
- memcpy(&data[24], &temp, 2);
+ temp = fr_udp_pkt->udp_pkt.udp_src_port;
+ fr_udp_pkt->udp_pkt.udp_src_port =
+ fr_udp_pkt->udp_pkt.udp_dst_port;
+ fr_udp_pkt->udp_pkt.udp_dst_port = temp;
+
+
+
/* add UDP pseudo header */
temp = 0x1100;
- memcpy(&data[udp_length + 22], &temp, 2);
- temp = (udp_length << 8) | (udp_length >> 8);
- memcpy(&data[udp_length + 24], &temp, 2);
+ *((unsigned short *)
+ (fr_udp_pkt->data+mbox_len+even_bound)) = temp;
+ temp = (udp_length<<8)|(udp_length>>8);
+ *((unsigned short *)
+ (fr_udp_pkt->data+mbox_len+even_bound+2)) = temp;
+
/* calculate UDP checksum */
- data[28] = data[29] = 0;
- sum = 0;
- for (i = 0; i < udp_length + 12; i += 2)
- {
- memcpy(&temp, &data[14 + i], 2);
- sum += (unsigned long) temp;
- }
- while (sum >> 16)
- sum = (sum & 0xffffUL) + (sum >> 16);
+ fr_udp_pkt->udp_pkt.udp_checksum = 0;
+
+ fr_udp_pkt->udp_pkt.udp_checksum =
+ calc_checksum(&data[UDP_OFFSET+sizeof(fr_encap_hdr_t)],
+ udp_length+UDP_OFFSET);
- temp = (unsigned short) sum;
- temp = ~temp;
- if (temp == 0)
- temp = 0xffff;
- memcpy(&data[28], &temp, 2);
/* fill in IP length */
- ip_length = udp_length + 20;
- temp = (ip_length << 8) | (ip_length >> 8);
- memcpy(&data[4], &temp, 2);
+ ip_length = udp_length + sizeof(ip_pkt_t);
+ temp = (ip_length<<8)|(ip_length>>8);
+ fr_udp_pkt->ip_pkt.total_length = temp;
+
/* swap IP addresses */
- memcpy(&temp, &data[14], 2);
- memcpy(&data[14], &data[18], 2);
- memcpy(&data[18], &temp, 2);
- memcpy(&temp, &data[16], 2);
- memcpy(&data[16], &data[20], 2);
- memcpy(&data[20], &temp, 2);
+ ip_temp = fr_udp_pkt->ip_pkt.ip_src_address;
+ fr_udp_pkt->ip_pkt.ip_src_address =
+ fr_udp_pkt->ip_pkt.ip_dst_address;
+ fr_udp_pkt->ip_pkt.ip_dst_address = ip_temp;
+
+
/* fill in IP checksum */
- data[12] = data[13] = 0;
- sum = 0;
- for (i = 0; i < 20; i += 2)
- {
- memcpy(&temp, &data[2 + i], 2);
- sum += (unsigned long) temp;
+ fr_udp_pkt->ip_pkt.hdr_checksum = 0;
+ fr_udp_pkt->ip_pkt.hdr_checksum =
+ calc_checksum(&data[sizeof(fr_encap_hdr_t)],
+ sizeof(ip_pkt_t));
+
+ return len;
+} /* reply_udp */
+
+unsigned short calc_checksum (char *data, int len)
+{
+ unsigned short temp;
+ unsigned long sum=0;
+ int i;
+
+ for( i = 0; i <len; i+=2 ) {
+ memcpy(&temp,&data[i],2);
+ sum += (unsigned long)temp;
}
- while (sum >> 16)
+
+ while (sum >> 16 ) {
sum = (sum & 0xffffUL) + (sum >> 16);
- temp = (unsigned short) sum;
+ }
+
+ temp = (unsigned short)sum;
temp = ~temp;
- if (temp == 0)
+
+ if( temp == 0 )
temp = 0xffff;
- memcpy(&data[12], &temp, 2);
- return len;
-} /* reply_udp */
+
+ return temp;
+}
+
/*
If incoming is 0 (outgoing)- if the net numbers is ours make it 0
if incoming is 1 - if the net number is 0 make it ours
- */
+*/
static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming)
{
unsigned long pnetwork_number;
- pnetwork_number = (unsigned long) ((sendpacket[14] << 24) +
- (sendpacket[15] << 16) + (sendpacket[16] << 8) +
- sendpacket[17]);
+
+ pnetwork_number = (unsigned long)((sendpacket[14] << 24) +
+ (sendpacket[15] << 16) + (sendpacket[16] << 8) +
+ sendpacket[17]);
+
if (!incoming) {
/* If the destination network number is ours, make it 0 */
- if (pnetwork_number == network_number) {
- sendpacket[14] = sendpacket[15] = sendpacket[16] =
- sendpacket[17] = 0x00;
+ if( pnetwork_number == network_number) {
+ sendpacket[14] = sendpacket[15] = sendpacket[16] =
+ sendpacket[17] = 0x00;
}
} else {
/* If the incoming network is 0, make it ours */
- if (pnetwork_number == 0)
- {
- sendpacket[14] = (unsigned char) (network_number >> 24);
- sendpacket[15] = (unsigned char) ((network_number &
- 0x00FF0000) >> 16);
- sendpacket[16] = (unsigned char) ((network_number &
- 0x0000FF00) >> 8);
- sendpacket[17] = (unsigned char) (network_number &
- 0x000000FF);
+ if( pnetwork_number == 0) {
+ sendpacket[14] = (unsigned char)(network_number >> 24);
+ sendpacket[15] = (unsigned char)((network_number &
+ 0x00FF0000) >> 16);
+ sendpacket[16] = (unsigned char)((network_number &
+ 0x0000FF00) >> 8);
+ sendpacket[17] = (unsigned char)(network_number &
+ 0x000000FF);
}
}
- pnetwork_number = (unsigned long) ((sendpacket[26] << 24) +
- (sendpacket[27] << 16) + (sendpacket[28] << 8) +
- sendpacket[29]);
- if (!incoming) {
+
+
+ pnetwork_number = (unsigned long)((sendpacket[26] << 24) +
+ (sendpacket[27] << 16) + (sendpacket[28] << 8) +
+ sendpacket[29]);
+
+ if( !incoming ) {
/* If the source network is ours, make it 0 */
- if (pnetwork_number == network_number)
- {
- sendpacket[26] = sendpacket[27] = sendpacket[28] =
- sendpacket[29] = 0x00;
+ if( pnetwork_number == network_number) {
+ sendpacket[26] = sendpacket[27] = sendpacket[28] =
+ sendpacket[29] = 0x00;
}
} else {
/* If the source network is 0, make it ours */
- if (pnetwork_number == 0) {
- sendpacket[26] = (unsigned char) (network_number >> 24);
- sendpacket[27] = (unsigned char) ((network_number &
- 0x00FF0000) >> 16);
- sendpacket[28] = (unsigned char) ((network_number &
- 0x0000FF00) >> 8);
- sendpacket[29] = (unsigned char) (network_number &
- 0x000000FF);
+ if( pnetwork_number == 0 ) {
+ sendpacket[26] = (unsigned char)(network_number >> 24);
+ sendpacket[27] = (unsigned char)((network_number &
+ 0x00FF0000) >> 16);
+ sendpacket[28] = (unsigned char)((network_number &
+ 0x0000FF00) >> 8);
+ sendpacket[29] = (unsigned char)(network_number &
+ 0x000000FF);
}
}
-} /* switch_net_numbers */
+} /* switch_net_numbers */
/*============================================================================
- * Get Ethernet-style interface statistics.
- * Return a pointer to struct net_device_stats.
+ * Get ethernet-style interface statistics.
+ * Return a pointer to struct enet_statistics.
*/
-
-static struct net_device_stats *if_stats(struct net_device *dev)
+static struct enet_statistics* if_stats (struct net_device* dev)
{
- fr_channel_t *chan = dev->priv;
- if(chan==NULL)
+ fr_channel_t* chan = dev->priv;
+
+ if(chan == NULL)
return NULL;
-
+
return &chan->ifstats;
}
/****** Interrupt Handlers **************************************************/
-/*============================================================================
- * S502 frame relay interrupt service routine.
- */
-static void fr502_isr(sdla_t * card)
-{
- fr502_flags_t *flags = card->flags;
- switch (flags->iflag)
- {
- case 0x01: /* receive interrupt */
- fr502_rx_intr(card);
- break;
- case 0x02: /* transmit interrupt */
- flags->imask &= ~0x02;
- tx_intr(card);
- break;
- default:
- spur_intr(card);
- }
- flags->iflag = 0;
-}
/*============================================================================
* S508 frame relay interrupt service routine.
*/
-
-static void fr508_isr(sdla_t * card)
+static void fr_isr (sdla_t* card)
{
- fr508_flags_t *flags = card->flags;
- fr_buf_ctl_t *bctl;
+ fr508_flags_t* flags = card->flags;
char *ptr = &flags->iflag;
- struct net_device *dev = card->wandev.dev;
- struct net_device *dev2;
- int i;
- unsigned long host_cpu_flags;
- unsigned disable_tx_intr = 1;
- fr_channel_t *chan;
- fr_dlci_interface_t *dlci_interface;
+ int i,err;
+ fr_mbox_t* mbox = card->mbox;
+
/* This flag prevents nesting of interrupts. See sdla_isr() routine
- * in sdlamain.c.
+ * in sdlamain.c.
*/
card->in_isr = 1;
+
++card->statistics.isr_entry;
- if (test_and_set_bit(0, (void *) &card->wandev.critical))
- {
- printk(KERN_INFO "fr508_isr: %s, wandev.critical set to 0x%02X, int type = 0x%02X\n", card->devname, card->wandev.critical, flags->iflag);
- ++card->statistics.isr_already_critical;
+
+ if(test_bit(1, (void*)&card->wandev.critical)) {
+ card->wandev.critical = 0;
+ flags->iflag = 0;
card->in_isr = 0;
return;
}
- /* For all interrupts set the critical flag to CRITICAL_RX_INTR.
- * If the if_send routine is called with this flag set it will set
- * the enable transmit flag to 1. (for a delayed interrupt)
- */
- card->wandev.critical = CRITICAL_IN_ISR;
- card->dlci_int_mode_unbusy = 0;
- card->buff_int_mode_unbusy = 0;
- switch (flags->iflag)
- {
- case 0x01: /* receive interrupt */
- ++card->statistics.isr_rx;
- fr508_rx_intr(card);
- break;
- case 0x02: /* transmit interrupt */
- ++card->statistics.isr_tx;
- bctl = (void *) (flags->tse_offs - FR_MB_VECTOR +
- card->hw.dpmbase);
- bctl->flag = 0xA0;
- if (card->intr_mode == DLCI_LIST_INTR_MODE)
- {
- /* Find the structure and make it unbusy */
- dev = find_channel(card, flags->dlci);
- dev->tbusy = 0;
- /* This is used to perform devtint at the
- * end of the isr
- */
- card->dlci_int_mode_unbusy = 1;
- /* check to see if any other interfaces are
- * busy. If so then do not disable the tx
- * interrupts
- */
- for (dev2 = card->wandev.dev; dev2;
- dev2 = dev2->slave)
- {
- if (dev2->tbusy == 1)
- {
- disable_tx_intr = 0;
- break;
- }
- }
- if (disable_tx_intr)
- flags->imask &= ~0x02;
- }
- else if (card->intr_mode == BUFFER_INTR_MODE)
- {
- for (dev2 = card->wandev.dev; dev2;
- dev2 = dev2->slave)
- {
- if (!dev2 || !dev2->start)
- {
- ++card->statistics.tx_intr_dev_not_started;
- continue;
- }
- if (dev2->tbusy)
- {
- card->buff_int_mode_unbusy = 1;
- ((fr_channel_t *) dev2->priv)->dev_pending_devtint = 1;
- dev2->tbusy = 0;
- }
- else
- ((fr_channel_t *) dev2->priv)->dev_pending_devtint = 0;
- }
- flags->imask &= ~0x02;
- }
- break;
- case 0x08:
- Intr_test_counter++;
+
+ if(card->hw.type != SDLA_S514) {
+ if (test_and_set_bit(0, (void*)&card->wandev.critical)) {
+ printk(KERN_INFO "%s: Critical while in ISR (0x%02X)\n",
+ card->devname, card->wandev.critical);
+ ++card->statistics.isr_already_critical;
+ card->in_isr = 0;
+ return;
+ }
+ }
+
+ switch (flags->iflag) {
+
+ case FR_INTR_RXRDY: /* receive interrupt */
+ ++card->statistics.isr_rx;
+ rx_intr(card);
+ break;
+
+
+ case FR_INTR_TXRDY: /* transmit interrupt */
+ ++ card->statistics.isr_tx;
+ tx_intr(card);
+ break;
+
+ case FR_INTR_READY:
+ Intr_test_counter++;
++card->statistics.isr_intr_test;
+ break;
+
+ case FR_INTR_DLC: /* Event interrupt occured */
+ mbox->cmd.command = FR_READ_STATUS;
+ mbox->cmd.length = 0;
+ err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
+ if (err)
+ fr_event(card, err, mbox);
break;
+
+ case FR_INTR_TIMER: /* Timer interrupt */
+ timer_intr(card);
+ break;
+
default:
- ++card->statistics.isr_spurious;
- spur_intr(card);
- printk(KERN_INFO "%s: Interrupt Type 0x%02X!\n",
- card->devname, flags->iflag);
- printk(KERN_INFO "%s: ID Bytes = ", card->devname);
- for (i = 0; i < 8; i++)
+ ++card->statistics.isr_spurious;
+ spur_intr(card);
+ printk(KERN_INFO "%s: Interrupt Type 0x%02X!\n",
+ card->devname, flags->iflag);
+
+ printk(KERN_INFO "%s: ID Bytes = ",card->devname);
+ for(i = 0; i < 8; i ++)
printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));
- printk(KERN_INFO "\n");
+ printk(KERN_INFO "\n");
+
break;
- }
- card->wandev.critical = CRITICAL_INTR_HANDLED;
- if (card->wandev.enable_tx_int)
- {
- if (card->intr_mode == DLCI_LIST_INTR_MODE)
- {
- for (dev2 = card->wandev.dev; dev2; dev2 = dev2->slave)
- {
- chan = dev2->priv;
- if (chan->tx_int_status == WAITING_TO_BE_ENABLED)
- {
- dlci_interface = chan->dlci_int_interface;
- dlci_interface->gen_interrupt |= 0x40;
- dlci_interface->packet_length = chan->pkt_length;
- chan->tx_int_status = DISABLED;
- }
- }
- }
- card->wandev.enable_tx_int = 0;
- flags->imask |= 0x02;
- ++card->statistics.isr_enable_tx_int;
- }
- save_flags(host_cpu_flags);
- cli();
+ }
+
card->in_isr = 0;
- card->wandev.critical = 0xD1;
flags->iflag = 0;
- card->wandev.critical = 0;
- restore_flags(host_cpu_flags);
- /* Device is now ready to send. The instant this is executed the If_Send
- routine is called. That is why this is put at the bottom of the ISR
- to prevent a endless loop condition caused by repeated Interrupts and
- enable_tx_int flag.
- */
- if (card->dlci_int_mode_unbusy)
- mark_bh(NET_BH);
- if (card->buff_int_mode_unbusy)
- {
- for (;;)
- {
- if (((fr_channel_t *) ((card->devs_struct)->dev_ptr)->priv)->dev_pending_devtint == 1)
- {
- ((fr_channel_t *) ((card->devs_struct)->dev_ptr)->priv)->dev_pending_devtint = 0;
- mark_bh(NET_BH);
- }
- if ((card->devs_struct)->next == card->dev_to_devtint_next)
- break;
- card->devs_struct = (card->devs_struct)->next;
- }
- card->devs_struct = (card->dev_to_devtint_next)->next;
- card->dev_to_devtint_next = card->devs_struct;
- }
+ if(card->hw.type != SDLA_S514)
+ clear_bit(0, (void*)&card->wandev.critical);
}
-/*============================================================================
- * Receive interrupt handler.
- */
-static void fr502_rx_intr(sdla_t * card)
-{
- fr_mbox_t *mbox = card->rxmb;
- struct sk_buff *skb;
- struct net_device *dev;
- fr_channel_t *chan;
- unsigned dlci, len;
- void *buf;
- unsigned char *sendpacket;
- unsigned char buf2[3];
- int udp_type;
- sdla_mapmem(&card->hw, FR502_RX_VECTOR);
- dlci = mbox->cmd.dlci;
- len = mbox->cmd.length;
- /* Find network interface for this packet */
- dev = find_channel(card, dlci);
- if (dev == NULL)
- {
- /* Invalid channel, discard packet */
- printk(KERN_INFO "%s: receiving on orphaned DLCI %d!\n",
- card->devname, dlci);
- sdla_mapmem(&card->hw, FR_MB_VECTOR);
- }
- chan = dev->priv;
- if (!dev->start)
- {
- ++chan->ifstats.rx_dropped;
- sdla_mapmem(&card->hw, FR_MB_VECTOR);
- }
- /* Allocate socket buffer */
- skb = dev_alloc_skb(len);
- if (skb == NULL)
- {
- printk(KERN_INFO "%s: no socket buffers available!\n",
- card->devname);
- ++chan->ifstats.rx_dropped;
- sdla_mapmem(&card->hw, FR_MB_VECTOR);
- }
- /* Copy data to the socket buffer */
- buf = skb_put(skb, len);
- memcpy(buf, mbox->data, len);
- sdla_mapmem(&card->hw, FR_MB_VECTOR);
- /* Check if it's a UDP management packet */
- sendpacket = skb->data;
- memcpy(&buf2, &card->wandev.udp_port, 2);
- udp_type = udp_pkt_type(skb, card);
- if ((udp_type == UDP_FPIPE_TYPE) || (udp_type == UDP_DRVSTATS_TYPE))
- {
- if (udp_type == UDP_DRVSTATS_TYPE)
- {
- ++chan->rx_intr_DRVSTATS_request;
- process_udp_driver_call(UDP_PKT_FRM_NETWORK, card, skb,
- dev, dlci, chan);
- }
- else
- {
- ++chan->rx_intr_FPIPE_request;
- process_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK, card, skb,
- dev, dlci, chan);
- }
- }
- else
- {
- /* Decapsulate packet and pass it up the protocol stack */
- skb->dev = dev;
- buf = skb_pull(skb, 1); /* remove hardware header */
- if (!wanrouter_type_trans(skb, dev))
- {
- /* can't decapsulate packet */
- dev_kfree_skb(skb);
- ++chan->ifstats.rx_errors;
- ++card->wandev.stats.rx_errors;
- }
- else
- {
- netif_rx(skb);
- ++chan->ifstats.rx_packets;
- ++card->wandev.stats.rx_packets;
- chan->ifstats.rx_bytes += skb->len;
- card->wandev.stats.rx_bytes += skb->len;
- }
- }
- sdla_mapmem(&card->hw, FR_MB_VECTOR);
-}
+
+
/*============================================================================
* Receive interrupt handler.
+ * When a receive interrupt occurs do the following:
+ * 1- Find the structure for the dlci that the interrupt occured on
+ * 2- If it doesn't exist then print appropriate msg and goto step 8.
+ * 3- If it exist then copy data to a skb.
+ * 4- If skb contains Sangoma UDP data then process them
+ * 5- If skb contains IPXWAN data then send IPXWAN reply packets
+ * 6- If skb contains Inverse Arp data then send Inv Arp replies
+ * 7- If skb contains any other data then decapsulate the packet and
+ * send it to the stack.
+ * 8- Release the receive element and update receive pointers on the board
*/
-
-static void fr508_rx_intr(sdla_t * card)
+static void rx_intr (sdla_t* card)
{
- fr_buf_ctl_t *frbuf = card->rxmb;
- struct sk_buff *skb;
- struct net_device *dev;
- fr_channel_t *chan;
- unsigned dlci, len, offs;
- void *buf;
- unsigned rx_count = 0;
- fr508_flags_t *flags = card->flags;
+ fr_rx_buf_ctl_t* frbuf = card->rxmb;
+ fr508_flags_t* flags = card->flags;
+ fr_channel_t* chan;
char *ptr = &flags->iflag;
- int i, err, udp_type;
- if (frbuf->flag != 0x01)
- {
- printk(KERN_INFO
- "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n",
- card->devname, (unsigned) frbuf, frbuf->flag);
- printk(KERN_INFO "%s: ID Bytes = ", card->devname);
- for (i = 0; i < 8; i++)
+ struct sk_buff* skb;
+ struct net_device* dev;
+ void* buf;
+ unsigned dlci, len, offs, len_incl_hdr;
+ int i, udp_type;
+
+ if (frbuf->flag != 0x01) {
+
+ printk(KERN_INFO
+ "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n",
+ card->devname, (unsigned)frbuf, frbuf->flag);
+
+ printk(KERN_INFO "%s: ID Bytes = ",card->devname);
+ for(i = 0; i < 8; i ++)
printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));
printk(KERN_INFO "\n");
+
++card->statistics.rx_intr_corrupt_rx_bfr;
return;
}
-
- do
- {
- len = frbuf->length;
- dlci = frbuf->dlci;
- offs = frbuf->offset;
- /* Find network interface for this packet */
- dev = find_channel(card, dlci);
+
+ len = frbuf->length;
+ dlci = frbuf->dlci;
+ offs = frbuf->offset;
+
+ /* Find network interface for this packet */
+ dev = find_channel(card, dlci);
+
+ if (dev == NULL) {
+
+ /* unconfigured DLCI, so discard packet */
+ printk(KERN_INFO "%s: received data on unconfigured DLCI %d!\n",
+ card->devname, dlci);
+ ++card->statistics.rx_intr_on_orphaned_DLCI;
+
+ } else {
chan = dev->priv;
- if (dev == NULL)
- {
- /* Invalid channel, discard packet */
- printk(KERN_INFO "%s: receiving on orphaned DLCI %d!\n"
- ,card->devname, dlci);
- ++card->statistics.rx_intr_on_orphaned_DLCI;
- }
- else
- {
- skb = dev_alloc_skb(len);
- if (!dev->start || (skb == NULL))
- {
- ++chan->ifstats.rx_dropped;
- if (dev->start)
- {
- printk(KERN_INFO
- "%s: no socket buffers available!\n",
- card->devname);
- ++chan->rx_intr_no_socket;
- } else
- ++chan->rx_intr_dev_not_started;
+
+ skb = dev_alloc_skb(len);
+
+ if (!dev->start || (skb == NULL)) {
+ ++chan->ifstats.rx_dropped;
+
+ if(dev->start) {
+
+ printk(KERN_INFO
+ "%s: no socket buffers available!\n",
+ card->devname);
+ chan->drvstats_rx_intr.rx_intr_no_socket ++;
+
+ } else
+ chan->drvstats_rx_intr.
+ rx_intr_dev_not_started ++;
+ } else {
+ /* Copy data to the socket buffer */
+ if ((offs + len) > card->u.f.rx_top + 1) {
+ unsigned tmp = card->u.f.rx_top - offs + 1;
+
+ buf = skb_put(skb, tmp);
+ sdla_peek(&card->hw, offs, buf, tmp);
+ offs = card->u.f.rx_base;
+ len -= tmp;
+ }
+
+ buf = skb_put(skb, len);
+ sdla_peek(&card->hw, offs, buf, len);
+
+ udp_type = udp_pkt_type( skb, card );
+
+ if(udp_type != UDP_INVALID_TYPE) {
+ if(store_udp_mgmt_pkt(udp_type,
+ UDP_PKT_FRM_NETWORK, card, skb, dlci)) {
+ flags->imask |= FR_INTR_TIMER;
+ if (udp_type == UDP_FPIPE_TYPE){
+ chan->drvstats_rx_intr.
+ rx_intr_PIPE_request ++;
+ }
+ }
}
- else
- {
- /* Copy data to the socket buffer */
- if ((offs + len) > card->u.f.rx_top + 1)
- {
- unsigned tmp = card->u.f.rx_top - offs + 1;
- buf = skb_put(skb, tmp);
- sdla_peek(&card->hw, offs, buf, tmp);
- offs = card->u.f.rx_base;
- len -= tmp;
- }
- buf = skb_put(skb, len);
- sdla_peek(&card->hw, offs, buf, len);
- udp_type = udp_pkt_type(skb, card);
- if (udp_type == UDP_DRVSTATS_TYPE)
- {
- ++chan->rx_intr_DRVSTATS_request;
- process_udp_driver_call(
- UDP_PKT_FRM_NETWORK, card, skb,
- dev, dlci, chan);
+
+ else if (chan->usedby == API) {
+ api_rx_hdr_t* api_rx_hdr;
+ chan->drvstats_rx_intr.
+ rx_intr_bfr_passed_to_stack ++;
+ chan->ifstats.rx_packets ++;
+ card->wandev.stats.rx_packets ++;
+ chan->ifstats.rx_bytes += skb->len;
+ card->wandev.stats.rx_bytes += skb->len;
+
+ skb_push(skb, sizeof(api_rx_hdr_t));
+ api_rx_hdr = (api_rx_hdr_t*)&skb->data[0x00];
+ api_rx_hdr->attr = frbuf->attr;
+ api_rx_hdr->time_stamp = frbuf->tmstamp;
+ skb->protocol = htons(0x16);
+ skb->pkt_type = PACKET_HOST;
+ /* Pass it up the protocol stack */
+ skb->dev = dev;
+ skb->mac.raw = skb->data;
+ netif_rx(skb);
+
+ } else if (handle_IPXWAN(skb->data,chan->name,
+ chan->enable_IPX, chan->network_number)) {
+ if (chan->enable_IPX) {
+ fr_send(card, dlci, 0, skb->len,
+ skb->data);
}
- else if (udp_type == UDP_FPIPE_TYPE)
- {
- ++chan->rx_intr_FPIPE_request;
- err = process_udp_mgmt_pkt(
- UDP_PKT_FRM_NETWORK, card,
- skb, dev, dlci, chan);
+ dev_kfree_skb(skb);
+
+/*FIXME: Fix the ARPS in next release
+
+ } else if (is_arp(skb->data)) {
+ if (process_ARP((arphdr_1490_t *)skb->data, card, dev)) {
+ printk (KERN_INFO "%s: Error processing ARP Packet.\n", card->devname);
}
- else if (handle_IPXWAN(skb->data, card->devname, card->wandev.enable_IPX, card->wandev.network_number))
- {
- if (card->wandev.enable_IPX)
- fr508_send(card, dlci, 0, skb->len, skb->data);
- }
- else
- {
- /* Decapsulate packet and pass it up the
- protocol stack */
- skb->dev = dev;
- /* remove hardware header */
- buf = skb_pull(skb, 1);
- if (!wanrouter_type_trans(skb, dev))
- {
- /* can't decapsulate packet */
- dev_kfree_skb(skb);
- ++chan->
- rx_intr_bfr_not_passed_to_stack;
- ++chan->
- ifstats.rx_errors;
- ++card->
- wandev.stats.rx_errors;
- }
- else
- {
- netif_rx(skb);
- ++chan->rx_intr_bfr_passed_to_stack;
- ++chan->ifstats.rx_packets;
- ++card->wandev.stats.rx_packets;
- chan->ifstats.rx_bytes += skb->len;
- card->wandev.stats.rx_bytes += skb->len;
- }
+ dev_kfree_skb(skb);
+*/
+
+ } else if ( skb->data[0] != 0x03) {
+ printk(KERN_INFO "%s: Non IETF packet discarded.\n", card->devname);
+ dev_kfree_skb(skb);
+
+ } else {
+
+ len_incl_hdr = skb->len;
+ /* Decapsulate packet and pass it up the
+ protocol stack */
+ skb->dev = dev;
+
+ /* remove hardware header */
+ buf = skb_pull(skb, 1);
+
+ if (!wanrouter_type_trans(skb, dev)) {
+
+ /* can't decapsulate packet */
+ dev_kfree_skb(skb);
+ chan->drvstats_rx_intr.
+ rx_intr_bfr_not_passed_to_stack ++;
+ ++ chan->ifstats.rx_errors;
+ ++ card->wandev.stats.rx_errors;
+
+ } else {
+ netif_rx(skb);
+ chan->drvstats_rx_intr.
+ rx_intr_bfr_passed_to_stack ++;
+ ++ chan->ifstats.rx_packets;
+ ++ card->wandev.stats.rx_packets;
+ chan->ifstats.rx_bytes += len_incl_hdr;
+ card->wandev.stats.rx_bytes +=
+ len_incl_hdr;
}
- }
- }
- /* Release buffer element and calculate a pointer to the next
- one */
- frbuf->flag = 0;
- card->rxmb = ++frbuf;
- if ((void *) frbuf > card->u.f.rxmb_last)
- card->rxmb = card->u.f.rxmb_base;
- /* The loop put in is temporary, that is why the break is
- * placed here. (?????)
- */
- break;
- frbuf = card->rxmb;
- }
- while (frbuf->flag && ((++rx_count) < 4));
+ }
+ }
+ }
+
+ /* Release buffer element and calculate a pointer to the next one */
+ frbuf->flag = 0;
+ card->rxmb = ++frbuf;
+ if ((void*)frbuf > card->u.f.rxmb_last)
+ card->rxmb = card->u.f.rxmb_base;
+
}
+
/*============================================================================
* Transmit interrupt handler.
- * o print a warning
- * o
- * If number of spurious interrupts exceeded some limit, then ???
*/
-static void tx_intr(sdla_t * card)
+static void tx_intr(sdla_t *card)
{
- struct net_device *dev = card->wandev.dev;
- if (card->intr_mode == BUFFER_INTR_MODE)
- {
- for (; dev; dev = dev->slave)
- {
- if (!dev || !dev->start)
- {
- ++card->statistics.tx_intr_dev_not_started;
- continue;
+ fr508_flags_t* flags = card->flags;
+ fr_tx_buf_ctl_t* bctl;
+ struct net_device* dev = card->wandev.dev;
+ fr_channel_t* chan;
+
+ if(card->hw.type == SDLA_S514){
+ bctl = (void*)(flags->tse_offs + card->hw.dpmbase);
+ }else{
+ bctl = (void*)(flags->tse_offs - FR_MB_VECTOR +
+ card->hw.dpmbase);
+ }
+
+ /* Find the structure and make it unbusy */
+ dev = find_channel(card, flags->dlci);
+ chan = dev->priv;
+
+ if(!chan->transmit_length) {
+ printk(KERN_INFO "%s: tx int error - transmit length zero\n",
+ card->wandev.name);
+ return;
+ }
+
+ /* If the 'if_send()' procedure is currently checking the 'tbusy'
+ status, then we cannot transmit. Instead, we configure the microcode
+ so as to re-issue this transmit interrupt at a later stage.
+ */
+ if (test_bit(2, (void*)&card->wandev.critical)) {
+ fr_dlci_interface_t* dlci_interface = chan->dlci_int_interface;
+ bctl->flag = 0xA0;
+ dlci_interface->gen_interrupt |= FR_INTR_TXRDY;
+ printk(KERN_INFO "%s: TX Interrupt Detected busy if_send\n",card->devname);
+
+ } else {
+ bctl->dlci = flags->dlci;
+ bctl->length = chan->transmit_length;
+ sdla_poke(&card->hw, bctl->offset, chan->transmit_buffer,
+ chan->transmit_length);
+ bctl->flag = 0xC0;
+
+ ++chan->ifstats.tx_packets;
+ ++card->wandev.stats.tx_packets;
+ chan->ifstats.tx_bytes += chan->transmit_length;
+ card->wandev.stats.tx_bytes += chan->transmit_length;
+ chan->transmit_length = 0;
+
+ /* if any other interfaces have transmit interrupts pending, */
+ /* do not disable the global transmit interrupt */
+ if(!(-- card->u.f.tx_interrupts_pending))
+ flags->imask &= ~FR_INTR_TXRDY;
+
+ dev->tbusy = 0;
+ mark_bh(NET_BH);
+ }
+}
+
+
+/*============================================================================
+ * Timer interrupt handler.
+ FIXME: update comments as we modify the code
+ * The timer interrupt is used for three purposes:
+ * 1) Processing udp calls from 'fpipemon'.
+ * 2) Processing update calls from /proc file system
+ * 2) Reading board-level statistics for updating the proc file system.
+ * 3) Sending inverse ARP request packets.
+ */
+static void timer_intr(sdla_t *card)
+{
+ fr508_flags_t* flags = card->flags;
+
+ if(card->u.f.timer_int_enabled & TMR_INT_ENABLED_UDP) {
+ if(card->u.f.udp_type == UDP_FPIPE_TYPE) {
+ if(process_udp_mgmt_pkt(card)) {
+ card->u.f.timer_int_enabled &=
+ ~TMR_INT_ENABLED_UDP;
}
- dev->tbusy = 0;
- mark_bh(NET_BH);
}
+ }
+
+ if(card->u.f.timer_int_enabled & TMR_INT_ENABLED_UPDATE) {
+ fr_get_err_stats(card);
+ fr_get_stats(card);
+ card->u.f.update_comms_stats = 0;
+ card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE;
}
- else
- {
- dev->tbusy = 0;
- mark_bh(NET_BH);
+
+
+//FIXME: Fix the dynamic IP addressing
+/*
+goto L4;
+
+ // Used to send inarp request at given interval
+ if (card->wandev.state == WAN_CONNECTED) {
+ int num_remaining = 0;
+ for (dev=card->wandev.dev;dev;dev=dev->slave) {
+ fr_channel_t *chan = dev->priv;
+
+ if (chan->inarp == INARP_REQUEST &&
+ chan->state == WAN_CONNECTED) {
+ num_remaining++;
+
+ if ((jiffies - chan->inarp_tick) > (chan->inarp_interval * HZ)) {
+ send_inarp_request(card,dev);
+ chan->inarp_tick = jiffies;
+ }
+ }
+ }
+ if (!num_remaining) { // no more to process
+ flags->imask &= ~FR_INTR_TIMER;
+ }
}
+L4:
+ ;
+*/
+ if(!card->u.f.timer_int_enabled)
+ flags->imask &= ~FR_INTR_TIMER;
}
+
/*============================================================================
* Spurious interrupt handler.
* o print a warning
* o
- * If number of spurious interrupts exceeded some limit, then ???
*/
-
-static void spur_intr(sdla_t * card)
+static void spur_intr (sdla_t* card)
{
printk(KERN_INFO "%s: spurious interrupt!\n", card->devname);
}
-/*
- Return 0 for non-IPXWAN packet
- 1 for IPXWAN packet or IPX is not enabled!
+//FIXME: Fix the IPX in next version
+/*===========================================================================
+ * Return 0 for non-IPXWAN packet
+ * 1 for IPXWAN packet or IPX is not enabled!
+ * FIXME: Use a IPX structure here not offsets
*/
-
static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number)
{
int i;
- if (sendpacket[1] == 0x00 &&
+
+ if( sendpacket[1] == 0x00 &&
sendpacket[2] == 0x80 &&
sendpacket[6] == 0x81 &&
- sendpacket[7] == 0x37)
- {
+ sendpacket[7] == 0x37) {
+
/* It's an IPX packet */
- if (!enable_IPX) {
+ if(!enable_IPX) {
/* Return 1 so we don't pass it up the stack. */
+ //FIXME: Take this out when IPX is fixed
+ printk (KERN_INFO
+ "%s: WARNING: Unsupported IPX packet received and dropped\n",
+ devname);
return 1;
}
- }
- else
- {
+ } else {
/* It's not IPX so return and pass it up the stack. */
return 0;
}
- if (sendpacket[24] == 0x90 &&
- sendpacket[25] == 0x04)
+
+ if( sendpacket[24] == 0x90 &&
+ sendpacket[25] == 0x04)
{
/* It's IPXWAN */
- if (sendpacket[10] == 0x02 &&
- sendpacket[42] == 0x00)
+
+ if( sendpacket[10] == 0x02 &&
+ sendpacket[42] == 0x00)
{
/* It's a timer request packet */
- printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n", devname);
- /* Go through the routing options and answer no to every */
- /* option except Unnumbered RIP/SAP */
- for (i = 49; sendpacket[i] == 0x00; i += 5)
+ printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n",devname);
+
+ /* Go through the routing options and answer no to every
+ * option except Unnumbered RIP/SAP
+ */
+ for(i = 49; sendpacket[i] == 0x00; i += 5)
{
/* 0x02 is the option for Unnumbered RIP/SAP */
- if (sendpacket[i + 4] != 0x02)
+ if( sendpacket[i + 4] != 0x02)
{
sendpacket[i + 1] = 0;
}
}
+
/* Skip over the extended Node ID option */
- if (sendpacket[i] == 0x04)
+ if( sendpacket[i] == 0x04 )
+ {
i += 8;
- /* We also want to turn off all header compression opt. */
- for (; sendpacket[i] == 0x80;)
+ }
+
+ /* We also want to turn off all header compression opt.
+ */
+ for(; sendpacket[i] == 0x80 ;)
{
sendpacket[i + 1] = 0;
i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4;
}
+
/* Set the packet type to timer response */
sendpacket[42] = 0x01;
- printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n", devname);
+
+ printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n",devname);
}
- else if (sendpacket[42] == 0x02)
+ else if( sendpacket[42] == 0x02 )
{
/* This is an information request packet */
- printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n", devname);
+ printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n",devname);
+
/* Set the packet type to information response */
sendpacket[42] = 0x03;
+
/* Set the router name */
sendpacket[59] = 'F';
sendpacket[60] = 'P';
@@ -1756,465 +2082,558 @@ static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char
sendpacket[63] = 'E';
sendpacket[64] = '-';
sendpacket[65] = CVHexToAscii(network_number >> 28);
- sendpacket[66] = CVHexToAscii((network_number & 0x0F000000) >> 24);
- sendpacket[67] = CVHexToAscii((network_number & 0x00F00000) >> 20);
- sendpacket[68] = CVHexToAscii((network_number & 0x000F0000) >> 16);
- sendpacket[69] = CVHexToAscii((network_number & 0x0000F000) >> 12);
- sendpacket[70] = CVHexToAscii((network_number & 0x00000F00) >> 8);
- sendpacket[71] = CVHexToAscii((network_number & 0x000000F0) >> 4);
+ sendpacket[66] = CVHexToAscii((network_number & 0x0F000000)>> 24);
+ sendpacket[67] = CVHexToAscii((network_number & 0x00F00000)>> 20);
+ sendpacket[68] = CVHexToAscii((network_number & 0x000F0000)>> 16);
+ sendpacket[69] = CVHexToAscii((network_number & 0x0000F000)>> 12);
+ sendpacket[70] = CVHexToAscii((network_number & 0x00000F00)>> 8);
+ sendpacket[71] = CVHexToAscii((network_number & 0x000000F0)>> 4);
sendpacket[72] = CVHexToAscii(network_number & 0x0000000F);
- for (i = 73; i < 107; i += 1)
+ for(i = 73; i < 107; i+= 1)
+ {
sendpacket[i] = 0;
- printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n", devname);
+ }
+
+ printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n",devname);
}
else
{
- printk(KERN_INFO "%s: Unknown IPXWAN packet!\n", devname);
+ printk(KERN_INFO "%s: Unknown IPXWAN packet!\n",devname);
return 0;
}
+
/* Set the WNodeID to our network address */
- sendpacket[43] = (unsigned char) (network_number >> 24);
- sendpacket[44] = (unsigned char) ((network_number & 0x00FF0000) >> 16);
- sendpacket[45] = (unsigned char) ((network_number & 0x0000FF00) >> 8);
- sendpacket[46] = (unsigned char) (network_number & 0x000000FF);
+ sendpacket[43] = (unsigned char)(network_number >> 24);
+ sendpacket[44] = (unsigned char)((network_number & 0x00FF0000) >> 16);
+ sendpacket[45] = (unsigned char)((network_number & 0x0000FF00) >> 8);
+ sendpacket[46] = (unsigned char)(network_number & 0x000000FF);
+
return 1;
}
- /* If we get here, its an IPX-data packet so it'll get passed up the stack. */
- /* switch the network numbers */
- switch_net_numbers(sendpacket, network_number, 1);
+
+ /* If we get here, its an IPX-data packet so it'll get passed up the
+ * stack.
+ * switch the network numbers
+ */
+ switch_net_numbers(sendpacket, network_number ,1);
return 0;
}
-
-/****** Background Polling Routines ****************************************/
-
/*============================================================================
- * Main polling routine.
- * This routine is repeatedly called by the WANPIPE 'thead' to allow for
- * time-dependent housekeeping work.
- *
- * o fetch asynchronous network events.
- *
- * Notes:
- * 1. This routine may be called on interrupt context with all interrupts
- * enabled. Beware!
- */
+ * Process Route.
+ * This routine is called as a polling routine to dynamically add/delete routes
+ * negotiated by inverse ARP. It is in this "task" because we don't want routes
+ * to be added while in interrupt context.
+*/
-static void wpf_poll(sdla_t * card)
+static void process_route (sdla_t* card)
{
-/* struct net_device* dev = card->wandev.dev; */
- fr508_flags_t *flags = card->flags;
- unsigned long host_cpu_flags;
- ++card->statistics.poll_entry;
- if (((jiffies - card->state_tick) < HZ) ||
- (card->intr_mode == INTR_TEST_MODE))
- return;
- disable_irq(card->hw.irq);
- ++card->irq_dis_poll_count;
- if (test_and_set_bit(0, (void *) &card->wandev.critical))
- {
- ++card->statistics.poll_already_critical;
- save_flags(host_cpu_flags);
- cli();
- if ((!card->irq_dis_if_send_count) &&
- (!(--card->irq_dis_poll_count)))
- enable_irq(card->hw.irq);
- restore_flags(host_cpu_flags);
- return;
- }
- card->wandev.critical = 0x11;
- ++card->statistics.poll_processed;
- /* This is to be changed later ??? */
- /*
- if( dev && dev->tbusy && !(flags->imask & 0x02) ) {
- printk(KERN_INFO "%s: Wpf_Poll: tbusy = 0x01, imask = 0x%02X\n", card->devname, flags->imask);
- }
- */
- if (flags->event)
- {
- fr_mbox_t *mbox = card->mbox;
- int err;
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
- mbox->cmd.command = FR_READ_STATUS;
- err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- if (err)
- fr_event(card, err, mbox);
- }
- card->wandev.critical = 0;
- save_flags(host_cpu_flags);
- cli();
- if ((!card->irq_dis_if_send_count) && (!(--card->irq_dis_poll_count)))
- enable_irq(card->hw.irq);
- restore_flags(host_cpu_flags);
- card->state_tick = jiffies;
+ struct net_device* dev;
+ struct in_device *in_dev;
+ struct rtentry route;
+ int err = 0;
+ mm_segment_t fs;
+
+
+ /* Dynamic Route adding/removing */
+ for (dev = card->wandev.dev; dev ; dev = dev->slave) {
+ if ( ((fr_channel_t*)dev->priv)->route_flag == ADD_ROUTE ||
+ ((fr_channel_t*)dev->priv)->route_flag == REMOVE_ROUTE ) {
+ fs = get_fs();
+
+ in_dev = dev->ip_ptr;
+
+ if( in_dev != NULL && in_dev->ifa_list != NULL) {
+ memset(&route, 0, sizeof(route));
+ route.rt_dev = dev->name;
+ route.rt_flags = 0;
+
+ ((struct sockaddr_in *) &(route.rt_dst)) ->
+ sin_addr.s_addr=in_dev->ifa_list->ifa_address;
+ ((struct sockaddr_in *) &(route.rt_dst)) ->
+ sin_family = AF_INET;
+ ((struct sockaddr_in *) &(route.rt_genmask)) ->
+ sin_addr.s_addr = 0xFFFFFFFF;
+ ((struct sockaddr_in *) &(route.rt_genmask)) ->
+ sin_family = AF_INET;
+
+ switch(((fr_channel_t*)dev->priv)->route_flag) {
+
+ case ADD_ROUTE:
+ set_fs(get_ds()); /* get user space block */
+ err = ip_rt_ioctl( SIOCADDRT, &route);
+ set_fs(fs); /* restore old block */
+
+ if (err) {
+ printk(KERN_INFO "%s: Adding of route failed. Error: %d\n", card->devname,err);
+ printk(KERN_INFO "%s: Address: %s\n",
+ ((fr_channel_t*)dev->priv)->name,
+ in_ntoa(in_dev->ifa_list->ifa_address) );
+ }
+ else {
+ ((fr_channel_t*)dev->priv)->
+ route_flag = ROUTE_ADDED;
+ }
+ break;
+
+ case REMOVE_ROUTE:
+ set_fs(get_ds()); /* get user space block */
+ err = ip_rt_ioctl( SIOCDELRT, &route);
+ set_fs(fs); /* restore old block */
+
+ if (err) {
+ printk(KERN_INFO "%s: Deleting of route failed. Error: %d\n", card->devname,err);
+ printk(KERN_INFO "%s: Address: %s\n",
+ dev->name,in_ntoa(in_dev->ifa_list->ifa_address) );
+ } else {
+ printk(KERN_INFO "%s: Removed route.\n",
+ ((fr_channel_t*)dev->priv)->name);
+ ((fr_channel_t*)dev->priv)->route_flag = NO_ROUTE;
+ }
+ break;
+ } /* Case Statement */
+ }
+ } /* If ADD/DELETE ROUTE */
+ } /* Device 'For' Loop */
+
+ card->poll = NULL;
}
+
+
/****** Frame Relay Firmware-Specific Functions *****************************/
/*============================================================================
* Read firmware code version.
* o fill string str with firmware version info.
*/
-
-static int fr_read_version(sdla_t * card, char *str)
+static int fr_read_version (sdla_t* card, char* str)
{
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox;
int retry = MAX_CMD_RETRY;
int err;
- do
+
+ do
{
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
mbox->cmd.command = FR_READ_CODE_VERSION;
+ mbox->cmd.length = 0;
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
} while (err && retry-- && fr_event(card, err, mbox));
- if (!err && str)
- {
+ if (!err && str) {
int len = mbox->cmd.length;
memcpy(str, mbox->data, len);
- str[len] = '\0';
+ str[len] = '\0';
}
return err;
}
+
/*============================================================================
* Set global configuration.
*/
-
-static int fr_configure(sdla_t * card, fr_conf_t * conf)
+static int fr_configure (sdla_t* card, fr_conf_t *conf)
{
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox;
int retry = MAX_CMD_RETRY;
int dlci_num = card->u.f.dlci_num;
int err, i;
- do
+
+ do
{
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
memcpy(mbox->data, conf, sizeof(fr_conf_t));
- if (dlci_num)
- for (i = 0; i < dlci_num; ++i)
- ((fr_conf_t *) mbox->data)->dlci[i] =
- card->u.f.node_dlci[i];
+
+ if (dlci_num) for (i = 0; i < dlci_num; ++i)
+ ((fr_conf_t*)mbox->data)->dlci[i] =
+ card->u.f.node_dlci[i];
+
mbox->cmd.command = FR_SET_CONFIG;
mbox->cmd.length =
- sizeof(fr_conf_t) + dlci_num * sizeof(short);
+ sizeof(fr_conf_t) + dlci_num * sizeof(short);
+
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && retry-- && fr_event(card, err, mbox));
+
+ } while (err && retry-- && fr_event(card, err, mbox));
return err;
}
+
/*============================================================================
* Set DLCI configuration.
*/
-static int fr_dlci_configure(sdla_t * card, fr_dlc_conf_t * conf, unsigned dlci)
+static int fr_dlci_configure (sdla_t* card, fr_dlc_conf_t *conf, unsigned dlci)
{
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox;
int retry = MAX_CMD_RETRY;
int err;
+
do
{
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
memcpy(mbox->data, conf, sizeof(fr_dlc_conf_t));
- mbox->cmd.dlci = (unsigned short) dlci;
+ mbox->cmd.dlci = (unsigned short) dlci;
mbox->cmd.command = FR_SET_CONFIG;
- mbox->cmd.length = 0x0E;
+ mbox->cmd.length = sizeof(fr_dlc_conf_t);
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && retry--);
+ } while (err && retry--);
+
return err;
}
/*============================================================================
* Set interrupt mode.
*/
-static int fr_set_intr_mode(sdla_t * card, unsigned mode, unsigned mtu)
+static int fr_set_intr_mode (sdla_t* card, unsigned mode, unsigned mtu,
+ unsigned short timeout)
{
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox;
+ fr508_intr_ctl_t* ictl = (void*)mbox->data;
int retry = MAX_CMD_RETRY;
int err;
+
do
{
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
- if (card->hw.fwid == SFID_FR502)
- {
- fr502_intr_ctl_t *ictl = (void *) mbox->data;
- memset(ictl, 0, sizeof(fr502_intr_ctl_t));
- ictl->mode = mode;
- ictl->tx_len = mtu;
- mbox->cmd.length = sizeof(fr502_intr_ctl_t);
- }
- else
- {
- fr508_intr_ctl_t *ictl = (void *) mbox->data;
- memset(ictl, 0, sizeof(fr508_intr_ctl_t));
- ictl->mode = mode;
- ictl->tx_len = mtu;
- ictl->irq = card->hw.irq;
- mbox->cmd.length = sizeof(fr508_intr_ctl_t);
- }
+ memset(ictl, 0, sizeof(fr508_intr_ctl_t));
+ ictl->mode = mode;
+ ictl->tx_len = mtu;
+ ictl->irq = card->hw.irq;
+
+ /* indicate timeout on timer */
+ if (mode & 0x20) ictl->timeout = timeout;
+
+ mbox->cmd.length = sizeof(fr508_intr_ctl_t);
mbox->cmd.command = FR_SET_INTR_MODE;
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && retry-- && fr_event(card, err, mbox));
+
+ } while (err && retry-- && fr_event(card, err, mbox));
return err;
}
+
/*============================================================================
* Enable communications.
*/
-static int fr_comm_enable(sdla_t * card)
+static int fr_comm_enable (sdla_t* card)
{
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox;
int retry = MAX_CMD_RETRY;
int err;
- do
+
+ do
{
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
mbox->cmd.command = FR_COMM_ENABLE;
+ mbox->cmd.length = 0;
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && retry-- && fr_event(card, err, mbox));
+ } while (err && retry-- && fr_event(card, err, mbox));
return err;
}
+
/*============================================================================
* Disable communications.
*/
-static int fr_comm_disable(sdla_t * card)
+static int fr_comm_disable (sdla_t* card)
{
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox;
int retry = MAX_CMD_RETRY;
int err;
+
do
{
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
mbox->cmd.command = FR_COMM_DISABLE;
+ mbox->cmd.length = 0;
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && retry-- && fr_event(card, err, mbox));
+ } while (err && retry-- && fr_event(card, err, mbox));
+
+ retry = MAX_CMD_RETRY;
+
+ do {
+ mbox->cmd.command = FR_SET_MODEM_STATUS;
+ mbox->cmd.length = 1;
+ mbox->data[0] = 0;
+ err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
+ } while (err && retry-- && fr_event(card, err, mbox));
return err;
}
+
/*============================================================================
* Get communications error statistics.
*/
-static int fr_get_err_stats(sdla_t * card)
+static int fr_get_err_stats (sdla_t* card)
{
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox;
int retry = MAX_CMD_RETRY;
int err;
-
+
+
do
{
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
mbox->cmd.command = FR_READ_ERROR_STATS;
+ mbox->cmd.length = 0;
+ mbox->cmd.dlci = 0;
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && retry-- && fr_event(card, err, mbox));
-
- if (!err)
- {
- fr_comm_stat_t *stats = (void *) mbox->data;
- card->wandev.stats.rx_over_errors = stats->rx_overruns;
- card->wandev.stats.rx_crc_errors = stats->rx_bad_crc;
- card->wandev.stats.rx_missed_errors = stats->rx_aborts;
- card->wandev.stats.rx_length_errors = stats->rx_too_long;
+ } while (err && retry-- && fr_event(card, err, mbox));
+
+ if (!err) {
+ fr_comm_stat_t* stats = (void*)mbox->data;
+ card->wandev.stats.rx_over_errors = stats->rx_overruns;
+ card->wandev.stats.rx_crc_errors = stats->rx_bad_crc;
+ card->wandev.stats.rx_missed_errors = stats->rx_aborts;
+ card->wandev.stats.rx_length_errors = stats->rx_too_long;
card->wandev.stats.tx_aborted_errors = stats->tx_aborts;
+
}
+
return err;
}
+
/*============================================================================
* Get statistics.
*/
-static int fr_get_stats(sdla_t * card)
+static int fr_get_stats (sdla_t* card)
{
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox;
int retry = MAX_CMD_RETRY;
int err;
- do
+
+
+ do
{
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
mbox->cmd.command = FR_READ_STATISTICS;
+ mbox->cmd.length = 0;
+ mbox->cmd.dlci = 0;
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && retry-- && fr_event(card, err, mbox));
-
- if (!err)
- {
- fr_link_stat_t *stats = (void *) mbox->data;
+ } while (err && retry-- && fr_event(card, err, mbox));
+
+ if (!err) {
+ fr_link_stat_t* stats = (void*)mbox->data;
card->wandev.stats.rx_frame_errors = stats->rx_bad_format;
- card->wandev.stats.rx_dropped = stats->rx_dropped + stats->rx_dropped2;
+ card->wandev.stats.rx_dropped =
+ stats->rx_dropped + stats->rx_dropped2;
}
+
return err;
}
+
/*============================================================================
* Add DLCI(s) (Access Node only!).
* This routine will perform the ADD_DLCIs command for the specified DLCI.
*/
-static int fr_add_dlci(sdla_t * card, int dlci, int num)
+static int fr_add_dlci (sdla_t* card, int dlci)
{
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox;
int retry = MAX_CMD_RETRY;
- int err, i;
- do
+ int err;
+
+ do
{
- unsigned short *dlci_list = (void *) mbox->data;
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
- for (i = 0; i < num; ++i)
- dlci_list[i] = card->u.f.node_dlci[i];
- mbox->cmd.length = num * sizeof(short);
+ unsigned short* dlci_list = (void*)mbox->data;
+
+ mbox->cmd.length = sizeof(short);
+ dlci_list[0] = dlci;
mbox->cmd.command = FR_ADD_DLCI;
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && retry-- && fr_event(card, err, mbox));
+
+ } while (err && retry-- && fr_event(card, err, mbox));
return err;
}
+
/*============================================================================
* Activate DLCI(s) (Access Node only!).
- * This routine will perform the ACTIVATE_DLCIs command with a list of DLCIs.
+ * This routine will perform the ACTIVATE_DLCIs command with a DLCI number.
*/
-static int fr_activate_dlci(sdla_t * card, int dlci, int num)
+static int fr_activate_dlci (sdla_t* card, int dlci)
{
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox;
int retry = MAX_CMD_RETRY;
- int err, i;
+ int err;
+
do
{
- unsigned short *dlci_list = (void *) mbox->data;
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
- for (i = 0; i < num; ++i)
- dlci_list[i] = card->u.f.node_dlci[i];
- mbox->cmd.length = num * sizeof(short);
+ unsigned short* dlci_list = (void*)mbox->data;
+
+ mbox->cmd.length = sizeof(short);
+ dlci_list[0] = dlci;
mbox->cmd.command = FR_ACTIVATE_DLCI;
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && retry-- && fr_event(card, err, mbox));
+
+ } while (err && retry-- && fr_event(card, err, mbox));
return err;
}
+
/*============================================================================
- * Issue in-channel signalling frame.
+ * Delete DLCI(s) (Access Node only!).
+ * This routine will perform the DELETE_DLCIs command with a DLCI number.
*/
-static int fr_issue_isf(sdla_t * card, int isf)
+static int fr_delete_dlci (sdla_t* card, int dlci)
{
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox;
int retry = MAX_CMD_RETRY;
int err;
+
do
{
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
- mbox->data[0] = isf;
- mbox->cmd.length = 1;
- mbox->cmd.command = FR_ISSUE_IS_FRAME;
+ unsigned short* dlci_list = (void*)mbox->data;
+
+ mbox->cmd.length = sizeof(short);
+ dlci_list[0] = dlci;
+ mbox->cmd.command = FR_DELETE_DLCI;
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && retry-- && fr_event(card, err, mbox));
+
+ } while (err && retry-- && fr_event(card, err, mbox));
return err;
}
+
+
+
/*============================================================================
- * Send a frame (S502 version).
+ * Issue in-channel signalling frame.
*/
-static int fr502_send(sdla_t * card, int dlci, int attr, int len, void *buf)
+static int fr_issue_isf (sdla_t* card, int isf)
{
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox;
int retry = MAX_CMD_RETRY;
int err;
-
- do
+
+ do
{
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
- memcpy(mbox->data, buf, len);
- mbox->cmd.dlci = dlci;
- mbox->cmd.attr = attr;
- mbox->cmd.length = len;
- mbox->cmd.command = FR_WRITE;
+ mbox->data[0] = isf;
+ mbox->cmd.length = 1;
+ mbox->cmd.command = FR_ISSUE_IS_FRAME;
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && retry-- && fr_event(card, err, mbox));
+ } while (err && retry-- && fr_event(card, err, mbox));
return err;
}
+
/*============================================================================
- * Send a frame (S508 version).
+ * Send a frame on a selected DLCI.
*/
-static int fr508_send(sdla_t * card, int dlci, int attr, int len, void *buf)
+static int fr_send (sdla_t* card, int dlci, unsigned char attr, int len,
+ void *buf)
{
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox + 0x800;
int retry = MAX_CMD_RETRY;
int err;
-
+
do
{
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
- mbox->cmd.dlci = dlci;
- mbox->cmd.attr = attr;
- mbox->cmd.length = len;
+ mbox->cmd.dlci = dlci;
+ mbox->cmd.attr = attr;
+ mbox->cmd.length = len;
mbox->cmd.command = FR_WRITE;
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && retry-- && fr_event(card, err, mbox));
-
- if (!err)
- {
- fr_buf_ctl_t *frbuf = (void *) (*(unsigned long *) mbox->data -
- FR_MB_VECTOR + card->hw.dpmbase);
+ } while (err && retry-- && fr_event(card, err, mbox));
+
+ if (!err) {
+
+ fr_tx_buf_ctl_t* frbuf;
+
+ if(card->hw.type == SDLA_S514)
+ frbuf = (void*)(*(unsigned long*)mbox->data +
+ card->hw.dpmbase);
+ else
+ frbuf = (void*)(*(unsigned long*)mbox->data -
+ FR_MB_VECTOR + card->hw.dpmbase);
+
sdla_poke(&card->hw, frbuf->offset, buf, len);
frbuf->flag = 0x01;
}
+
return err;
}
/****** Firmware Asynchronous Event Handlers ********************************/
/*============================================================================
- * Main asynchronous event/error handler.
+ * Main asyncronous event/error handler.
* This routine is called whenever firmware command returns non-zero
* return code.
*
* Return zero if previous command has to be cancelled.
*/
-
-static int fr_event(sdla_t * card, int event, fr_mbox_t * mbox)
+static int fr_event (sdla_t *card, int event, fr_mbox_t* mbox)
{
- fr508_flags_t *flags = card->flags;
+ fr508_flags_t* flags = card->flags;
char *ptr = &flags->iflag;
int i;
- switch (event)
- {
+
+ switch (event) {
+
case FRRES_MODEM_FAILURE:
return fr_modem_failure(card, mbox);
+
case FRRES_CHANNEL_DOWN:
+ {
+ struct net_device *dev;
+
+ /* Remove all routes from associated DLCI's */
+ for (dev = card->wandev.dev; dev; dev = dev->slave) {
+ fr_channel_t *chan = dev->priv;
+ if (chan->route_flag == ROUTE_ADDED) {
+ chan->route_flag = REMOVE_ROUTE;
+ card->poll = &process_route;
+ }
+
+ if (chan->inarp == INARP_CONFIGURED) {
+ chan->inarp = INARP_REQUEST;
+ }
+ }
+
wanpipe_set_state(card, WAN_DISCONNECTED);
return 1;
+ }
+
case FRRES_CHANNEL_UP:
+ {
+ struct net_device *dev;
+ int num_requests = 0;
+
+ /* Remove all routes from associated DLCI's */
+ for (dev = card->wandev.dev; dev; dev = dev->slave) {
+ fr_channel_t *chan = dev->priv;
+ if( chan->inarp == INARP_REQUEST ){
+ num_requests++;
+ chan->inarp_tick = jiffies;
+ }
+ }
+
+ /* Allow timer interrupts */
+ if (num_requests) flags->imask |= 0x20;
wanpipe_set_state(card, WAN_CONNECTED);
return 1;
+ }
+
case FRRES_DLCI_CHANGE:
return fr_dlci_change(card, mbox);
+
case FRRES_DLCI_MISMATCH:
- printk(KERN_INFO "%s: DLCI list mismatch!\n",
- card->devname);
+ printk(KERN_INFO "%s: DLCI list mismatch!\n",
+ card->devname);
return 1;
+
case CMD_TIMEOUT:
printk(KERN_ERR "%s: command 0x%02X timed out!\n",
- card->devname, mbox->cmd.command);
- printk(KERN_INFO "%s: ID Bytes = ", card->devname);
- for (i = 0; i < 8; i++)
- printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));
- printk(KERN_INFO "\n");
+ card->devname, mbox->cmd.command);
+ printk(KERN_INFO "%s: ID Bytes = ",card->devname);
+ for(i = 0; i < 8; i ++)
+ printk(KERN_INFO "0x%02X ", *(ptr + 0x18 + i));
+ printk(KERN_INFO "\n");
+
break;
+
case FRRES_DLCI_INACTIVE:
- printk(KERN_ERR "%s: DLCI %u is inactive!\n",
- card->devname, mbox->cmd.dlci);
break;
+
case FRRES_CIR_OVERFLOW:
break;
case FRRES_BUFFER_OVERFLOW:
- break;
+ break;
default:
printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n"
- ,card->devname, mbox->cmd.command, event);
+ , card->devname, mbox->cmd.command, event);
}
+
return 0;
}
@@ -2223,178 +2642,228 @@ static int fr_event(sdla_t * card, int event, fr_mbox_t * mbox)
*
* Return zero if previous command has to be cancelled.
*/
-static int fr_modem_failure(sdla_t * card, fr_mbox_t * mbox)
+static int fr_modem_failure (sdla_t *card, fr_mbox_t* mbox)
{
printk(KERN_INFO "%s: physical link down! (modem error 0x%02X)\n",
- card->devname, mbox->data[0]);
- switch (mbox->cmd.command)
- {
+ card->devname, mbox->data[0]);
+
+ switch (mbox->cmd.command){
case FR_WRITE:
+
case FR_READ:
return 0;
}
+
return 1;
}
+
/*============================================================================
* Handle DLCI status change.
*
* Return zero if previous command has to be cancelled.
*/
-static int fr_dlci_change(sdla_t * card, fr_mbox_t * mbox)
+static int fr_dlci_change (sdla_t *card, fr_mbox_t* mbox)
{
- dlci_status_t *status = (void *) mbox->data;
+ dlci_status_t* status = (void*)mbox->data;
int cnt = mbox->cmd.length / sizeof(dlci_status_t);
- fr_dlc_conf_t cfg;
fr_channel_t *chan;
- struct net_device *dev2;
- for (; cnt; --cnt, ++status)
- {
- unsigned short dlci = status->dlci;
- struct net_device *dev = find_channel(card, dlci);
- if (dev == NULL)
- {
- printk(KERN_INFO
- "%s: CPE contains unconfigured DLCI= %d\n",
- card->devname, dlci);
- }
- else
- {
- if (status->state & 0x01)
- {
+ struct net_device* dev2;
+
+
+ for (; cnt; --cnt, ++status) {
+
+ unsigned short dlci= status->dlci;
+ struct net_device* dev = find_channel(card, dlci);
+
+ if (dev == NULL){
+ printk(KERN_INFO
+ "%s: CPE contains unconfigured DLCI= %d\n",
+ card->devname, dlci);
+
+ printk(KERN_INFO
+ "%s: unconfigured DLCI %d reported by network\n"
+ , card->devname, dlci);
+
+ }else{
+ if (status->state == FR_LINK_INOPER) {
printk(KERN_INFO
- "%s: DLCI %u has been deleted!\n",
- card->devname, dlci);
+ "%s: DLCI %u is inactive!\n",
+ card->devname, dlci);
+
if (dev && dev->start)
set_chan_state(dev, WAN_DISCONNECTED);
}
- else if (status->state & 0x02)
- {
+
+ if (status->state & FR_DLCI_DELETED) {
+
printk(KERN_INFO
- "%s: DLCI %u becomes active!\n",
- card->devname, dlci);
+ "%s: DLCI %u has been deleted!\n",
+ card->devname, dlci);
+
+ if (dev && dev->start) {
+ fr_channel_t *chan = dev->priv;
+
+ if (chan->route_flag == ROUTE_ADDED) {
+ chan->route_flag = REMOVE_ROUTE;
+ card->poll = &process_route;
+ }
+
+ if (chan->inarp == INARP_CONFIGURED) {
+ chan->inarp = INARP_REQUEST;
+ }
+
+ set_chan_state(dev, WAN_DISCONNECTED);
+ }
+
+ } else if (status->state & FR_DLCI_ACTIVE) {
+
chan = dev->priv;
+
/* This flag is used for configuring specific
DLCI(s) when they become active.
- */
+ */
chan->dlci_configured = DLCI_CONFIG_PENDING;
+
if (dev && dev->start)
set_chan_state(dev, WAN_CONNECTED);
+
}
}
}
- for (dev2 = card->wandev.dev; dev2; dev2 = dev2->slave)
- {
+
+ for (dev2 =card->wandev.dev; dev2; dev2 = dev2->slave){
+
chan = dev2->priv;
- if (chan->dlci_configured == DLCI_CONFIG_PENDING)
- {
- memset(&cfg, 0, sizeof(cfg));
- if (chan->cir_status == CIR_DISABLED)
- {
- cfg.cir_fwd = cfg.cir_bwd = 16;
- cfg.bc_fwd = cfg.bc_bwd = 16;
- cfg.conf_flags = 0x0001;
- printk(KERN_INFO "%s: CIR Disabled for %s\n",
- card->devname, chan->name);
- } else if (chan->cir_status == CIR_ENABLED) {
- cfg.cir_fwd = cfg.cir_bwd = chan->cir;
- cfg.bc_fwd = cfg.bc_bwd = chan->bc;
- cfg.be_fwd = cfg.be_bwd = chan->be;
- cfg.conf_flags = 0x0000;
- printk(KERN_INFO "%s: CIR Enabled for %s\n",
- card->devname, chan->name);
- }
- if (fr_dlci_configure(card, &cfg, chan->dlci))
- {
- printk(KERN_INFO
- "%s: DLCI Configure failed for %d\n",
- card->devname, chan->dlci);
+
+ if (chan->dlci_configured == DLCI_CONFIG_PENDING) {
+ if (fr_init_dlci(card, chan)){
return 1;
}
- chan->dlci_configured = DLCI_CONFIGURED;
- /* Read the interface byte mapping into the channel
- structure.
- */
- if (card->intr_mode == DLCI_LIST_INTR_MODE)
- read_DLCI_IB_mapping(card, chan);
}
+
}
return 1;
}
+
+
+static int fr_init_dlci (sdla_t *card, fr_channel_t *chan)
+{
+ fr_dlc_conf_t cfg;
+ fr508_flags_t* flags = card->flags;
+
+ memset(&cfg, 0, sizeof(cfg));
+
+ if ( chan->cir_status == CIR_DISABLED) {
+
+ cfg.cir_fwd = cfg.cir_bwd = 16;
+ cfg.bc_fwd = cfg.bc_bwd = 16;
+ cfg.conf_flags = 0x0001;
+
+ }else if (chan->cir_status == CIR_ENABLED) {
+
+ cfg.cir_fwd = cfg.cir_bwd = chan->cir;
+ cfg.bc_fwd = cfg.bc_bwd = chan->bc;
+ cfg.be_fwd = cfg.be_bwd = chan->be;
+ cfg.conf_flags = 0x0000;
+ }
+
+ if (fr_dlci_configure( card, &cfg , chan->dlci)){
+ printk(KERN_INFO
+ "%s: DLCI Configure failed for %d\n",
+ card->devname, chan->dlci);
+ return 1;
+ }
+
+ chan->dlci_configured = DLCI_CONFIGURED;
+
+ /* Allow timer interrupts */
+ if( chan->inarp == INARP_REQUEST && card->wandev.state == WAN_CONNECTED) {
+ chan->inarp_tick = jiffies;
+ flags->imask |= 0x20;
+ }
+
+ /* Read the interface byte mapping into the channel
+ structure.
+ */
+ read_DLCI_IB_mapping( card, chan );
+
+ return 0;
+}
/******* Miscellaneous ******************************************************/
/*============================================================================
* Update channel state.
*/
-static int update_chan_state(struct net_device *dev)
+static int update_chan_state (struct net_device* dev)
{
- fr_channel_t *chan = dev->priv;
- sdla_t *card = chan->card;
- fr_mbox_t *mbox = card->mbox;
+ fr_channel_t* chan = dev->priv;
+ sdla_t* card = chan->card;
+ fr_mbox_t* mbox = card->mbox;
int retry = MAX_CMD_RETRY;
int err;
- int dlci_found = 0;
- do
+ do
{
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
mbox->cmd.command = FR_LIST_ACTIVE_DLCI;
+ mbox->cmd.length = 0;
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && retry-- && fr_event(card, err, mbox));
+ } while (err && retry-- && fr_event(card, err, mbox));
- if (!err)
- {
- unsigned short *list = (void *) mbox->data;
+ if (!err) {
+
+ unsigned short* list = (void*)mbox->data;
int cnt = mbox->cmd.length / sizeof(short);
- for (; cnt; --cnt, ++list)
- {
- if (*list == chan->dlci)
- {
- dlci_found = 1;
- set_chan_state(dev, WAN_CONNECTED);
+
+ for (; cnt; --cnt, ++list) {
+
+ if (*list == chan->dlci) {
+ set_chan_state(dev, WAN_CONNECTED);
break;
}
}
- if (!dlci_found)
- printk(KERN_INFO "%s: DLCI %u is inactive\n",
- card->devname, chan->dlci);
}
-
+
return err;
}
+
/*============================================================================
* Set channel state.
*/
-static void set_chan_state(struct net_device *dev, int state)
+static void set_chan_state (struct net_device* dev, int state)
{
- fr_channel_t *chan = dev->priv;
- sdla_t *card = chan->card;
+ fr_channel_t* chan = dev->priv;
+ sdla_t* card = chan->card;
unsigned long flags;
-
+
save_flags(flags);
cli();
-
- if (chan->state != state)
- {
- switch (state)
- {
+
+ if (chan->state != state) {
+
+ switch (state) {
+
case WAN_CONNECTED:
- printk(KERN_INFO "%s: interface %s connected!\n"
- ,card->devname, dev->name);
+ printk(KERN_INFO
+ "%s: Interface %s: DLCI %d connected\n",
+ card->devname, dev->name, chan->dlci);
break;
+
case WAN_CONNECTING:
- printk(KERN_INFO
- "%s: interface %s connecting...\n",
- card->devname, dev->name);
+ printk(KERN_INFO
+ "%s: Interface %s: DLCI %d connecting\n",
+ card->devname, dev->name, chan->dlci);
break;
+
case WAN_DISCONNECTED:
- printk(KERN_INFO
- "%s: interface %s disconnected!\n",
- card->devname, dev->name);
+ printk (KERN_INFO
+ "%s: Interface %s: DLCI %d disconnected!\n",
+ card->devname, dev->name, chan->dlci);
break;
}
+
chan->state = state;
}
+
chan->state_tick = jiffies;
restore_flags(flags);
}
@@ -2402,14 +2871,14 @@ static void set_chan_state(struct net_device *dev, int state)
/*============================================================================
* Find network device by its channel number.
*/
-static struct net_device *find_channel(sdla_t * card, unsigned dlci)
+static struct net_device* find_channel (sdla_t* card, unsigned dlci)
{
- struct net_device *dev;
- for (dev = card->wandev.dev; dev; dev = dev->slave)
- if (((fr_channel_t *) dev->priv)->dlci == dlci)
- break;
- return dev;
+ if(dlci > HIGHEST_VALID_DLCI)
+ return NULL;
+
+ return(card->u.f.dlci_to_dev_map[dlci]);
}
+
/*============================================================================
* Check to see if a frame can be sent. If no transmit buffers available,
* enable transmit interrupts.
@@ -2417,22 +2886,17 @@ static struct net_device *find_channel(sdla_t * card, unsigned dlci)
* Return: 1 - Tx buffer(s) available
* 0 - no buffers available
*/
-
-static int is_tx_ready(sdla_t * card, fr_channel_t * chan)
+static int is_tx_ready (sdla_t* card, fr_channel_t* chan)
{
- if (card->hw.fwid == SFID_FR508)
- {
- unsigned char sb = inb(card->hw.port);
- if (sb & 0x02)
- return 1;
- }
- else
- {
- fr502_flags_t *flags = card->flags;
- if (flags->tx_ready)
- return 1;
- flags->imask |= 0x02;
- }
+ unsigned char sb;
+
+ if(card->hw.type == SDLA_S514)
+ return 1;
+
+ sb = inb(card->hw.port);
+ if (sb & 0x02)
+ return 1;
+
return 0;
}
@@ -2440,688 +2904,790 @@ static int is_tx_ready(sdla_t * card, fr_channel_t * chan)
* Convert decimal string to unsigned integer.
* If len != 0 then only 'len' characters of the string are converted.
*/
-static unsigned int dec_to_uint(unsigned char *str, int len)
+static unsigned int dec_to_uint (unsigned char* str, int len)
{
unsigned val;
- if (!len)
+
+ if (!len)
len = strlen(str);
+
for (val = 0; len && is_digit(*str); ++str, --len)
- val = (val * 10) + (*str - (unsigned) '0');
+ val = (val * 10) + (*str - (unsigned)'0');
+
return val;
}
+
+
+/*=============================================================================
+ * Store a UDP management packet for later processing.
+ */
+
+static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t* card,
+ struct sk_buff *skb, int dlci)
+{
+ int udp_pkt_stored = 0;
+
+ if(!card->u.f.udp_pkt_lgth &&(skb->len <= MAX_LGTH_UDP_MGNT_PKT)){
+ card->u.f.udp_pkt_lgth = skb->len;
+ card->u.f.udp_type = udp_type;
+ card->u.f.udp_pkt_src = udp_pkt_src;
+ card->u.f.udp_dlci = dlci;
+ memcpy(card->u.f.udp_pkt_data, skb->data, skb->len);
+ card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UDP;
+ udp_pkt_stored = 1;
+
+ }else{
+ printk(KERN_INFO "ERROR: UDP packet not stored for DLCI %d\n",
+ dlci);
+ }
+
+ dev_kfree_skb(skb);
+
+ return(udp_pkt_stored);
+}
+
+
/*==============================================================================
* Process UDP call of type FPIPE8ND
*/
-
-static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan)
+static int process_udp_mgmt_pkt(sdla_t* card)
{
+
int c_retry = MAX_CMD_RETRY;
- unsigned char *data;
unsigned char *buf;
- unsigned char buf2[5];
- unsigned int loops, frames, len;
- unsigned long data_ptr;
- unsigned short real_len, buffer_length;
+ unsigned char frames;
+ unsigned int len;
+ unsigned short buffer_length;
struct sk_buff *new_skb;
- unsigned char *sendpacket;
- fr_mbox_t *mbox = card->mbox;
+ fr_mbox_t* mbox = card->mbox;
int err;
struct timeval tv;
int udp_mgmt_req_valid = 1;
- sendpacket = skb->data;
- memcpy(&buf2, &card->wandev.udp_port, 2);
- if ((data = kmalloc(2000, GFP_ATOMIC)) == NULL)
- {
- printk(KERN_INFO
- "%s: Error allocating memory for UDP management cmnd 0x%02X",
- card->devname, data[47]);
- ++chan->UDP_FPIPE_mgmt_kmalloc_err;
- return 1;
- }
- memcpy(data, sendpacket, skb->len);
- switch (data[47])
- {
- /* FPIPE_ENABLE_TRACE */
- case 0x41:
- /* FPIPE_DISABLE_TRACE */
- case 0x42:
- /* FPIPE_GET_TRACE_INFO */
- case 0x43:
- /* SET FT1 MODE */
- case 0x81:
- if (udp_pkt_src == UDP_PKT_FRM_NETWORK)
- {
- ++chan->UDP_FPIPE_mgmt_direction_err;
+ struct net_device* dev;
+ fr_channel_t* chan;
+ fr_udp_pkt_t *fr_udp_pkt;
+ unsigned short num_trc_els;
+ fr_trc_el_t* ptr_trc_el;
+ fr_trc_el_t trc_el;
+ fpipemon_trc_t* fpipemon_trc;
+
+ char udp_pkt_src = card->u.f.udp_pkt_src;
+ int dlci = card->u.f.udp_dlci;
+
+ /* Find network interface for this packet */
+ dev = find_channel(card, dlci);
+ chan = dev->priv;
+
+ /* If the UDP packet is from the network, we are going to have to
+ transmit a response. Before doing so, we must check to see that
+ we are not currently transmitting a frame (in 'if_send()') and
+ that we are not already in a 'delayed transmit' state.
+ */
+ if(udp_pkt_src == UDP_PKT_FRM_NETWORK) {
+ if (test_bit(0, (void*)&card->wandev.critical) ||
+ test_bit(2, (void*)&card->wandev.critical)) {
+ return 0;
+ }
+ if((dev->tbusy) || (card->u.f.tx_interrupts_pending)) {
+ return 0;
+ }
+ }
+
+ fr_udp_pkt = (fr_udp_pkt_t *)card->u.f.udp_pkt_data;
+
+ switch(fr_udp_pkt->cblock.command) {
+
+ case FPIPE_ENABLE_TRACING:
+ case FPIPE_DISABLE_TRACING:
+ case FPIPE_GET_TRACE_INFO:
+ case FR_SET_FT1_MODE:
+ if(udp_pkt_src == UDP_PKT_FRM_NETWORK) {
+ chan->drvstats_gen.
+ UDP_PIPE_mgmt_direction_err ++;
udp_mgmt_req_valid = 0;
break;
}
- /* FPIPE_FT1_READ_STATUS */
- case 0x44:
- /* FT1 MONITOR STATUS */
- case 0x80:
- if (card->hw.fwid != SFID_FR508)
- {
- ++chan->UDP_FPIPE_mgmt_adptr_type_err;
- udp_mgmt_req_valid = 0;
- }
- break;
+
default:
break;
- }
- if (!udp_mgmt_req_valid)
- {
+ }
+
+ if(!udp_mgmt_req_valid) {
/* set length to 0 */
- data[48] = data[49] = 0;
+ fr_udp_pkt->cblock.length = 0;
/* set return code */
- data[50] = (card->hw.fwid != SFID_FR508) ? 0x1F : 0xCD;
- }
- else
- {
- switch (data[47])
- {
- /* FPIPE_ENABLE_TRACE */
- case 0x41:
- if (!TracingEnabled)
- {
- do
- {
- /* SET_TRACE_CONFIGURATION */
- mbox->cmd.command = 0x60;
- mbox->cmd.length = 1;
- mbox->cmd.dlci = 0x00;
- mbox->data[0] = 0x37;
- err = sdla_exec(mbox) ?
- mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && c_retry-- && fr_event(card, err, mbox));
-
- if (err)
- {
- TracingEnabled = 0;
- /* set the return code */
- data[50] = mbox->cmd.result;
- mbox->cmd.length = 0;
- break;
- }
- /* get num_frames */
- sdla_peek(&card->hw, 0x9000, &num_frames, 2);
- sdla_peek(&card->hw, 0x9002, &curr_trace_addr,4);
- start_trace_addr = curr_trace_addr;
- /* MAX_SEND_BUFFER_SIZE -
- * sizeof(UDP_MGMT_PACKET) - 41 */
- available_buffer_space = 1926;
- /* set return code */
- data[50] = 0;
- }
- else
- {
- /* set return code to line trace already
- enabled */
- data[50] = 1;
- }
- mbox->cmd.length = 0;
- TracingEnabled = 1;
- break;
- /* FPIPE_DISABLE_TRACE */
- case 0x42:
- if (TracingEnabled)
- {
- do
- {
- /* SET_TRACE_CONFIGURATION */
- mbox->cmd.command = 0x60;
- mbox->cmd.length = 1;
- mbox->cmd.dlci = 0x00;
- mbox->data[0] = 0x36;
- err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && c_retry-- && fr_event(card, err, mbox));
- }
- /* set return code */
- data[50] = 0;
- mbox->cmd.length = 0;
- TracingEnabled = 0;
- break;
- /* FPIPE_GET_TRACE_INFO */
- case 0x43:
- /* Line trace cannot be performed on the 502 */
- if (!TracingEnabled)
- {
- /* set return code */
- data[50] = 1;
+ fr_udp_pkt->cblock.result = 0xCD;
+ } else {
+
+ switch(fr_udp_pkt->cblock.command) {
+
+ case FPIPE_ENABLE_TRACING:
+ if(!card->TracingEnabled) {
+ do {
+ mbox->cmd.command = FR_SET_TRACE_CONFIG;
+ mbox->cmd.length = 1;
+ mbox->cmd.dlci = 0x00;
+ mbox->data[0] = fr_udp_pkt->data[0] |
+ RESET_TRC;
+ err = sdla_exec(mbox) ?
+ mbox->cmd.result : CMD_TIMEOUT;
+ } while (err && c_retry-- && fr_event(card, err,
+ mbox));
+
+ if(err) {
+ card->TracingEnabled = 0;
+ /* set the return code */
+ fr_udp_pkt->cblock.result =
+ mbox->cmd.result;
mbox->cmd.length = 0;
break;
}
- buffer_length = 0;
- loops = (num_frames < 20) ? num_frames : 20;
- for (frames = 0; frames < loops; frames += 1)
- {
- sdla_peek(&card->hw, curr_trace_addr, &buf2, 1);
- /* no data on board so exit */
- if (buf2[0] == 0x00)
- break;
- /* 1+sizeof(FRAME_DATA) = 9 */
- if ((available_buffer_space - buffer_length) < 9)
- {
- /* indicate we have more frames on board
- and exit */
- data[62] |= 0x02;
- break;
- }
- /* get frame status */
- sdla_peek(&card->hw, curr_trace_addr + 0x05, &data[62 + buffer_length], 1);
- /* get time stamp */
- sdla_peek(&card->hw, curr_trace_addr + 0x06, &data[66 + buffer_length], 2);
- /* get frame length */
- sdla_peek(&card->hw, curr_trace_addr + 0x01, &data[64 + buffer_length], 2);
- /* get pointer to real data */
- sdla_peek(&card->hw, curr_trace_addr + 0x0C,&data_ptr, 4);
- /* see if we can fit the frame into the user buffer */
- memcpy(&real_len, &data[64 + buffer_length], 2);
- if (data_ptr == 0 || real_len + 8 > available_buffer_space)
- {
- data[63 + buffer_length] = 0x00;
- }
- else
- {
- /* we can take it next time */
- if (available_buffer_space - buffer_length < real_len + 8)
- {
- data[62] |= 0x02;
- break;
- }
- /* ok, get the frame */
- data[63 + buffer_length] = 0x01;
- /* get the data */
- sdla_peek(&card->hw, data_ptr, &data[68 + buffer_length], real_len);
- /* zero the opp flag to show we got the frame */
- buf2[0] = 0x00;
- sdla_poke(&card->hw, curr_trace_addr, &buf2, 1);
- /* now move onto the next frame */
- curr_trace_addr += 16;
- /* check if we passed the last address */
- if (curr_trace_addr >= (start_trace_addr + num_frames * 16))
- curr_trace_addr = start_trace_addr;
- /* update buffer length and make sure
- its even */
- if (data[63 + buffer_length] == 0x01)
- buffer_length += real_len - 1;
- /* for the header */
- buffer_length += 8;
- if (buffer_length & 0x0001)
- buffer_length += 1;
- }
- }
- /* ok now set the total number of frames passed in the
- high 5 bits */
- data[62] = (frames << 3) | data[62];
- /* set the data length */
- mbox->cmd.length = buffer_length;
- memcpy(&data[48], &buffer_length, 2);
- data[50] = 0;
- break;
- /* FPIPE_FT1_READ_STATUS */
- case 0x44:
- sdla_peek(&card->hw, 0xF020, &data[62], 2);
- data[48] = 2;
- data[49] = 0;
- data[50] = 0;
- mbox->cmd.length = 2;
- break;
- /* FPIPE_FLUSH_DRIVER_STATS */
- case 0x48:
- init_chan_statistics(chan);
- init_global_statistics(card);
- mbox->cmd.length = 0;
- break;
- case 0x49:
- do_gettimeofday(&tv);
- chan->router_up_time = tv.tv_sec - chan->router_start_time;
- *(unsigned long *) &data[62] = chan->router_up_time;
- mbox->cmd.length = 4;
- break;
- /* FPIPE_KILL_BOARD */
- case 0x50:
- break;
- /* FT1 MONITOR STATUS */
- case 0x80:
- if (data[62] == 1)
- {
- if (rCount++ != 0)
- {
- data[50] = 0;
- mbox->cmd.length = 1;
- break;
- }
- }
- /* Disable FT1 MONITOR STATUS */
- if (data[62] == 0)
- {
- if (--rCount != 0)
- {
- data[50] = 0;
- mbox->cmd.length = 1;
- break;
- }
- }
- default:
- do
- {
- memcpy(&mbox->cmd, &sendpacket[47], sizeof(fr_cmd_t));
- if (mbox->cmd.length)
- memcpy(&mbox->data, &sendpacket[62],mbox->cmd.length);
- err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && c_retry-- && fr_event(card, err, mbox));
+
+ sdla_peek(&card->hw, NO_TRC_ELEMENTS_OFF,
+ &num_trc_els, 2);
+ sdla_peek(&card->hw, BASE_TRC_ELEMENTS_OFF,
+ &card->u.f.trc_el_base, 4);
+ card->u.f.curr_trc_el = card->u.f.trc_el_base;
+ card->u.f.trc_el_last = card->u.f.curr_trc_el +
+ ((num_trc_els - 1) *
+ sizeof(fr_trc_el_t));
+
+ /* Calculate the maximum trace data area in */
+ /* the UDP packet */
+ card->u.f.trc_bfr_space=(MAX_LGTH_UDP_MGNT_PKT -
+ sizeof(fr_encap_hdr_t) -
+ sizeof(ip_pkt_t) -
+ sizeof(udp_pkt_t) -
+ sizeof(wp_mgmt_t) -
+ sizeof(cblock_t));
+
+ /* set return code */
+ fr_udp_pkt->cblock.result = 0;
- if (!err)
- {
- ++chan->UDP_FPIPE_mgmt_adptr_cmnd_OK;
- memcpy(data, sendpacket, skb->len);
- memcpy(&data[47], &mbox->cmd, sizeof(fr_cmd_t));
- if (mbox->cmd.length)
- {
- memcpy(&data[62], &mbox->data,mbox->cmd.length);
- }
+ } else {
+ /* set return code to line trace already
+ enabled */
+ fr_udp_pkt->cblock.result = 1;
+ }
+
+ mbox->cmd.length = 0;
+ card->TracingEnabled = 1;
+ break;
+
+
+ case FPIPE_DISABLE_TRACING:
+ if(card->TracingEnabled) {
+
+ do {
+ mbox->cmd.command = FR_SET_TRACE_CONFIG;
+ mbox->cmd.length = 1;
+ mbox->cmd.dlci = 0x00;
+ mbox->data[0] = ~ACTIVATE_TRC;
+ err = sdla_exec(mbox) ?
+ mbox->cmd.result : CMD_TIMEOUT;
+ } while (err && c_retry-- && fr_event(card, err, mbox));
+ }
+
+ /* set return code */
+ fr_udp_pkt->cblock.result = 0;
+ mbox->cmd.length = 0;
+ card->TracingEnabled = 0;
+ break;
+
+ case FPIPE_GET_TRACE_INFO:
+
+ /* Line trace cannot be performed on the 502 */
+ if(!card->TracingEnabled) {
+ /* set return code */
+ fr_udp_pkt->cblock.result = 1;
+ mbox->cmd.length = 0;
+ break;
+ }
+
+ (void *)ptr_trc_el = card->u.f.curr_trc_el;
+
+ buffer_length = 0;
+ fr_udp_pkt->data[0x00] = 0x00;
+
+ for(frames = 0; frames < MAX_FRMS_TRACED; frames ++) {
+
+ sdla_peek(&card->hw, (unsigned long)ptr_trc_el,
+ (void *)&trc_el.flag,
+ sizeof(fr_trc_el_t));
+ if(trc_el.flag == 0x00) {
+ break;
}
- else
- {
- ++chan->UDP_FPIPE_mgmt_adptr_cmnd_timeout;
+ if((card->u.f.trc_bfr_space - buffer_length)
+ < sizeof(fpipemon_trc_hdr_t)) {
+ fr_udp_pkt->data[0x00] |= MORE_TRC_DATA;
+ break;
+ }
+
+ fpipemon_trc =
+ (fpipemon_trc_t *)&fr_udp_pkt->data[buffer_length];
+ fpipemon_trc->fpipemon_trc_hdr.status =
+ trc_el.attr;
+ fpipemon_trc->fpipemon_trc_hdr.tmstamp =
+ trc_el.tmstamp;
+ fpipemon_trc->fpipemon_trc_hdr.length =
+ trc_el.length;
+
+ if(!trc_el.offset || !trc_el.length) {
+
+ fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x00;
+
+ }else if((trc_el.length + sizeof(fpipemon_trc_hdr_t) + 1) >
+ (card->u.f.trc_bfr_space - buffer_length)){
+
+ fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x00;
+ fr_udp_pkt->data[0x00] |= MORE_TRC_DATA;
+
+ }else {
+ fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x01;
+ sdla_peek(&card->hw, trc_el.offset,
+ fpipemon_trc->data,
+ trc_el.length);
+ }
+
+ trc_el.flag = 0x00;
+ sdla_poke(&card->hw, (unsigned long)ptr_trc_el,
+ &trc_el.flag, 1);
+
+ ptr_trc_el ++;
+ if((void *)ptr_trc_el > card->u.f.trc_el_last)
+ (void*)ptr_trc_el = card->u.f.trc_el_base;
+
+ buffer_length += sizeof(fpipemon_trc_hdr_t);
+ if(fpipemon_trc->fpipemon_trc_hdr.data_passed) {
+ buffer_length += trc_el.length;
+ }
+
+ if(fr_udp_pkt->data[0x00] & MORE_TRC_DATA) {
+ break;
}
+ }
+
+ if(frames == MAX_FRMS_TRACED) {
+ fr_udp_pkt->data[0x00] |= MORE_TRC_DATA;
}
- }
- /* Fill UDP TTL */
- data[10] = card->wandev.ttl;
- len = reply_udp(data, mbox->cmd.length);
- if (udp_pkt_src == UDP_PKT_FRM_NETWORK)
- {
- err = fr508_send(card, dlci, 0, len, data);
- if (err)
- ++chan->UDP_FPIPE_mgmt_adptr_send_passed;
+
+ card->u.f.curr_trc_el = (void *)ptr_trc_el;
+
+ /* set the total number of frames passed */
+ fr_udp_pkt->data[0x00] |=
+ ((frames << 1) & (MAX_FRMS_TRACED << 1));
+
+ /* set the data length and return code */
+ fr_udp_pkt->cblock.length = mbox->cmd.length = buffer_length;
+ fr_udp_pkt->cblock.result = 0;
+ break;
+
+ case FPIPE_FT1_READ_STATUS:
+ sdla_peek(&card->hw, 0xF020,
+ &fr_udp_pkt->data[0x00] , 2);
+ fr_udp_pkt->cblock.length = 2;
+ fr_udp_pkt->cblock.result = 0;
+ break;
+
+ case FPIPE_FLUSH_DRIVER_STATS:
+ init_chan_statistics(chan);
+ init_global_statistics(card);
+ mbox->cmd.length = 0;
+ break;
+
+ case FPIPE_ROUTER_UP_TIME:
+ do_gettimeofday(&tv);
+ chan->router_up_time = tv.tv_sec -
+ chan->router_start_time;
+ *(unsigned long *)&fr_udp_pkt->data =
+ chan->router_up_time;
+ mbox->cmd.length = 4;
+ break;
+
+
+ case FR_FT1_STATUS_CTRL:
+ if(fr_udp_pkt->data[0] == 1) {
+ if(rCount++ != 0 ){
+ fr_udp_pkt->cblock.result = 0;
+ mbox->cmd.length = 1;
+ break;
+ }
+ }
+
+ /* Disable FT1 MONITOR STATUS */
+ if(fr_udp_pkt->data[0] == 0) {
+ if( --rCount != 0) {
+ fr_udp_pkt->cblock.result = 0;
+ mbox->cmd.length = 1;
+ break;
+ }
+ }
+
+ case FPIPE_DRIVER_STAT_IFSEND:
+ memcpy(fr_udp_pkt->data,
+ &chan->drvstats_if_send.if_send_entry,
+ sizeof(if_send_stat_t));
+ mbox->cmd.length = sizeof(if_send_stat_t);
+ break;
+
+ case FPIPE_DRIVER_STAT_INTR:
+ memcpy(fr_udp_pkt->data,
+ &card->statistics.isr_entry,
+ sizeof(global_stats_t));
+ memcpy(&fr_udp_pkt->data[sizeof(global_stats_t)],
+ &chan->drvstats_rx_intr.rx_intr_no_socket,
+ sizeof(rx_intr_stat_t));
+ mbox->cmd.length = sizeof(global_stats_t) +
+ sizeof(rx_intr_stat_t);
+ break;
+
+ case FPIPE_DRIVER_STAT_GEN:
+ memcpy(fr_udp_pkt->data,
+ &chan->drvstats_gen.UDP_PIPE_mgmt_kmalloc_err,
+ sizeof(pipe_mgmt_stat_t));
+
+ memcpy(&fr_udp_pkt->data[sizeof(pipe_mgmt_stat_t)],
+ &card->statistics, sizeof(global_stats_t));
+
+ fr_udp_pkt->cblock.result = 0;
+ fr_udp_pkt->cblock.length = sizeof(global_stats_t)+
+ sizeof(rx_intr_stat_t);
+ mbox->cmd.length = fr_udp_pkt->cblock.length;
+ break;
+
+ default:
+ do {
+ memcpy(&mbox->cmd,
+ &fr_udp_pkt->cblock.command,
+ sizeof(fr_cmd_t));
+ if(mbox->cmd.length) {
+ memcpy(&mbox->data,
+ (char *)fr_udp_pkt->data,
+ mbox->cmd.length);
+ }
+
+ err = sdla_exec(mbox) ? mbox->cmd.result :
+ CMD_TIMEOUT;
+ } while (err && c_retry-- && fr_event(card, err, mbox));
+
+ if(!err)
+ chan->drvstats_gen.
+ UDP_PIPE_mgmt_adptr_cmnd_OK ++;
+ else
+ chan->drvstats_gen.
+ UDP_PIPE_mgmt_adptr_cmnd_timeout ++;
+
+ /* copy the result back to our buffer */
+ memcpy(&fr_udp_pkt->cblock.command,
+ &mbox->cmd, sizeof(fr_cmd_t));
+
+ if(mbox->cmd.length) {
+ memcpy(&fr_udp_pkt->data,
+ &mbox->data, mbox->cmd.length);
+ }
+ }
+ }
+
+ /* Fill UDP TTL */
+ fr_udp_pkt->ip_pkt.ttl = card->wandev.ttl;
+ len = reply_udp(card->u.f.udp_pkt_data, mbox->cmd.length);
+
+ if(udp_pkt_src == UDP_PKT_FRM_NETWORK) {
+
+ err = fr_send(card, dlci, 0, len, card->u.f.udp_pkt_data);
+ if (err)
+ chan->drvstats_gen.UDP_PIPE_mgmt_adptr_send_passed ++;
else
- ++chan->UDP_FPIPE_mgmt_adptr_send_failed;
- dev_kfree_skb(skb);
- }
- else
- {
+ chan->drvstats_gen.UDP_PIPE_mgmt_adptr_send_failed ++;
+ } else {
/* Allocate socket buffer */
- if ((new_skb = dev_alloc_skb(len)) != NULL)
- {
+ if((new_skb = dev_alloc_skb(len)) != NULL) {
+
/* copy data into new_skb */
buf = skb_put(new_skb, len);
- memcpy(buf, data, len);
+ memcpy(buf, card->u.f.udp_pkt_data, len);
+
/* Decapsulate packet and pass it up the protocol
stack */
new_skb->dev = dev;
- buf = skb_pull(new_skb, 1); /* remove hardware header */
- if (!wanrouter_type_trans(new_skb, dev))
- {
- ++chan->UDP_FPIPE_mgmt_not_passed_to_stack;
+ buf = skb_pull(new_skb, 1); /* remove hardware header*/
+
+ if(!wanrouter_type_trans(new_skb, dev)) {
+
+ chan->drvstats_gen.
+ UDP_PIPE_mgmt_not_passed_to_stack ++;
/* can't decapsulate packet */
dev_kfree_skb(new_skb);
- }
- else
- {
- ++chan->UDP_FPIPE_mgmt_passed_to_stack;
+ } else {
+ chan->drvstats_gen.
+ UDP_PIPE_mgmt_passed_to_stack ++;
netif_rx(new_skb);
- }
- }
- else
- {
- ++chan->UDP_FPIPE_mgmt_no_socket;
- printk(KERN_INFO
- "%s: UDP mgmt cmnd, no socket buffers available!\n",
- card->devname);
- }
- }
- kfree(data);
- return 0;
+ }
+
+ } else {
+ chan->drvstats_gen.UDP_PIPE_mgmt_no_socket ++;
+ printk(KERN_INFO
+ "%s: UDP mgmt cmnd, no socket buffers available!\n",
+ card->devname);
+ }
+ }
+
+ card->u.f.udp_pkt_lgth = 0;
+
+ return 1;
}
+
/*==============================================================================
- * Perform the Interrupt Test by running the READ_CODE_VERSION command MAX_INTR_
- * TEST_COUNTER times.
+ * Send Inverse ARP Request
*/
-
-static int intr_test(sdla_t * card)
+
+int send_inarp_request(sdla_t *card, struct net_device *dev)
{
- fr_mbox_t *mb = card->mbox;
- int err, i;
- /* The critical flag is unset here because we want to get into the
- ISR without the flag already set. The If_open sets the flag.
- */
- card->wandev.critical = 0;
- err = fr_set_intr_mode(card, 0x08, card->wandev.mtu);
- if (err == CMD_OK)
- {
- for (i = 0; i < MAX_INTR_TEST_COUNTER; i++)
- {
- /* Run command READ_CODE_VERSION */
- memset(&mb->cmd, 0, sizeof(fr_cmd_t));
- mb->cmd.length = 0;
- mb->cmd.command = 0x40;
- err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
- if (err != CMD_OK)
- fr_event(card, err, mb);
- }
- }
- else
- {
- return err;
+ arphdr_1490_t *ArpPacket;
+ arphdr_fr_t *arphdr;
+ fr_channel_t *chan = dev->priv;
+ struct in_device *in_dev;
+
+ in_dev = dev->ip_ptr;
+
+ if(in_dev != NULL ) {
+
+ ArpPacket = kmalloc(sizeof(arphdr_1490_t) + sizeof(arphdr_fr_t), GFP_ATOMIC);
+ /* SNAP Header indicating ARP */
+ ArpPacket->control = 0x03;
+ ArpPacket->pad = 0x00;
+ ArpPacket->NLPID = 0x80;
+ ArpPacket->OUI[0] = 0;
+ ArpPacket->OUI[1] = 0;
+ ArpPacket->OUI[2] = 0;
+ ArpPacket->PID = 0x0608;
+
+ arphdr = (arphdr_fr_t *)(ArpPacket + 1); // Go to ARP Packet
+
+ /* InARP request */
+ arphdr->ar_hrd = 0x0F00; /* Frame Relay HW type */
+ arphdr->ar_pro = 0x0008; /* IP Protocol */
+ arphdr->ar_hln = 2; /* HW addr length */
+ arphdr->ar_pln = 4; /* IP addr length */
+ arphdr->ar_op = htons(0x08); /* InARP Request */
+ arphdr->ar_sha = 0; /* src HW DLCI - Doesn't matter */
+ if(in_dev->ifa_list != NULL)
+ arphdr->ar_sip = in_dev->ifa_list->ifa_local; /* Local Address */else
+ arphdr->ar_sip = 0;
+ arphdr->ar_tha = 0; /* dst HW DLCI - Doesn't matter */
+ arphdr->ar_tip = 0; /* Remote Address -- what we want */
+
+ printk(KERN_INFO "%s: Sending InARP request on DLCI %d.\n", card->devname, chan->dlci);
+ fr_send(card, chan->dlci, 0,
+ sizeof(arphdr_1490_t) + sizeof(arphdr_fr_t),
+ (void *)ArpPacket);
+ kfree(ArpPacket);
}
- err = fr_set_intr_mode(card, 0, card->wandev.mtu);
- if (err != CMD_OK)
- return err;
- card->wandev.critical = 1;
- return 0;
+
+ return 1;
}
-/*============================================================================
- * Process UDP call of type DRVSTATS.
+
+
+/*==============================================================================
+ * Check packet for ARP Type
*/
-static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, int dlci, fr_channel_t * chan)
+
+int is_arp(void *buf)
{
- int c_retry = MAX_CMD_RETRY;
- unsigned char *sendpacket;
- unsigned char buf2[5];
- unsigned char *data;
- unsigned char *buf;
- unsigned int len;
- fr_mbox_t *mbox = card->mbox;
- struct sk_buff *new_skb;
- int err;
- sendpacket = skb->data;
- memcpy(&buf2, &card->wandev.udp_port, 2);
- if ((data = kmalloc(2000, GFP_ATOMIC)) == NULL)
- {
- printk(KERN_INFO
- "%s: Error allocating memory for UDP DRIVER STATS cmnd0x%02X"
- ,card->devname, data[45]);
- ++chan->UDP_DRVSTATS_mgmt_kmalloc_err;
+ arphdr_1490_t *arphdr = (arphdr_1490_t *)buf;
+
+ if (arphdr->pad == 0x00 &&
+ arphdr->NLPID == 0x80 &&
+ arphdr->PID == 0x0608)
return 1;
- }
- memcpy(data, sendpacket, skb->len);
- switch (data[47])
- {
- case 0x45:
- *(unsigned long *) &data[62] = chan->if_send_entry;
- *(unsigned long *) &data[66] = chan->if_send_skb_null;
- *(unsigned long *) &data[70] = chan->if_send_broadcast;
- *(unsigned long *) &data[74] = chan->if_send_multicast;
- *(unsigned long *) &data[78] = chan->if_send_critical_ISR;
- *(unsigned long *) &data[82] = chan->if_send_critical_non_ISR;
- *(unsigned long *) &data[86] = chan->if_send_busy;
- *(unsigned long *) &data[90] = chan->if_send_busy_timeout;
- *(unsigned long *) &data[94] = chan->if_send_DRVSTATS_request;
- *(unsigned long *) &data[98] = chan->if_send_FPIPE_request;
- *(unsigned long *) &data[102] = chan->if_send_wan_disconnected;
- *(unsigned long *) &data[106] = chan->if_send_dlci_disconnected;
- *(unsigned long *) &data[110] = chan->if_send_no_bfrs;
- *(unsigned long *) &data[114] = chan->if_send_adptr_bfrs_full;
- *(unsigned long *) &data[118] = chan->if_send_bfrs_passed_to_adptr;
- *(unsigned long *) &data[120] = card->irq_dis_if_send_count;
- mbox->cmd.length = 62;
- break;
- case 0x46:
- *(unsigned long *) &data[62] = card->statistics.isr_entry;
- *(unsigned long *) &data[66] = card->statistics.isr_already_critical;
- *(unsigned long *) &data[70] = card->statistics.isr_rx;
- *(unsigned long *) &data[74] = card->statistics.isr_tx;
- *(unsigned long *) &data[78] = card->statistics.isr_intr_test;
- *(unsigned long *) &data[82] = card->statistics.isr_spurious;
- *(unsigned long *) &data[86] = card->statistics.isr_enable_tx_int;
- *(unsigned long *) &data[90] = card->statistics.tx_intr_dev_not_started;
- *(unsigned long *) &data[94] = card->statistics.rx_intr_corrupt_rx_bfr;
- *(unsigned long *) &data[98] = card->statistics.rx_intr_on_orphaned_DLCI;
- *(unsigned long *) &data[102] = chan->rx_intr_no_socket;
- *(unsigned long *) &data[106] = chan->rx_intr_dev_not_started;
- *(unsigned long *) &data[110] = chan->rx_intr_DRVSTATS_request;
- *(unsigned long *) &data[114] = chan->rx_intr_FPIPE_request;
- *(unsigned long *) &data[118] = chan->rx_intr_bfr_not_passed_to_stack;
- *(unsigned long *) &data[122] = chan->rx_intr_bfr_passed_to_stack;
- mbox->cmd.length = 64;
- break;
- case 0x47:
- *(unsigned long *) &data[62] = chan->UDP_FPIPE_mgmt_kmalloc_err;
- *(unsigned long *) &data[66] = chan->UDP_FPIPE_mgmt_adptr_type_err;
- *(unsigned long *) &data[70] = chan->UDP_FPIPE_mgmt_direction_err;
- *(unsigned long *) &data[74] = chan->UDP_FPIPE_mgmt_adptr_cmnd_timeout;
- *(unsigned long *) &data[78] = chan->UDP_FPIPE_mgmt_adptr_cmnd_OK;
- *(unsigned long *) &data[82] = chan->UDP_FPIPE_mgmt_adptr_send_passed;
- *(unsigned long *) &data[86] = chan->UDP_FPIPE_mgmt_adptr_send_failed;
- *(unsigned long *) &data[90] = chan->UDP_FPIPE_mgmt_no_socket;
- *(unsigned long *) &data[94] = chan->UDP_FPIPE_mgmt_not_passed_to_stack;
- *(unsigned long *) &data[98] = chan->UDP_FPIPE_mgmt_passed_to_stack;
- *(unsigned long *) &data[102] = chan->UDP_DRVSTATS_mgmt_kmalloc_err;
- *(unsigned long *) &data[106] = chan->UDP_DRVSTATS_mgmt_adptr_cmnd_timeout;
- *(unsigned long *) &data[110] = chan->UDP_DRVSTATS_mgmt_adptr_cmnd_OK;
- *(unsigned long *) &data[114] = chan->UDP_DRVSTATS_mgmt_adptr_send_passed;
- *(unsigned long *) &data[118] = chan->UDP_DRVSTATS_mgmt_adptr_send_failed;
- *(unsigned long *) &data[122] = chan->UDP_DRVSTATS_mgmt_no_socket;
- *(unsigned long *) &data[126] = chan->UDP_DRVSTATS_mgmt_not_passed_to_stack;
- *(unsigned long *) &data[130] = chan->UDP_DRVSTATS_mgmt_passed_to_stack;
- *(unsigned long *) &data[134] = card->statistics.poll_entry;
- *(unsigned long *) &data[138] = card->statistics.poll_already_critical;
- *(unsigned long *) &data[142] = card->statistics.poll_processed;
- *(unsigned long *) &data[144] = card->irq_dis_poll_count;
- mbox->cmd.length = 86;
- break;
- default:
- do
- {
- memcpy(&mbox->cmd, &sendpacket[47], sizeof(fr_cmd_t));
- if (mbox->cmd.length)
- memcpy(&mbox->data, &sendpacket[62], mbox->cmd.length);
- err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- }
- while (err && c_retry-- && fr_event(card, err, mbox));
+ else return 0;
+}
+
+/*==============================================================================
+ * Process ARP Packet Type
+ */
+
+int process_ARP(arphdr_1490_t *ArpPacket, sdla_t *card, struct net_device* dev)
+{
+
+ arphdr_fr_t *arphdr = (arphdr_fr_t *)(ArpPacket + 1); /* Skip header */
+ fr_rx_buf_ctl_t* frbuf = card->rxmb;
+ struct in_device *in_dev;
+
+
+ in_dev = dev->ip_ptr;
+ if( in_dev != NULL && in_dev->ifa_list != NULL) {
+ switch (ntohs(arphdr->ar_op)) {
+
+ case 0x08: // Inverse ARP request -- Send Reply, add route.
- if (!err)
- {
- ++chan->UDP_DRVSTATS_mgmt_adptr_cmnd_OK;
- memcpy(data, sendpacket, skb->len);
- memcpy(&data[47], &mbox->cmd, sizeof(fr_cmd_t));
- if (mbox->cmd.length)
- memcpy(&data[62], &mbox->data, mbox->cmd.length);
- }
- else
- {
- ++chan->UDP_DRVSTATS_mgmt_adptr_cmnd_timeout;
+ /* Check for valid Address */
+ printk(KERN_INFO "%s: Recvd PtP addr %s -InArp Req\n", ((fr_channel_t *)dev->priv)->name, in_ntoa(arphdr->ar_sip));
+
+ if ((in_dev->ifa_list->ifa_mask & arphdr->ar_sip) != (in_dev->ifa_list->ifa_mask & in_dev->ifa_list->ifa_local)) {
+ printk(KERN_INFO "%s: Invalid PtP address. InARP ignored.\n", card->devname);
+ printk(KERN_INFO "mask %X\n", in_dev->ifa_list->ifa_mask);
+ printk(KERN_INFO "local %X\n", in_dev->ifa_list->ifa_local);
+ return -1;
}
- }
- /* Fill UDP TTL */
- data[10] = card->wandev.ttl;
- len = reply_udp(data, mbox->cmd.length);
- if (udp_pkt_src == UDP_PKT_FRM_NETWORK)
- {
- err = fr508_send(card, dlci, 0, len, data);
- if (err)
- ++chan->UDP_DRVSTATS_mgmt_adptr_send_failed;
- else
- ++chan->UDP_DRVSTATS_mgmt_adptr_send_passed;
- dev_kfree_skb(skb);
- }
- else
- {
- /* Allocate socket buffer */
- if ((new_skb = dev_alloc_skb(len)) != NULL)
- {
- /* copy data into new_skb */
- buf = skb_put(new_skb, len);
- memcpy(buf, data, len);
- /* Decapsulate packet and pass it up the
- protocol stack */
- new_skb->dev = dev;
- /* remove hardware header */
- buf = skb_pull(new_skb, 1);
- if (!wanrouter_type_trans(new_skb, dev))
+
+ if (in_dev->ifa_list->ifa_local == arphdr->ar_sip) {
+ printk(KERN_INFO "%s: Local addr = PtP addr. InARP ignored.\n", card->devname);
+ return -1;
+ }
+
+ arphdr->ar_op = htons(0x09); /* InARP Reply */
+
+ /* Set addresses */
+ arphdr->ar_tip = arphdr->ar_sip;
+ arphdr->ar_sip = in_dev->ifa_list->ifa_local;
+
+ fr_send(card, frbuf->dlci, 0, frbuf->length, (void *)ArpPacket);
+
+ /* Modify Point-to-Point Address */
{
- /* can't decapsulate packet */
- ++chan->UDP_DRVSTATS_mgmt_not_passed_to_stack;
- dev_kfree_skb(new_skb);
+ struct ifreq if_info;
+ struct sockaddr_in *if_data;
+ mm_segment_t fs = get_fs();
+ int err;
+
+ /* Set remote addresses */
+ memset(&if_info, 0, sizeof(if_info));
+ strcpy(if_info.ifr_name, dev->name);
+
+ set_fs(get_ds()); /* get user space block */
+
+ if_data = (struct sockaddr_in *)&if_info.ifr_dstaddr;
+ if_data->sin_addr.s_addr = arphdr->ar_tip;
+ if_data->sin_family = AF_INET;
+ err = devinet_ioctl( SIOCSIFDSTADDR, &if_info );
+
+ set_fs(fs); /* restore old block */
}
- else
+
+ /* Add Route Flag */
+ /* The route will be added in the polling routine so
+ that it is not interrupt context. */
+
+ ((fr_channel_t *) dev->priv)->route_flag = ADD_ROUTE;
+ card->poll = &process_route;
+
+ break;
+
+ case 0x09: // Inverse ARP reply
+
+ /* Check for valid Address */
+ printk(KERN_INFO "%s: Recvd PtP addr %s -InArp Reply\n", ((fr_channel_t *)dev->priv)->name, in_ntoa(arphdr->ar_sip));
+
+ if ((in_dev->ifa_list->ifa_mask & arphdr->ar_sip) != (in_dev->ifa_list->ifa_mask & in_dev->ifa_list->ifa_local)) {
+ printk(KERN_INFO "%s: Invalid PtP address. InARP ignored.\n", card->devname);
+ return -1;
+ }
+
+ if (in_dev->ifa_list->ifa_local == arphdr->ar_sip) {
+ printk(KERN_INFO "%s: Local addr = PtP addr. InARP ignored.\n", card->devname);
+ return -1;
+ }
+
+ /* Modify Point-to-Point Address */
{
- ++chan->UDP_DRVSTATS_mgmt_passed_to_stack;
- netif_rx(new_skb);
+ struct ifreq if_info;
+ struct sockaddr_in *if_data;
+ mm_segment_t fs = get_fs();
+ int err;
+
+ /* Set remote addresses */
+ memset(&if_info, 0, sizeof(if_info));
+ strcpy(if_info.ifr_name, dev->name);
+
+ set_fs(get_ds()); /* get user space block */
+
+ if_data = (struct sockaddr_in *)&if_info.ifr_dstaddr;
+ if_data->sin_addr.s_addr = arphdr->ar_sip;
+ if_data->sin_family = AF_INET;
+ err = devinet_ioctl( SIOCSIFDSTADDR, &if_info );
+
+ set_fs(fs); /* restore old block */
}
+
+ /* Add Route Flag */
+ /* The route will be added in the polling routine so
+ that it is not interrupt context. */
+
+ ((fr_channel_t *) dev->priv)->route_flag = ADD_ROUTE;
+ ((fr_channel_t *) dev->priv)->inarp = INARP_CONFIGURED;
+ card->poll = &process_route;
+
+ break;
+ default: // ARP's and RARP's -- Shouldn't happen.
}
- else
- {
- ++chan->UDP_DRVSTATS_mgmt_no_socket;
- printk(KERN_INFO "%s: UDP mgmt cmnd, no socket buffers available!\n", card->devname);
+ }
+
+ return 0;
+}
+
+
+/*==============================================================================
+ * Perform the Interrupt Test by running the READ_CODE_VERSION command MAX_INTR_
+ * TEST_COUNTER times.
+ */
+static int intr_test( sdla_t* card )
+{
+ fr_mbox_t* mb = card->mbox;
+ int err,i;
+
+ /* The critical flag is unset here because we want to get into the
+ ISR without the flag already set. The If_open sets the flag.
+ */
+ clear_bit(1, (void*)&card->wandev.critical);
+
+ err = fr_set_intr_mode(card, FR_INTR_READY, card->wandev.mtu, 0 );
+
+ if (err == CMD_OK) {
+
+ for ( i = 0; i < MAX_INTR_TEST_COUNTER; i++ ) {
+ /* Run command READ_CODE_VERSION */
+ mb->cmd.length = 0;
+ mb->cmd.command = FR_READ_CODE_VERSION;
+ err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
+ if (err != CMD_OK)
+ fr_event(card, err, mb);
}
+
+ } else {
+ return err;
}
- kfree(data);
+
+ err = fr_set_intr_mode( card, 0, card->wandev.mtu, 0 );
+
+ if( err != CMD_OK )
+ return err;
+
+ set_bit(1, (void*)&card->wandev.critical);
return 0;
}
/*==============================================================================
- * Determine what type of UDP call it is. DRVSTATS or FPIPE8ND ?
+ * Determine what type of UDP call it is. FPIPE8ND ?
*/
-
-static int udp_pkt_type(struct sk_buff *skb, sdla_t * card)
+static int udp_pkt_type( struct sk_buff *skb, sdla_t* card )
{
- unsigned char *sendpacket;
- unsigned char buf2[5];
- sendpacket = skb->data;
- memcpy(&buf2, &card->wandev.udp_port, 2);
- if (sendpacket[2] == 0x45 && /* IP packet */
- sendpacket[11] == 0x11 && /* UDP packet */
- sendpacket[24] == buf2[1] && /* UDP Port */
- sendpacket[25] == buf2[0] &&
- sendpacket[38] == 0x01)
- {
- if (sendpacket[30] == 0x46 && /* FPIPE8ND: Signature */
- sendpacket[31] == 0x50 &&
- sendpacket[32] == 0x49 &&
- sendpacket[33] == 0x50 &&
- sendpacket[34] == 0x45 &&
- sendpacket[35] == 0x38 &&
- sendpacket[36] == 0x4E &&
- sendpacket[37] == 0x44)
- {
- return UDP_FPIPE_TYPE;
- } else if (sendpacket[30] == 0x44 && /* DRVSTATS: Signature */
- sendpacket[31] == 0x52 &&
- sendpacket[32] == 0x56 &&
- sendpacket[33] == 0x53 &&
- sendpacket[34] == 0x54 &&
- sendpacket[35] == 0x41 &&
- sendpacket[36] == 0x54 &&
- sendpacket[37] == 0x53)
- {
- return UDP_DRVSTATS_TYPE;
- }
- else
- return UDP_INVALID_TYPE;
+ fr_udp_pkt_t *fr_udp_pkt = (fr_udp_pkt_t *)skb->data;
+
+ if((fr_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) &&
+ (fr_udp_pkt->ip_pkt.ver_inet_hdr_length == 0x45) &&
+ (fr_udp_pkt->udp_pkt.udp_dst_port ==
+ ntohs(card->wandev.udp_port)) &&
+ (fr_udp_pkt->wp_mgmt.request_reply ==
+ UDPMGMT_REQUEST)) {
+ if(!strncmp(fr_udp_pkt->wp_mgmt.signature,
+ UDPMGMT_FPIPE_SIGNATURE, 8))
+ return UDP_FPIPE_TYPE;
}
- else
- return UDP_INVALID_TYPE;
+
+ return UDP_INVALID_TYPE;
}
+
+
/*==============================================================================
* Initializes the Statistics values in the fr_channel structure.
*/
-
-void init_chan_statistics(fr_channel_t * chan)
+void init_chan_statistics( fr_channel_t* chan)
{
- chan->if_send_entry = 0;
- chan->if_send_skb_null = 0;
- chan->if_send_broadcast = 0;
- chan->if_send_multicast = 0;
- chan->if_send_critical_ISR = 0;
- chan->if_send_critical_non_ISR = 0;
- chan->if_send_busy = 0;
- chan->if_send_busy_timeout = 0;
- chan->if_send_FPIPE_request = 0;
- chan->if_send_DRVSTATS_request = 0;
- chan->if_send_wan_disconnected = 0;
- chan->if_send_dlci_disconnected = 0;
- chan->if_send_no_bfrs = 0;
- chan->if_send_adptr_bfrs_full = 0;
- chan->if_send_bfrs_passed_to_adptr = 0;
- chan->rx_intr_no_socket = 0;
- chan->rx_intr_dev_not_started = 0;
- chan->rx_intr_FPIPE_request = 0;
- chan->rx_intr_DRVSTATS_request = 0;
- chan->rx_intr_bfr_not_passed_to_stack = 0;
- chan->rx_intr_bfr_passed_to_stack = 0;
- chan->UDP_FPIPE_mgmt_kmalloc_err = 0;
- chan->UDP_FPIPE_mgmt_direction_err = 0;
- chan->UDP_FPIPE_mgmt_adptr_type_err = 0;
- chan->UDP_FPIPE_mgmt_adptr_cmnd_OK = 0;
- chan->UDP_FPIPE_mgmt_adptr_cmnd_timeout = 0;
- chan->UDP_FPIPE_mgmt_adptr_send_passed = 0;
- chan->UDP_FPIPE_mgmt_adptr_send_failed = 0;
- chan->UDP_FPIPE_mgmt_not_passed_to_stack = 0;
- chan->UDP_FPIPE_mgmt_passed_to_stack = 0;
- chan->UDP_FPIPE_mgmt_no_socket = 0;
- chan->UDP_DRVSTATS_mgmt_kmalloc_err = 0;
- chan->UDP_DRVSTATS_mgmt_adptr_cmnd_OK = 0;
- chan->UDP_DRVSTATS_mgmt_adptr_cmnd_timeout = 0;
- chan->UDP_DRVSTATS_mgmt_adptr_send_passed = 0;
- chan->UDP_DRVSTATS_mgmt_adptr_send_failed = 0;
- chan->UDP_DRVSTATS_mgmt_not_passed_to_stack = 0;
- chan->UDP_DRVSTATS_mgmt_passed_to_stack = 0;
- chan->UDP_DRVSTATS_mgmt_no_socket = 0;
+ memset(&chan->drvstats_if_send.if_send_entry, 0,
+ sizeof(if_send_stat_t));
+ memset(&chan->drvstats_rx_intr.rx_intr_no_socket, 0,
+ sizeof(rx_intr_stat_t));
+ memset(&chan->drvstats_gen.UDP_PIPE_mgmt_kmalloc_err, 0,
+ sizeof(pipe_mgmt_stat_t));
}
+
/*==============================================================================
* Initializes the Statistics values in the Sdla_t structure.
*/
-
-void init_global_statistics(sdla_t * card)
+void init_global_statistics( sdla_t* card )
{
/* Intialize global statistics for a card */
- card->statistics.isr_entry = 0;
- card->statistics.isr_already_critical = 0;
- card->statistics.isr_rx = 0;
- card->statistics.isr_tx = 0;
- card->statistics.isr_intr_test = 0;
- card->statistics.isr_spurious = 0;
- card->statistics.isr_enable_tx_int = 0;
- card->statistics.rx_intr_corrupt_rx_bfr = 0;
- card->statistics.rx_intr_on_orphaned_DLCI = 0;
- card->statistics.tx_intr_dev_not_started = 0;
- card->statistics.poll_entry = 0;
- card->statistics.poll_already_critical = 0;
- card->statistics.poll_processed = 0;
+ memset(&card->statistics.isr_entry, 0, sizeof(global_stats_t));
}
-static void read_DLCI_IB_mapping(sdla_t * card, fr_channel_t * chan)
+static void read_DLCI_IB_mapping( sdla_t* card, fr_channel_t* chan )
{
- fr_mbox_t *mbox = card->mbox;
- int retry = MAX_CMD_RETRY;
- dlci_IB_mapping_t *result;
- int err, counter, found;
- do
- {
- memset(&mbox->cmd, 0, sizeof(fr_cmd_t));
+ fr_mbox_t* mbox = card->mbox;
+ int retry = MAX_CMD_RETRY;
+ dlci_IB_mapping_t* result;
+ int err, counter, found;
+
+ do {
mbox->cmd.command = FR_READ_DLCI_IB_MAPPING;
+ mbox->cmd.length = 0;
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
+ } while (err && retry-- && fr_event(card, err, mbox));
+
+ if( mbox->cmd.result != 0){
+ printk(KERN_INFO "%s: Read DLCI IB Mapping failed\n",
+ chan->name);
}
- while (err && retry-- && fr_event(card, err, mbox));
-
- if (mbox->cmd.result != 0)
- printk(KERN_INFO "%s: Read DLCI IB Mapping failed\n", chan->name);
counter = mbox->cmd.length / sizeof(dlci_IB_mapping_t);
- result = (void *) mbox->data;
+ result = (void *)mbox->data;
+
found = 0;
- for (; counter; --counter, ++result)
- {
- if (result->dlci == chan->dlci)
- {
- printk(KERN_INFO "%s: DLCI= %d, IB addr = %lx for %s\n"
- ,card->devname, result->dlci, result->addr_value ,chan->name);
+ for (; counter; --counter, ++result) {
+ if ( result->dlci == chan->dlci ) {
chan->IB_addr = result->addr_value;
- chan->dlci_int_interface = (void *) (card->hw.dpmbase +
- (chan->IB_addr & 0x00001FFF));
+ if(card->hw.type == SDLA_S514){
+ chan->dlci_int_interface =
+ (void*)(card->hw.dpmbase +
+ chan->IB_addr);
+ }else{
+ chan->dlci_int_interface =
+ (void*)(card->hw.dpmbase +
+ (chan->IB_addr & 0x00001FFF));
+
+ }
found = 1;
- break;
- }
+ break;
+ }
}
if (!found)
- printk(KERN_INFO "%s: DLCI %d not found by IB MAPPING cmd\n",
- card->devname, chan->dlci);
+ printk( KERN_INFO "%s: DLCI %d not found by IB MAPPING cmd\n",
+ card->devname, chan->dlci);
+}
+
+void s508_s514_lock(sdla_t *card, unsigned long *smp_flags)
+{
+
+ if (card->hw.type != SDLA_S514){
+#ifdef __SMP__
+ spin_lock_irqsave(&card->lock, *smp_flags);
+#else
+ disable_irq(card->hw.irq);
+#endif
+ }
+#ifdef __SMP__
+ else{
+ spin_lock(&card->lock);
+ }
+#endif
+}
+
+void s508_s514_unlock(sdla_t *card, unsigned long *smp_flags)
+{
+ if (card->hw.type != SDLA_S514){
+#ifdef __SMP__
+ spin_unlock_irqrestore(&card->lock, *smp_flags);
+#else
+ enable_irq(card->hw.irq);
+#endif
+ }
+#ifdef __SMP__
+ else{
+ spin_unlock(&card->lock);
+ }
+#endif
+
}
/****** End *****************************************************************/
diff --git a/drivers/net/wan/sdla_ppp.c b/drivers/net/wan/sdla_ppp.c
index d35ac7c18..1b900fc62 100644
--- a/drivers/net/wan/sdla_ppp.c
+++ b/drivers/net/wan/sdla_ppp.c
@@ -1,21 +1,39 @@
/*****************************************************************************
* sdla_ppp.c WANPIPE(tm) Multiprotocol WAN Link Driver. PPP module.
*
-* Author: Jaspreet Singh <jaspreet@sangoma.com>
+* Author: Nenad Corbic <ncorbic@sangoma.com>
*
-* Copyright: (c) 1995-1997 Sangoma Technologies Inc.
+* Copyright: (c) 1995-1999 Sangoma Technologies 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.
* ============================================================================
-* Mar 15, 1998 Alan Cox o 2.1.8x basic port.
+*
+* Oct 25, 1999 Nenad Corbic o Support for 2.0.X kernels
+* Moved dynamic route processing into
+* a polling routine.
+* Oct 07, 1999 Nenad Corbic o Support for S514 PCI card.
+* Gideon Hack o UPD and Updates executed using timer interrupt
+* Sep 10, 1999 Nenad Corbic o Fixed up the /proc statistics
+* Jul 20, 1999 Nenad Corbic o Remove the polling routines and use
+* interrupts instead.
+* Sep 17, 1998 Jaspreet Singh o Updates for 2.2.X Kernels.
+* Aug 13, 1998 Jaspreet Singh o Improved Line Tracing.
+* Jun 22, 1998 David Fong o Added remote IP address assignment
+* Mar 15, 1998 Alan Cox o 2.1.8x basic port.
+* Apr 16, 1998 Jaspreet Singh o using htons() for the IPX protocol.
+* Dec 09, 1997 Jaspreet Singh o Added PAP and CHAP.
+* o Implemented new routines like
+* ppp_set_inbnd_auth(), ppp_set_outbnd_auth(),
+* tokenize() and strstrip().
* Nov 27, 1997 Jaspreet Singh o Added protection against enabling of irqs
* while they have been disabled.
* Nov 24, 1997 Jaspreet Singh o Fixed another RACE condition caused by
* disabling and enabling of irqs.
-* o Added new counters for stats on disable/enable* IRQs.
+* o Added new counters for stats on disable/enable
+* IRQs.
* Nov 10, 1997 Jaspreet Singh o Initialized 'skb->mac.raw' to 'skb->data'
* before every netif_rx().
* o Free up the device structure in del_if().
@@ -56,6 +74,7 @@
* Jan 06, 1997 Gene Kozin Initial version.
*****************************************************************************/
+#include <linux/version.h>
#include <linux/kernel.h> /* printk(), and other useful stuff */
#include <linux/stddef.h> /* offsetof(), etc. */
#include <linux/errno.h> /* return codes */
@@ -65,10 +84,15 @@
#include <linux/wanpipe.h> /* WANPIPE common user API definitions */
#include <linux/if_arp.h> /* ARPHRD_* defines */
#include <asm/byteorder.h> /* htons(), etc. */
-#include <asm/uaccess.h> /* copyto/from user */
-#define _GNUC_
-#include <linux/sdla_ppp.h> /* PPP firmware API definitions */
+#include <linux/in.h> /* sockaddr_in */
+#include <linux/inet.h> /* in_aton(), in_ntoa() prototypes */
+
+#include <linux/inetdevice.h>
+#include <asm/uaccess.h>
+#include <linux/if.h>
+#include <linux/sdla_ppp.h> /* PPP firmware API definitions */
+#include <linux/sdlasfm.h> /* S514 Type Definition */
/****** Defines & Macros ****************************************************/
#ifdef _DEBUG_
@@ -76,130 +100,183 @@
#else
#define STATIC static
#endif
-#define PPP_DFLT_MTU 1500 /* default MTU */
-#define PPP_MAX_MTU 4000 /* maximum MTU */
+
+#define PPP_DFLT_MTU 1500 /* default MTU */
+#define PPP_MAX_MTU 4000 /* maximum MTU */
#define PPP_HDR_LEN 1
-#define CONNECT_TIMEOUT (90*HZ) /* link connection timeout */
-#define HOLD_DOWN_TIME (30*HZ) /* link hold down time */
+
+#define CONNECT_TIMEOUT (90*HZ) /* link connection timeout */
+#define HOLD_DOWN_TIME (5*HZ) /* link hold down time : Changed from 30 to 5 */
/* For handle_IPXWAN() */
#define CVHexToAscii(b) (((unsigned char)(b) > (unsigned char)9) ? ((unsigned char)'A' + ((unsigned char)(b) - (unsigned char)10)) : ((unsigned char)'0' + (unsigned char)(b)))
+/* Macro for enabling/disabling debugging comments */
+//#define NEX_DEBUG
+#ifdef NEX_DEBUG
+#define NEX_PRINTK(format, a...) printk(format, ## a)
+#else
+#define NEX_PRINTK(format, a...)
+#endif /* NEX_DEBUG */
+
+#define DCD(a) ( a & 0x08 ? "HIGH" : "LOW" )
+#define CTS(a) ( a & 0x20 ? "HIGH" : "LOW" )
+#define LCP(a) ( a == 0x09 ? "OPEN" : "CLOSED" )
+#define IP(a) ( a == 0x09 ? "ENABLED" : "DISABLED" )
+
+#define TMR_INT_ENABLED_UPDATE 1
+#define TMR_INT_ENABLED_PPP_EVENT 2
+#define TMR_INT_ENABLED_UDP 4
+
+/* Set Configuraton Command Definitions */
+#define PERCENT_TX_BUFF 60
+#define TIME_BETWEEN_CONF_REQ 30
+#define TIME_BETWEEN_PAP_CHAP_REQ 30
+#define WAIT_PAP_CHAP_WITHOUT_REPLY 300
+#define WAIT_AFTER_DCD_CTS_LOW 5
+#define TIME_DCD_CTS_LOW_AFTER_LNK_DOWN 10
+#define WAIT_DCD_HIGH_AFTER_ENABLE_COMM 900
+#define MAX_CONF_REQ_WITHOUT_REPLY 10
+#define MAX_TERM_REQ_WITHOUT_REPLY 2
+#define NUM_CONF_NAK_WITHOUT_REPLY 5
+#define NUM_AUTH_REQ_WITHOUT_REPLY 10
+
+#define END_OFFSET 0x1F0
+#if LINUX_VERSION_CODE < 0x020125
+#define test_and_set_bit set_bit
+#endif
+
/******Data Structures*****************************************************/
+
/* This structure is placed in the private data area of the device structure.
* The card structure used to occupy the private area but now the following
* structure will incorporate the card structure along with PPP specific data
*/
-
-typedef struct ppp_private_area
+
+typedef struct ppp_private_area
{
- sdla_t *card;
+ sdla_t* card;
unsigned long router_start_time; /*router start time in sec */
- unsigned long tick_counter; /*used for 5 second counter */
- unsigned mc; /*multicast support on or off */
+ unsigned long tick_counter; /*used for 5 second counter*/
+ unsigned mc; /*multicast support on or off*/
+ unsigned char enable_IPX;
+ unsigned long network_number;
+ unsigned char pap;
+ unsigned char chap;
+ unsigned char sysname[31]; /* system name for in-bnd auth*/
+ unsigned char userid[511]; /* list of user ids */
+ unsigned char passwd[511]; /* list of passwords */
+ unsigned protocol; /* SKB Protocol */
+ u32 ip_local; /* Local IP Address */
+ u32 ip_remote; /* remote IP Address */
+
+ unsigned char timer_int_enabled; /* Who enabled the timer inter*/
+ unsigned char update_comms_stats; /* Used by update function */
+ unsigned long curr_trace_addr; /* Trace information */
+ unsigned long start_trace_addr;
+ unsigned long end_trace_addr;
+
+ unsigned short udp_pkt_lgth;
+ char udp_pkt_src;
+ char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
+
/* PPP specific statistics */
- unsigned long if_send_entry;
- unsigned long if_send_skb_null;
- unsigned long if_send_broadcast;
- unsigned long if_send_multicast;
- unsigned long if_send_critical_ISR;
- unsigned long if_send_critical_non_ISR;
- unsigned long if_send_busy;
- unsigned long if_send_busy_timeout;
- unsigned long if_send_DRVSTATS_request;
- unsigned long if_send_PTPIPE_request;
- unsigned long if_send_wan_disconnected;
- unsigned long if_send_adptr_bfrs_full;
- unsigned long if_send_protocol_error;
- unsigned long if_send_tx_int_enabled;
- unsigned long if_send_bfr_passed_to_adptr;
- unsigned long rx_intr_no_socket;
- unsigned long rx_intr_DRVSTATS_request;
- unsigned long rx_intr_PTPIPE_request;
- unsigned long rx_intr_bfr_not_passed_to_stack;
- unsigned long rx_intr_bfr_passed_to_stack;
- unsigned long UDP_PTPIPE_mgmt_kmalloc_err;
- unsigned long UDP_PTPIPE_mgmt_adptr_type_err;
- unsigned long UDP_PTPIPE_mgmt_direction_err;
- unsigned long UDP_PTPIPE_mgmt_adptr_cmnd_timeout;
- unsigned long UDP_PTPIPE_mgmt_adptr_cmnd_OK;
- unsigned long UDP_PTPIPE_mgmt_passed_to_adptr;
- unsigned long UDP_PTPIPE_mgmt_passed_to_stack;
- unsigned long UDP_PTPIPE_mgmt_no_socket;
- unsigned long UDP_DRVSTATS_mgmt_kmalloc_err;
- unsigned long UDP_DRVSTATS_mgmt_adptr_type_err;
- unsigned long UDP_DRVSTATS_mgmt_direction_err;
- unsigned long UDP_DRVSTATS_mgmt_adptr_cmnd_timeout;
- unsigned long UDP_DRVSTATS_mgmt_adptr_cmnd_OK;
- unsigned long UDP_DRVSTATS_mgmt_passed_to_adptr;
- unsigned long UDP_DRVSTATS_mgmt_passed_to_stack;
- unsigned long UDP_DRVSTATS_mgmt_no_socket;
- unsigned long router_up_time;
-} ppp_private_area_t;
-/* variable for keeping track of enabling/disabling FT1 monitor status */
+ if_send_stat_t if_send_stat;
+ rx_intr_stat_t rx_intr_stat;
+ pipe_mgmt_stat_t pipe_mgmt_stat;
+ unsigned long router_up_time;
+
+}ppp_private_area_t;
+
+/* variable for keeping track of enabling/disabling FT1 monitor status */
static int rCount = 0;
+
extern void disable_irq(unsigned int);
extern void enable_irq(unsigned int);
/****** Function Prototypes *************************************************/
/* WAN link driver entry points. These are called by the WAN router module. */
-static int update(wan_device_t * wandev);
-static int new_if(wan_device_t * wandev, struct net_device *dev,
- wanif_conf_t * conf);
-static int del_if(wan_device_t * wandev, struct net_device *dev);
+static int update(wan_device_t *wandev);
+static int new_if(wan_device_t *wandev, struct net_device *dev, wanif_conf_t *conf);
+static int del_if(wan_device_t *wandev, struct net_device *dev);
+
/* WANPIPE-specific entry points */
-static int wpp_exec(struct sdla *card, void *u_cmd, void *u_data);
+static int wpp_exec (struct sdla *card, void *u_cmd, void *u_data);
+
/* Network device interface */
static int if_init(struct net_device *dev);
static int if_open(struct net_device *dev);
static int if_close(struct net_device *dev);
-static int if_header(struct sk_buff *skb, struct net_device *dev,
- unsigned short type, void *daddr, void *saddr, unsigned len);
+static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
+ void *daddr, void *saddr, unsigned len);
static int if_rebuild_hdr(struct sk_buff *skb);
+static struct net_device_stats *if_stats(struct net_device *dev);
static int if_send(struct sk_buff *skb, struct net_device *dev);
-static struct enet_statistics *if_stats(struct net_device *dev);
+
+
/* PPP firmware interface functions */
-static int ppp_read_version(sdla_t * card, char *str);
-static int ppp_configure(sdla_t * card, void *data);
-static int ppp_set_intr_mode(sdla_t * card, unsigned mode);
-static int ppp_comm_enable(sdla_t * card);
-static int ppp_comm_disable(sdla_t * card);
-static int ppp_get_err_stats(sdla_t * card);
-static int ppp_send(sdla_t * card, void *data, unsigned len, unsigned proto);
-static int ppp_error(sdla_t * card, int err, ppp_mbox_t * mb);
-/* Interrupt handlers */
-STATIC void wpp_isr(sdla_t * card);
-static void rx_intr(sdla_t * card);
-static void tx_intr(sdla_t * card);
+static int ppp_read_version(sdla_t *card, char *str);
+static int ppp_set_outbnd_auth(sdla_t *card, ppp_private_area_t *ppp_priv_area);
+static int ppp_set_inbnd_auth(sdla_t *card, ppp_private_area_t *ppp_priv_area);
+static int ppp_configure(sdla_t *card, void *data);
+static int ppp_set_intr_mode(sdla_t *card, unsigned char mode);
+static int ppp_comm_enable(sdla_t *card);
+static int ppp_comm_disable(sdla_t *card);
+static int ppp_get_err_stats(sdla_t *card);
+static int ppp_send(sdla_t *card, void *data, unsigned len, unsigned proto);
+static int ppp_error(sdla_t *card, int err, ppp_mbox_t *mb);
+
+STATIC void wpp_isr(sdla_t *card);
+static void rx_intr(sdla_t *card);
+static void event_intr(sdla_t *card);
+static void timer_intr(sdla_t *card);
+
/* Background polling routines */
-static void wpp_poll(sdla_t * card);
-static void poll_active(sdla_t * card);
-static void poll_connecting(sdla_t * card);
-static void poll_disconnected(sdla_t * card);
+static void process_route(sdla_t *card);
+static void poll_disconnected(sdla_t *card);
+
/* Miscellaneous functions */
-static int config502(sdla_t * card);
-static int config508(sdla_t * card);
+static int read_info( sdla_t *card );
+static int read_connection_info (sdla_t *card);
+static int remove_route( sdla_t *card );
+static int config508(ppp_private_area_t *ppp_priv_area, sdla_t *card);
static void show_disc_cause(sdla_t * card, unsigned cause);
-static unsigned char bps_to_speed_code(unsigned long bps);
-static int reply_udp(unsigned char *data, unsigned int mbox_len);
-static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, ppp_private_area_t * ppp_priv_area);
-static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, ppp_private_area_t * ppp_priv_area);
-static void init_ppp_tx_rx_buff(sdla_t * card);
-static int intr_test(sdla_t * card);
-static int udp_pkt_type(struct sk_buff *skb, sdla_t * card);
-static void init_ppp_priv_struct(ppp_private_area_t * ppp_priv_area);
-static void init_global_statistics(sdla_t * card);
+static int reply_udp( unsigned char *data, unsigned int mbox_len );
+static void process_udp_mgmt_pkt(sdla_t *card, struct net_device *dev,
+ ppp_private_area_t *ppp_priv_area);
+static void init_ppp_tx_rx_buff( sdla_t *card );
+static int intr_test( sdla_t *card );
+static int udp_pkt_type( struct sk_buff *skb , sdla_t *card);
+static void init_ppp_priv_struct( ppp_private_area_t *ppp_priv_area);
+static void init_global_statistics( sdla_t *card );
+static int tokenize(char *str, char **tokens);
+static char* strstrip(char *str, char *s);
+static int chk_bcast_mcast_addr(sdla_t* card, struct net_device* dev,
+ struct sk_buff *skb);
+static int Read_connection_info;
static int Intr_test_counter;
-static char TracingEnabled;
-static unsigned long curr_trace_addr;
-static unsigned long start_trace_addr;
static unsigned short available_buffer_space;
+
/* IPX functions */
-static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming);
-static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number, unsigned short proto);
+static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number,
+ unsigned char incoming);
+static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_PX,
+ unsigned long network_number, unsigned short proto);
+
+/* Lock Functions */
+static void s508_lock (sdla_t *card, unsigned long *smp_flags);
+static void s508_unlock (sdla_t *card, unsigned long *smp_flags);
+
+static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
+ struct sk_buff *skb, struct net_device* dev,
+ ppp_private_area_t* ppp_priv_area );
+static unsigned short calc_checksum (char *data, int len);
+
+
+
/****** Public Functions ****************************************************/
@@ -215,30 +292,40 @@ static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char
* Return: 0 o.k.
* < 0 failure.
*/
-int wpp_init(sdla_t * card, wandev_conf_t * conf)
+int wpp_init(sdla_t *card, wandev_conf_t *conf)
{
- union {
+ union
+ {
char str[80];
} u;
+
/* Verify configuration ID */
if (conf->config_id != WANCONFIG_PPP) {
+
printk(KERN_INFO "%s: invalid configuration ID %u!\n",
- card->devname, conf->config_id);
+ card->devname, conf->config_id);
return -EINVAL;
+
}
- /* Initialize protocol-specific fields */
- switch (card->hw.fwid) {
- case SFID_PPP502:
- card->mbox = (void *) (card->hw.dpmbase + PPP502_MB_OFFS);
- card->flags = (void *) (card->hw.dpmbase + PPP502_FLG_OFFS);
- break;
- case SFID_PPP508:
- card->mbox = (void *) (card->hw.dpmbase + PPP508_MB_OFFS);
- card->flags = (void *) (card->hw.dpmbase + PPP508_FLG_OFFS);
- break;
- default:
- return -EINVAL;
+
+ /* Initialize miscellaneous pointers to structures on the adapter */
+ switch (card->hw.type) {
+
+ case SDLA_S508:
+ card->mbox =(void*)(card->hw.dpmbase + PPP508_MB_OFFS);
+ card->flags=(void*)(card->hw.dpmbase + PPP508_FLG_OFFS);
+ break;
+
+ case SDLA_S514:
+ card->mbox =(void*)(card->hw.dpmbase + PPP514_MB_OFFS);
+ card->flags=(void*)(card->hw.dpmbase + PPP514_FLG_OFFS);
+ break;
+
+ default:
+ return -EINVAL;
+
}
+
/* Read firmware version. Note that when adapter initializes, it
* clears the mailbox, so it may appear that the first command was
* executed successfully when in fact it was merely erased. To work
@@ -246,33 +333,36 @@ int wpp_init(sdla_t * card, wandev_conf_t * conf)
*/
if (ppp_read_version(card, NULL) || ppp_read_version(card, u.str))
return -EIO;
- printk(KERN_INFO "%s: running PPP firmware v%s\n", card->devname, u.str);
+
+ printk(KERN_INFO "%s: running PPP firmware v%s\n",card->devname, u.str);
/* Adjust configuration and set defaults */
card->wandev.mtu = (conf->mtu) ?
- min(conf->mtu, PPP_MAX_MTU) : PPP_DFLT_MTU;
- card->wandev.bps = conf->bps;
- card->wandev.interface = conf->interface;
- card->wandev.clocking = conf->clocking;
- card->wandev.station = conf->station;
- card->isr = &wpp_isr;
- card->poll = &wpp_poll;
- card->exec = &wpp_exec;
- card->wandev.update = &update;
- card->wandev.new_if = &new_if;
- card->wandev.del_if = &del_if;
- card->wandev.state = WAN_DISCONNECTED;
- card->wandev.udp_port = conf->udp_port;
- card->wandev.ttl = conf->ttl;
+ min(conf->mtu, PPP_MAX_MTU) : PPP_DFLT_MTU;
+
+ card->wandev.bps = conf->bps;
+ card->wandev.interface = conf->interface;
+ card->wandev.clocking = conf->clocking;
+ card->wandev.station = conf->station;
+ card->isr = &wpp_isr;
+ card->poll = NULL;
+ card->exec = &wpp_exec;
+ card->wandev.update = &update;
+ card->wandev.new_if = &new_if;
+ card->wandev.del_if = &del_if;
+ card->wandev.state = WAN_DISCONNECTED;
+ card->wandev.udp_port = conf->udp_port;
+ card->wandev.ttl = conf->ttl;
card->irq_dis_if_send_count = 0;
- card->irq_dis_poll_count = 0;
- TracingEnabled = 0;
- card->wandev.enable_IPX = conf->enable_IPX;
- if (conf->network_number)
- card->wandev.network_number = conf->network_number;
- else
- card->wandev.network_number = 0xDEADBEEF;
+ card->irq_dis_poll_count = 0;
+ card->u.p.authenticator = conf->u.ppp.authenticator;
+ card->u.p.ip_mode = conf->u.ppp.ip_mode ?
+ conf->u.ppp.ip_mode : WANOPT_PPP_STATIC;
+ card->TracingEnabled = 0;
+ Read_connection_info = 1;
+
/* initialize global statistics */
- init_global_statistics(card);
+ init_global_statistics( card );
+
return 0;
}
@@ -281,19 +371,43 @@ int wpp_init(sdla_t * card, wandev_conf_t * conf)
/*============================================================================
* Update device status & statistics.
*/
-static int update(wan_device_t * wandev)
+static int update(wan_device_t *wandev)
{
- sdla_t *card;
+ sdla_t* card = wandev->private;
+ struct net_device* dev = card->wandev.dev;
+ volatile ppp_private_area_t *ppp_priv_area = dev->priv;
+ ppp_flags_t *flags = card->flags;
+ unsigned long timeout;
+
/* sanity checks */
if ((wandev == NULL) || (wandev->private == NULL))
return -EFAULT;
+
if (wandev->state == WAN_UNCONFIGURED)
return -ENODEV;
- if (test_and_set_bit(0, (void *) &wandev->critical))
+
+ //FIXME: Do we need this
+ if (test_bit(0, (void*)&wandev->critical))
return -EAGAIN;
- card = wandev->private;
- ppp_get_err_stats(card);
- wandev->critical = 0;
+
+ ppp_priv_area->update_comms_stats = 2;
+ ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UPDATE;
+ flags->imask |= PPP_INTR_TIMER;
+
+ /* wait a maximum of 1 second for the statistics to be updated */
+ timeout = jiffies;
+ for(;;) {
+ if(ppp_priv_area->update_comms_stats == 0){
+ break;
+ }
+ if ((jiffies - timeout) > (1 * HZ)){
+ ppp_priv_area->update_comms_stats = 0;
+ ppp_priv_area->timer_int_enabled &=
+ ~TMR_INT_ENABLED_UPDATE;
+ return -EAGAIN;
+ }
+ }
+
return 0;
}
@@ -309,46 +423,98 @@ static int update(wan_device_t * wandev)
* Return: 0 o.k.
* < 0 failure (channel will not be created)
*/
-
-static int new_if(wan_device_t * wandev, struct net_device *dev, wanif_conf_t * conf)
+static int new_if(wan_device_t *wandev, struct net_device *dev, wanif_conf_t *conf)
{
sdla_t *card = wandev->private;
ppp_private_area_t *ppp_priv_area;
+
if (wandev->ndev)
return -EEXIST;
+
if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) {
+
printk(KERN_INFO "%s: invalid interface name!\n",
- card->devname);
+ card->devname);
return -EINVAL;
+
}
+
/* allocate and initialize private data */
ppp_priv_area = kmalloc(sizeof(ppp_private_area_t), GFP_KERNEL);
- if (ppp_priv_area == NULL)
- return -ENOMEM;
+
+ if( ppp_priv_area == NULL )
+ return -ENOMEM;
+
memset(ppp_priv_area, 0, sizeof(ppp_private_area_t));
- ppp_priv_area->card = card;
+
+ ppp_priv_area->card = card;
+
/* initialize data */
strcpy(card->u.p.if_name, conf->name);
+
/* initialize data in ppp_private_area structure */
- init_ppp_priv_struct(ppp_priv_area);
+
+ init_ppp_priv_struct( ppp_priv_area );
+
ppp_priv_area->mc = conf->mc;
+ ppp_priv_area->pap = conf->pap;
+ ppp_priv_area->chap = conf->chap;
+
+ /* If no user ids are specified */
+ if(!strlen(conf->userid) && (ppp_priv_area->pap||ppp_priv_area->chap)){
+ kfree(ppp_priv_area);
+ return -EINVAL;
+ }
+
+ /* If no passwords are specified */
+ if(!strlen(conf->passwd) && (ppp_priv_area->pap||ppp_priv_area->chap)){
+ kfree(ppp_priv_area);
+ return -EINVAL;
+ }
+
+ if(strlen(conf->sysname) > 31){
+ kfree(ppp_priv_area);
+ return -EINVAL;
+ }
+
+ /* If no system name is specified */
+ if(!strlen(conf->sysname) && (card->u.p.authenticator)){
+ kfree(ppp_priv_area);
+ return -EINVAL;
+ }
+
+ /* copy the data into the ppp private structure */
+ memcpy(ppp_priv_area->userid, conf->userid, strlen(conf->userid));
+ memcpy(ppp_priv_area->passwd, conf->passwd, strlen(conf->passwd));
+ memcpy(ppp_priv_area->sysname, conf->sysname, strlen(conf->sysname));
+
+
+ ppp_priv_area->enable_IPX = conf->enable_IPX;
+ if (conf->network_number)
+ ppp_priv_area->network_number = conf->network_number;
+ else
+ ppp_priv_area->network_number = 0xDEADBEEF;
+
+
/* prepare network device data space for registration */
dev->name = card->u.p.if_name;
dev->init = &if_init;
dev->priv = ppp_priv_area;
+
return 0;
}
/*============================================================================
* Delete logical channel.
*/
-
-static int del_if(wan_device_t * wandev, struct net_device *dev)
+static int del_if(wan_device_t *wandev, struct net_device *dev)
{
if (dev->priv) {
- kfree(dev->priv);
- dev->priv = NULL;
- }
+
+ kfree(dev->priv);
+ dev->priv = NULL;
+ }
+
return 0;
}
@@ -358,26 +524,36 @@ static int del_if(wan_device_t * wandev, struct net_device *dev)
* Execute adapter interface command.
*/
+//FIXME: Why do we need this ????
static int wpp_exec(struct sdla *card, void *u_cmd, void *u_data)
{
ppp_mbox_t *mbox = card->mbox;
int len;
- if(copy_from_user((void *) &mbox->cmd, u_cmd, sizeof(ppp_cmd_t)))
+
+ if (copy_from_user((void*)&mbox->cmd, u_cmd, sizeof(ppp_cmd_t)))
return -EFAULT;
+
len = mbox->cmd.length;
+
if (len) {
- if(copy_from_user((void *) &mbox->data, u_data, len))
+
+ if( copy_from_user((void*)&mbox->data, u_data, len))
return -EFAULT;
+
}
+
/* execute command */
if (!sdla_exec(mbox))
return -EIO;
+
/* return result */
- if(copy_to_user(u_cmd, (void *) &mbox->cmd, sizeof(ppp_cmd_t)))
+ if( copy_to_user(u_cmd, (void*)&mbox->cmd, sizeof(ppp_cmd_t)))
return -EFAULT;
len = mbox->cmd.length;
- if (len && u_data && copy_to_user(u_data, (void *) &mbox->data, len))
+
+ if (len && u_data && copy_to_user(u_data, (void*)&mbox->data, len))
return -EFAULT;
+
return 0;
}
@@ -390,32 +566,49 @@ static int wpp_exec(struct sdla *card, void *u_cmd, void *u_data)
* interface registration. Returning anything but zero will fail interface
* registration.
*/
-
static int if_init(struct net_device *dev)
{
ppp_private_area_t *ppp_priv_area = dev->priv;
sdla_t *card = ppp_priv_area->card;
wan_device_t *wandev = &card->wandev;
+#ifndef LINUX_2_1
+ int i;
+#endif
/* Initialize device driver entry points */
- dev->open = &if_open;
- dev->stop = &if_close;
- dev->hard_header = &if_header;
- dev->rebuild_header = &if_rebuild_hdr;
- dev->hard_start_xmit = &if_send;
- dev->get_stats = &if_stats;
+ dev->open = &if_open;
+ dev->stop = &if_close;
+ dev->hard_header = &if_header;
+ dev->rebuild_header = &if_rebuild_hdr;
+ dev->hard_start_xmit = &if_send;
+ dev->get_stats = &if_stats;
+
+
/* Initialize media-specific parameters */
- dev->type = ARPHRD_PPP; /* ARP h/w type */
- dev->mtu = wandev->mtu;
- dev->hard_header_len = PPP_HDR_LEN; /* media header length */
+ dev->type = ARPHRD_PPP; /* ARP h/w type */
+ dev->flags |= IFF_POINTOPOINT;
+
+ /* Enable Mulitcasting if specified by user*/
+ if (ppp_priv_area->mc == WANOPT_YES){
+ dev->flags |= IFF_MULTICAST;
+ }
+
+#ifndef LINUX_2_1
+ dev->family = AF_INET;
+#endif
+ dev->mtu = wandev->mtu;
+ dev->hard_header_len = PPP_HDR_LEN; /* media header length */
+
/* Initialize hardware parameters (just for reference) */
- dev->irq = wandev->irq;
- dev->dma = wandev->dma;
- dev->base_addr = wandev->ioport;
- dev->mem_start = (unsigned long)wandev->maddr;
- dev->mem_end = dev->mem_start + wandev->msize - 1;
- /* Set transmit buffer queue length */
- dev->tx_queue_len = 100;
+ dev->irq = wandev->irq;
+ dev->dma = wandev->dma;
+ dev->base_addr = wandev->ioport;
+ dev->mem_start = wandev->maddr;
+ dev->mem_end = wandev->maddr + wandev->msize - 1;
+
+ /* Set transmit buffer queue length */
+ dev->tx_queue_len = 100;
+
/* Initialize socket buffers */
dev_init_buffers(dev);
return 0;
@@ -428,7 +621,6 @@ static int if_init(struct net_device *dev)
*
* Return 0 if O.k. or errno.
*/
-
static int if_open(struct net_device *dev)
{
ppp_private_area_t *ppp_priv_area = dev->priv;
@@ -436,48 +628,100 @@ static int if_open(struct net_device *dev)
ppp_flags_t *flags = card->flags;
struct timeval tv;
int err = 0;
+
if (dev->start)
- return -EBUSY; /* only one open is allowed */
- if (test_and_set_bit(0, (void *) &card->wandev.critical))
+ return -EBUSY; /* only one open is allowed */
+
+ if (test_and_set_bit(0, (void*)&card->wandev.critical))
return -EAGAIN;
- if ((card->hw.fwid == SFID_PPP502) ? config502(card) : config508(card)) {
- err = -EIO;
- card->wandev.critical = 0;
- return err;
- }
- Intr_test_counter = 0;
- err = intr_test(card);
- if ((err) || (Intr_test_counter != (MAX_INTR_TEST_COUNTER + 1))) {
- printk(KERN_INFO "%s: Interrupt Test Failed, Counter: %i\n",
- card->devname, Intr_test_counter);
- err = -EIO;
- card->wandev.critical = 0;
- return err;
+
+ if (!card->configured){
+
+ if (config508(ppp_priv_area, card)){
+
+ err = -EIO;
+ card->wandev.critical = 0;
+ return err;
+ }
+
+ Intr_test_counter = 0;
+ err = intr_test( card );
+
+ if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) {
+ printk("%s: Interrupt Test Failed, Counter: %i\n",
+ card->devname, Intr_test_counter);
+ printk( "%s: Please choose another interrupt\n",card->devname);
+ err = -EIO;
+ card->wandev.critical = 0;
+ return err;
+ }
+
+ printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n",
+ card->devname, Intr_test_counter);
+ card->configured = 1;
+
}
- printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n",
- card->devname, Intr_test_counter);
+
/* Initialize Rx/Tx buffer control fields */
- init_ppp_tx_rx_buff(card);
- if (ppp_set_intr_mode(card, 0x03)) {
+ init_ppp_tx_rx_buff( card );
+
+ if (ppp_set_intr_mode(card, PPP_INTR_RXRDY|
+ PPP_INTR_TXRDY|
+ PPP_INTR_MODEM|
+ PPP_INTR_CMD |
+ PPP_INTR_DISC |
+ PPP_INTR_OPEN |
+ PPP_INTR_DROP_DTR |
+ PPP_INTR_TIMER)) {
+
err = -EIO;
card->wandev.critical = 0;
return err;
+
}
- flags->imask &= ~0x02;
+
+ /* Turn off the transmit and timer interrupt */
+ flags->imask &= ~(PPP_INTR_TXRDY | PPP_INTR_TIMER) ;
+
+ /* If you are not the authenticator and any one of the protocol is
+ * enabled then we call the set_out_bound_authentication.
+ */
+ if ( !card->u.p.authenticator && (ppp_priv_area->pap || ppp_priv_area->chap)) {
+ if ( ppp_set_outbnd_auth(card, ppp_priv_area) ){
+ err = -EIO;
+ card->wandev.critical = 0;
+ return err;
+ }
+ }
+
+ /* If you are the authenticator and any one of the protocol is enabled
+ * then we call the set_in_bound_authentication.
+ */
+ if ( card->u.p.authenticator && (ppp_priv_area->pap || ppp_priv_area->chap)) {
+ if ( ppp_set_inbnd_auth(card, ppp_priv_area) ){
+ err = -EIO;
+ card->wandev.critical = 0;
+ return err;
+ }
+ }
+
if (ppp_comm_enable(card)) {
err = -EIO;
card->wandev.critical = 0;
return err;
}
+
+
wanpipe_set_state(card, WAN_CONNECTING);
wanpipe_open(card);
dev->mtu = min(dev->mtu, card->wandev.mtu);
dev->interrupt = 0;
dev->tbusy = 0;
dev->start = 1;
- do_gettimeofday(&tv);
+ do_gettimeofday( &tv );
ppp_priv_area->router_start_time = tv.tv_sec;
card->wandev.critical = 0;
+
return err;
}
@@ -486,13 +730,14 @@ static int if_open(struct net_device *dev)
* o if this is the last open, then disable communications and interrupts.
* o reset flags.
*/
-
static int if_close(struct net_device *dev)
{
ppp_private_area_t *ppp_priv_area = dev->priv;
sdla_t *card = ppp_priv_area->card;
- if (test_and_set_bit(0, (void *) &card->wandev.critical))
+
+ if (test_and_set_bit(0, (void*)&card->wandev.critical))
return -EAGAIN;
+
dev->start = 0;
wanpipe_close(card);
wanpipe_set_state(card, WAN_DISCONNECTED);
@@ -511,19 +756,21 @@ static int if_close(struct net_device *dev)
*
* Return: media header length.
*/
-
static int if_header(struct sk_buff *skb, struct net_device *dev,
- unsigned short type, void *daddr, void *saddr, unsigned len)
+ unsigned short type, void *daddr, void *saddr, unsigned len)
{
- switch (type)
+ switch (type)
{
case ETH_P_IP:
+
case ETH_P_IPX:
- skb->protocol = type;
+ skb->protocol = htons(type);
break;
+
default:
skb->protocol = 0;
}
+
return PPP_HDR_LEN;
}
@@ -534,13 +781,14 @@ static int if_header(struct sk_buff *skb, struct net_device *dev,
* 0 physical address not resolved
*/
-static int if_rebuild_hdr(struct sk_buff *skb)
+static int if_rebuild_hdr (struct sk_buff *skb)
{
- struct net_device *dev=skb->dev;
+ struct net_device *dev = skb->dev;
ppp_private_area_t *ppp_priv_area = dev->priv;
sdla_t *card = ppp_priv_area->card;
+
printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n",
- card->devname, dev->name);
+ card->devname, dev->name);
return 1;
}
@@ -561,303 +809,355 @@ static int if_rebuild_hdr(struct sk_buff *skb)
* 2. Setting tbusy flag will inhibit further transmit requests from the
* protocol stack and can be used for flow control with protocol layer.
*/
-
-static int if_send(struct sk_buff *skb, struct net_device *dev)
+static int if_send (struct sk_buff *skb, struct net_device *dev)
{
ppp_private_area_t *ppp_priv_area = dev->priv;
sdla_t *card = ppp_priv_area->card;
unsigned char *sendpacket;
- unsigned long check_braddr, check_mcaddr;
- unsigned long host_cpu_flags;
+ unsigned long smp_flags;
ppp_flags_t *flags = card->flags;
int retry = 0;
- int err, udp_type;
- ++ppp_priv_area->if_send_entry;
+ int udp_type;
+
+
+ ++ppp_priv_area->if_send_stat.if_send_entry;
+
if (skb == NULL) {
+
/* If we get here, some higher layer thinks we've missed an
* tx-done interrupt.
*/
printk(KERN_INFO "%s: interface %s got kicked!\n",
- card->devname, dev->name);
- ++ppp_priv_area->if_send_skb_null;
+ card->devname, dev->name);
+
+ ++ppp_priv_area->if_send_stat.if_send_skb_null;
+
mark_bh(NET_BH);
return 0;
+
}
+
if (dev->tbusy) {
+
/* If our device stays busy for at least 5 seconds then we will
* kick start the device by making dev->tbusy = 0. We expect
* that our device never stays busy more than 5 seconds. So this
* is only used as a last resort.
*/
- ++ppp_priv_area->if_send_busy;
- ++card->wandev.stats.collisions;
- if ((jiffies - ppp_priv_area->tick_counter) < (5 * HZ)) {
+
+ ++ppp_priv_area->if_send_stat.if_send_tbusy;
+ ++card->wandev.stats.collisions;
+
+ if ((jiffies - ppp_priv_area->tick_counter) < (5*HZ)) {
return 1;
}
- printk(KERN_INFO "%s: Transmit times out\n", card->devname);
- ++ppp_priv_area->if_send_busy_timeout;
- /* unbusy the card (because only one interface per card) */
+
+ printk (KERN_INFO "%s: Transmit times out\n",card->devname);
+
+ ++ppp_priv_area->if_send_stat.if_send_tbusy_timeout;
+ ++card->wandev.stats.collisions;
+
+ /* unbusy the card (because only one interface per card)*/
dev->tbusy = 0;
- }
+ }
sendpacket = skb->data;
- udp_type = udp_pkt_type(skb, card);
- if (udp_type == UDP_DRVSTATS_TYPE) {
- ++ppp_priv_area->if_send_DRVSTATS_request;
- process_udp_driver_call(UDP_PKT_FRM_STACK, card, skb, dev,
- ppp_priv_area);
- dev_kfree_skb(skb);
- return 0;
- } else if (udp_type == UDP_PTPIPE_TYPE)
- ++ppp_priv_area->if_send_PTPIPE_request;
- /* retreive source address in two forms: broadcast & multicast */
- check_braddr = sendpacket[15];
- check_mcaddr = sendpacket[12];
- check_braddr = check_braddr << 8;
- check_mcaddr = check_mcaddr << 8;
- check_braddr |= sendpacket[14];
- check_mcaddr |= sendpacket[13];
- check_braddr = check_braddr << 8;
- check_mcaddr = check_mcaddr << 8;
- check_braddr |= sendpacket[13];
- check_mcaddr |= sendpacket[14];
- check_braddr = check_braddr << 8;
- check_mcaddr = check_mcaddr << 8;
- check_braddr |= sendpacket[12];
- check_mcaddr |= sendpacket[15];
- /* if the Source Address is a Multicast address */
- if ((ppp_priv_area->mc == WANOPT_NO) && (check_mcaddr >= 0xE0000001)
- && (check_mcaddr <= 0xFFFFFFFE)) {
- printk(KERN_INFO "%s: Mutlicast Src. Addr. silently discarded\n"
- ,card->devname);
- dev_kfree_skb(skb);
- ++ppp_priv_area->if_send_multicast;
- ++card->wandev.stats.tx_dropped;
+
+ udp_type = udp_pkt_type( skb, card );
+
+
+ if (udp_type == UDP_PTPIPE_TYPE){
+ if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev,
+ ppp_priv_area)){
+ flags->imask |= PPP_INTR_TIMER;
+ }
+ ++ppp_priv_area->if_send_stat.if_send_PIPE_request;
return 0;
+
}
- disable_irq(card->hw.irq);
- ++card->irq_dis_if_send_count;
- if (test_and_set_bit(0, (void *) &card->wandev.critical)) {
- if (card->wandev.critical == CRITICAL_IN_ISR) {
- /* If the critical flag is set due to an Interrupt
- * then set enable transmit interrupt flag to enable
- * transmit interrupt. (delay interrupt)
- */
- card->wandev.enable_tx_int = 1;
- dev->tbusy = 1;
- /* set the counter to see if we get the interrupt in
- * 5 seconds.
- */
- ppp_priv_area->tick_counter = jiffies;
- ++ppp_priv_area->if_send_critical_ISR;
- save_flags(host_cpu_flags);
- cli();
- if ((!(--card->irq_dis_if_send_count)) &&
- (!card->irq_dis_poll_count))
- enable_irq(card->hw.irq);
- restore_flags(host_cpu_flags);
- return 1;
+
+ /* Check for broadcast and multicast addresses
+ * If found, drop (deallocate) a packet and return.
+ */
+ if(chk_bcast_mcast_addr(card, dev, skb)){
+ return 0;
+ }
+
+
+ if(card->hw.type != SDLA_S514){
+ s508_lock(card,&smp_flags);
+ }
+
+ if (test_and_set_bit(0, (void*)&card->wandev.critical)) {
+
+ printk(KERN_INFO "%s: Critical in if_send: %x\n",
+ card->wandev.name,card->wandev.critical);
+ dev_kfree_skb(skb);
+
+ ++card->wandev.stats.tx_dropped;
+ ++ppp_priv_area->if_send_stat.if_send_critical_non_ISR;
+
+ if(card->hw.type != SDLA_S514){
+ s508_unlock(card,&smp_flags);
}
- dev_kfree_skb(skb);
- ++ppp_priv_area->if_send_critical_non_ISR;
- save_flags(host_cpu_flags);
- cli();
- if ((!(--card->irq_dis_if_send_count)) &&
- (!card->irq_dis_poll_count))
- enable_irq(card->hw.irq);
- restore_flags(host_cpu_flags);
+
return 0;
}
- if (udp_type == UDP_PTPIPE_TYPE) {
- err = process_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb,
- dev, ppp_priv_area);
- } else if (card->wandev.state != WAN_CONNECTED) {
- ++ppp_priv_area->if_send_wan_disconnected;
- ++card->wandev.stats.tx_dropped;
- } else if (!skb->protocol) {
- ++ppp_priv_area->if_send_protocol_error;
- ++card->wandev.stats.tx_errors;
+
+ if (card->wandev.state != WAN_CONNECTED) {
+
+ ++ppp_priv_area->if_send_stat.if_send_wan_disconnected;
+ ++card->wandev.stats.tx_dropped;
+
+ } else if (!skb->protocol) {
+ ++ppp_priv_area->if_send_stat.if_send_protocol_error;
+ ++card->wandev.stats.tx_errors;
+
} else {
- /*If it's IPX change the network numbers to 0 if they're ours. */
- if (skb->protocol == ETH_P_IPX) {
- if (card->wandev.enable_IPX) {
- switch_net_numbers(skb->data,
- card->wandev.network_number, 0);
+
+ /*If it's IPX change the network numbers to 0 if they're ours.*/
+ if( skb->protocol == htons(ETH_P_IPX) ) {
+ if(ppp_priv_area->enable_IPX) {
+ switch_net_numbers( skb->data,
+ ppp_priv_area->network_number, 0);
} else {
++card->wandev.stats.tx_dropped;
goto tx_done;
}
}
+
if (ppp_send(card, skb->data, skb->len, skb->protocol)) {
retry = 1;
dev->tbusy = 1;
- ++ppp_priv_area->if_send_adptr_bfrs_full;
- ++ppp_priv_area->if_send_tx_int_enabled;
+ ++ppp_priv_area->if_send_stat.if_send_adptr_bfrs_full;
+ ++ppp_priv_area->if_send_stat.if_send_tx_int_enabled;
ppp_priv_area->tick_counter = jiffies;
- ++card->wandev.stats.tx_errors;
flags->imask |= 0x02; /* unmask Tx interrupts */
} else {
- ++ppp_priv_area->if_send_bfr_passed_to_adptr;
+ ++ppp_priv_area->if_send_stat.if_send_bfr_passed_to_adptr;
++card->wandev.stats.tx_packets;
card->wandev.stats.tx_bytes += skb->len;
}
- }
-tx_done:
- if (!retry) {
+ }
+
+tx_done:
+ if (!retry){
dev_kfree_skb(skb);
}
+
card->wandev.critical = 0;
- save_flags(host_cpu_flags);
- cli();
- if ((!(--card->irq_dis_if_send_count)) && (!card->irq_dis_poll_count))
- enable_irq(card->hw.irq);
- restore_flags(host_cpu_flags);
+
+ if(card->hw.type != SDLA_S514){
+ s508_unlock(card,&smp_flags);
+ }
+
+
return retry;
}
+
+/*=============================================================================
+ * Store a UDP management packet for later processing.
+ */
+
+static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
+ struct sk_buff *skb, struct net_device* dev,
+ ppp_private_area_t* ppp_priv_area )
+{
+ int udp_pkt_stored = 0;
+
+ if(!ppp_priv_area->udp_pkt_lgth && (skb->len<=MAX_LGTH_UDP_MGNT_PKT)){
+ ppp_priv_area->udp_pkt_lgth = skb->len;
+ ppp_priv_area->udp_pkt_src = udp_pkt_src;
+ memcpy(ppp_priv_area->udp_pkt_data, skb->data, skb->len);
+ ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UDP;
+ ppp_priv_area->protocol = skb->protocol;
+ udp_pkt_stored = 1;
+ }else{
+ if (skb->len > MAX_LGTH_UDP_MGNT_PKT){
+ printk(KERN_INFO "%s: PIPEMON UDP request too long : %i\n",
+ card->devname, skb->len);
+ }else{
+ printk(KERN_INFO "%s: PIPEMON UPD request already pending\n",
+ card->devname);
+ }
+ ppp_priv_area->udp_pkt_lgth = 0;
+ }
+
+ dev_kfree_skb(skb);
+ return(udp_pkt_stored);
+}
+
+
+
/*============================================================================
* Reply to UDP Management system.
* Return length of reply.
*/
-
-static int reply_udp(unsigned char *data, unsigned int mbox_len)
+static int reply_udp( unsigned char *data, unsigned int mbox_len )
{
- unsigned short len, udp_length, temp, i, ip_length;
- unsigned long sum;
+ unsigned short len, udp_length, temp, ip_length;
+ unsigned long ip_temp;
+ int even_bound = 0;
+ ppp_udp_pkt_t *p_udp_pkt = (ppp_udp_pkt_t *)data;
+
/* Set length of packet */
- len = mbox_len + 60;
+ len = sizeof(ip_pkt_t)+
+ sizeof(udp_pkt_t)+
+ sizeof(wp_mgmt_t)+
+ sizeof(cblock_t)+
+ mbox_len;
+
/* fill in UDP reply */
- data[36] = 0x02;
+ p_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY;
+
/* fill in UDP length */
- udp_length = mbox_len + 40;
+ udp_length = sizeof(udp_pkt_t)+
+ sizeof(wp_mgmt_t)+
+ sizeof(cblock_t)+
+ mbox_len;
+
+
/* put it on an even boundary */
- if (udp_length & 0x0001) {
+ if ( udp_length & 0x0001 ) {
udp_length += 1;
len += 1;
- }
- temp = (udp_length << 8) | (udp_length >> 8);
- memcpy(&data[24], &temp, 2);
+ even_bound=1;
+ }
+
+ temp = (udp_length<<8)|(udp_length>>8);
+ p_udp_pkt->udp_pkt.udp_length = temp;
+
+
/* swap UDP ports */
- memcpy(&temp, &data[20], 2);
- memcpy(&data[20], &data[22], 2);
- memcpy(&data[22], &temp, 2);
+ temp = p_udp_pkt->udp_pkt.udp_src_port;
+ p_udp_pkt->udp_pkt.udp_src_port =
+ p_udp_pkt->udp_pkt.udp_dst_port;
+ p_udp_pkt->udp_pkt.udp_dst_port = temp;
+
+
/* add UDP pseudo header */
temp = 0x1100;
- memcpy(&data[udp_length + 20], &temp, 2);
- temp = (udp_length << 8) | (udp_length >> 8);
- memcpy(&data[udp_length + 22], &temp, 2);
+ *((unsigned short *)(p_udp_pkt->data+mbox_len+even_bound)) = temp;
+ temp = (udp_length<<8)|(udp_length>>8);
+ *((unsigned short *)(p_udp_pkt->data+mbox_len+even_bound+2)) = temp;
+
/* calculate UDP checksum */
- data[26] = data[27] = 0;
- sum = 0;
- for (i = 0; i < udp_length + 12; i += 2) {
- memcpy(&temp, &data[12 + i], 2);
- sum += (unsigned long) temp;
- }
- while (sum >> 16) {
- sum = (sum & 0xffffUL) + (sum >> 16);
- }
- temp = (unsigned short) sum;
- temp = ~temp;
- if (temp == 0)
- temp = 0xffff;
- memcpy(&data[26], &temp, 2);
+ p_udp_pkt->udp_pkt.udp_checksum = 0;
+ p_udp_pkt->udp_pkt.udp_checksum =
+ calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET);
+
/* fill in IP length */
- ip_length = udp_length + 20;
- temp = (ip_length << 8) | (ip_length >> 8);
- memcpy(&data[2], &temp, 2);
+ ip_length = udp_length + sizeof(ip_pkt_t);
+ temp = (ip_length<<8)|(ip_length>>8);
+ p_udp_pkt->ip_pkt.total_length = temp;
+
/* swap IP addresses */
- memcpy(&temp, &data[12], 2);
- memcpy(&data[12], &data[16], 2);
- memcpy(&data[16], &temp, 2);
- memcpy(&temp, &data[14], 2);
- memcpy(&data[14], &data[18], 2);
- memcpy(&data[18], &temp, 2);
+ ip_temp = p_udp_pkt->ip_pkt.ip_src_address;
+ p_udp_pkt->ip_pkt.ip_src_address = p_udp_pkt->ip_pkt.ip_dst_address;
+ p_udp_pkt->ip_pkt.ip_dst_address = ip_temp;
+
/* fill in IP checksum */
- data[10] = data[11] = 0;
- sum = 0;
- for (i = 0; i < 20; i += 2) {
- memcpy(&temp, &data[i], 2);
- sum += (unsigned long) temp;
+ p_udp_pkt->ip_pkt.hdr_checksum = 0;
+ p_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t));
+
+ return len;
+
+} /* reply_udp */
+
+unsigned short calc_checksum (char *data, int len)
+{
+ unsigned short temp;
+ unsigned long sum=0;
+ int i;
+
+ for( i = 0; i <len; i+=2 ) {
+ memcpy(&temp,&data[i],2);
+ sum += (unsigned long)temp;
}
- while (sum >> 16) {
+
+ while (sum >> 16 ) {
sum = (sum & 0xffffUL) + (sum >> 16);
}
- temp = (unsigned short) sum;
+
+ temp = (unsigned short)sum;
temp = ~temp;
- if (temp == 0)
+
+ if( temp == 0 )
temp = 0xffff;
- memcpy(&data[10], &temp, 2);
- return len;
-} /* reply_udp */
+
+ return temp;
+}
/*
If incoming is 0 (outgoing)- if the net numbers is ours make it 0
if incoming is 1 - if the net number is 0 make it ours
- */
+*/
static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming)
{
unsigned long pnetwork_number;
- pnetwork_number = (unsigned long) ((sendpacket[6] << 24) +
- (sendpacket[7] << 16) + (sendpacket[8] << 8) +
- sendpacket[9]);
+
+ pnetwork_number = (unsigned long)((sendpacket[6] << 24) +
+ (sendpacket[7] << 16) + (sendpacket[8] << 8) +
+ sendpacket[9]);
+
if (!incoming) {
- /* If the destination network number is ours, make it 0 */
- if (pnetwork_number == network_number) {
- sendpacket[6] = sendpacket[7] = sendpacket[8] =
- sendpacket[9] = 0x00;
+ //If the destination network number is ours, make it 0
+ if( pnetwork_number == network_number) {
+ sendpacket[6] = sendpacket[7] = sendpacket[8] =
+ sendpacket[9] = 0x00;
}
} else {
- /* If the incoming network is 0, make it ours */
- if (pnetwork_number == 0) {
- sendpacket[6] = (unsigned char) (network_number >> 24);
- sendpacket[7] = (unsigned char) ((network_number &
- 0x00FF0000) >> 16);
- sendpacket[8] = (unsigned char) ((network_number &
- 0x0000FF00) >> 8);
- sendpacket[9] = (unsigned char) (network_number &
- 0x000000FF);
+ //If the incoming network is 0, make it ours
+ if( pnetwork_number == 0) {
+ sendpacket[6] = (unsigned char)(network_number >> 24);
+ sendpacket[7] = (unsigned char)((network_number &
+ 0x00FF0000) >> 16);
+ sendpacket[8] = (unsigned char)((network_number &
+ 0x0000FF00) >> 8);
+ sendpacket[9] = (unsigned char)(network_number &
+ 0x000000FF);
}
}
- pnetwork_number = (unsigned long) ((sendpacket[18] << 24) +
- (sendpacket[19] << 16) + (sendpacket[20] << 8) +
- sendpacket[21]);
- if (!incoming) {
- /* If the source network is ours, make it 0 */
- if (pnetwork_number == network_number) {
- sendpacket[18] = sendpacket[19] = sendpacket[20] =
- sendpacket[21] = 0x00;
+
+
+ pnetwork_number = (unsigned long)((sendpacket[18] << 24) +
+ (sendpacket[19] << 16) + (sendpacket[20] << 8) +
+ sendpacket[21]);
+
+ if( !incoming ) {
+ //If the source network is ours, make it 0
+ if( pnetwork_number == network_number) {
+ sendpacket[18] = sendpacket[19] = sendpacket[20] =
+ sendpacket[21] = 0x00;
}
} else {
- /* If the source network is 0, make it ours */
- if (pnetwork_number == 0) {
- sendpacket[18] = (unsigned char) (network_number >> 24);
- sendpacket[19] = (unsigned char) ((network_number &
- 0x00FF0000) >> 16);
- sendpacket[20] = (unsigned char) ((network_number &
- 0x0000FF00) >> 8);
- sendpacket[21] = (unsigned char) (network_number &
- 0x000000FF);
+ //If the source network is 0, make it ours
+ if( pnetwork_number == 0 ) {
+ sendpacket[18] = (unsigned char)(network_number >> 24);
+ sendpacket[19] = (unsigned char)((network_number &
+ 0x00FF0000) >> 16);
+ sendpacket[20] = (unsigned char)((network_number &
+ 0x0000FF00) >> 8);
+ sendpacket[21] = (unsigned char)(network_number &
+ 0x000000FF);
}
}
-} /* switch_net_numbers */
+} /* switch_net_numbers */
/*============================================================================
- * Get Ethernet-style interface statistics.
- * Return a pointer to struct enet_statistics.
+ * Get ethernet-style interface statistics.
+ * Return a pointer to struct net_device_stats.
*/
-
-static struct enet_statistics *if_stats(struct net_device *dev)
+static struct net_device_stats *if_stats(struct net_device *dev)
{
+
ppp_private_area_t *ppp_priv_area = dev->priv;
- sdla_t *card;
+ sdla_t* card;
- /*
- * Device is down:No statistics
- */
-
- if(ppp_priv_area==NULL)
+ if( ppp_priv_area == NULL )
return NULL;
-
+
card = ppp_priv_area->card;
return &card->wandev.stats;
}
@@ -868,122 +1168,257 @@ static struct enet_statistics *if_stats(struct net_device *dev)
* Read firmware code version.
* Put code version as ASCII string in str.
*/
-
-static int ppp_read_version(sdla_t * card, char *str)
+static int ppp_read_version(sdla_t *card, char *str)
{
ppp_mbox_t *mb = card->mbox;
int err;
+
memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
mb->cmd.command = PPP_READ_CODE_VERSION;
err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
+
if (err != CMD_OK)
+
ppp_error(card, err, mb);
+
else if (str) {
+
int len = mb->cmd.length;
+
memcpy(str, mb->data, len);
str[len] = '\0';
+
+ }
+
+ return err;
+}
+/*===========================================================================
+ * Set Out-Bound Authentication.
+*/
+static int ppp_set_outbnd_auth (sdla_t *card, ppp_private_area_t *ppp_priv_area)
+{
+ ppp_mbox_t *mb = card->mbox;
+ int err;
+
+ memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
+ memset(&mb->data, 0, (strlen(ppp_priv_area->userid) +
+ strlen(ppp_priv_area->passwd) + 2 ) );
+ memcpy(mb->data, ppp_priv_area->userid, strlen(ppp_priv_area->userid));
+ memcpy((mb->data + strlen(ppp_priv_area->userid) + 1),
+ ppp_priv_area->passwd, strlen(ppp_priv_area->passwd));
+
+ mb->cmd.length = strlen(ppp_priv_area->userid) +
+ strlen(ppp_priv_area->passwd) + 2 ;
+
+ mb->cmd.command = PPP_SET_OUTBOUND_AUTH;
+
+ err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
+
+ if (err != CMD_OK)
+ ppp_error(card, err, mb);
+
+ return err;
+}
+
+/*===========================================================================
+ * Set In-Bound Authentication.
+*/
+static int ppp_set_inbnd_auth (sdla_t *card, ppp_private_area_t *ppp_priv_area)
+{
+ ppp_mbox_t *mb = card->mbox;
+ int err, i;
+ char* user_tokens[32];
+ char* pass_tokens[32];
+ int userids, passwds;
+ int add_ptr;
+
+ memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
+ memset(&mb->data, 0, 1008);
+ memcpy(mb->data, ppp_priv_area->sysname,
+ strlen(ppp_priv_area->sysname));
+
+ /* Parse the userid string and the password string and build a string
+ to copy it to the data area of the command structure. The string
+ will look like "SYS_NAME<NULL>USER1<NULL>PASS1<NULL>USER2<NULL>PASS2
+ ....<NULL> "
+ */
+ userids = tokenize( ppp_priv_area->userid, user_tokens);
+ passwds = tokenize( ppp_priv_area->passwd, pass_tokens);
+
+ if (userids != passwds){
+ printk(KERN_INFO "%s: Number of passwords does not equal the number of user ids\n", card->devname);
+ return 1;
}
+
+ add_ptr = strlen(ppp_priv_area->sysname) + 1;
+ for (i=0; i<userids; i++){
+ memcpy((mb->data + add_ptr), user_tokens[i],
+ strlen(user_tokens[i]));
+ memcpy((mb->data + add_ptr + strlen(user_tokens[i]) + 1),
+ pass_tokens[i], strlen(pass_tokens[i]));
+ add_ptr = add_ptr + strlen(user_tokens[i]) + 1 +
+ strlen(pass_tokens[i]) + 1;
+ }
+
+ mb->cmd.length = add_ptr + 1;
+ mb->cmd.command = PPP_SET_INBOUND_AUTH;
+
+ err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
+
+ if (err != CMD_OK)
+ ppp_error(card, err, mb);
+
return err;
}
+
/*============================================================================
- * Configure PPP firmware.
+ * Tokenize string.
+ * Parse a string of the following syntax:
+ * <arg1>,<arg2>,...
+ * and fill array of tokens with pointers to string elements.
+ *
*/
+static int tokenize (char *str, char **tokens)
+{
+ int cnt = 0;
+
+ tokens[0] = strtok(str, "/");
+ while (tokens[cnt] && (cnt < 32 - 1))
+ {
+ tokens[cnt] = strstrip(tokens[cnt], " \t");
+ tokens[++cnt] = strtok(NULL, "/");
+ }
+ return cnt;
+}
-static int ppp_configure(sdla_t * card, void *data)
+/*============================================================================
+ * Strip leading and trailing spaces off the string str.
+ */
+static char* strstrip (char *str, char* s)
+{
+ char *eos = str + strlen(str); /* -> end of string */
+
+ while (*str && strchr(s, *str))
+ ++str /* strip leading spaces */
+ ;
+ while ((eos > str) && strchr(s, *(eos - 1)))
+ --eos /* strip trailing spaces */
+ ;
+ *eos = '\0';
+ return str;
+}
+/*============================================================================
+ * Configure PPP firmware.
+ */
+static int ppp_configure(sdla_t *card, void *data)
{
ppp_mbox_t *mb = card->mbox;
- int data_len = (card->hw.fwid == SFID_PPP502) ?
- sizeof(ppp502_conf_t) : sizeof(ppp508_conf_t);
+ int data_len = sizeof(ppp508_conf_t);
int err;
+
memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
memcpy(mb->data, data, data_len);
- mb->cmd.length = data_len;
+ mb->cmd.length = data_len;
mb->cmd.command = PPP_SET_CONFIG;
err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
- if (err != CMD_OK)
+
+ if (err != CMD_OK)
ppp_error(card, err, mb);
+
return err;
}
/*============================================================================
* Set interrupt mode.
*/
-
-static int ppp_set_intr_mode(sdla_t * card, unsigned mode)
+static int ppp_set_intr_mode(sdla_t *card, unsigned char mode)
{
ppp_mbox_t *mb = card->mbox;
+ ppp_intr_info_t *ppp_intr_data = (ppp_intr_info_t *) &mb->data[0];
int err;
+
memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
- mb->data[0] = mode;
- switch (card->hw.fwid) {
- case SFID_PPP502:
- mb->cmd.length = 1;
- break;
- case SFID_PPP508:
- default:
- mb->data[1] = card->hw.irq;
- mb->cmd.length = 2;
- }
+ ppp_intr_data->i_enable = mode;
+
+ ppp_intr_data->irq = card->hw.irq;
+ mb->cmd.length = 2;
+
+ /* If timer has been enabled, set the timer delay to 1sec */
+ if (mode & 0x80){
+ ppp_intr_data->timer_len = 5;//100; //250;
+ mb->cmd.length = 4;
+ }
+
mb->cmd.command = PPP_SET_INTR_FLAGS;
err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
- if (err != CMD_OK)
+
+ if (err != CMD_OK)
ppp_error(card, err, mb);
+
+
return err;
}
/*============================================================================
* Enable communications.
*/
-
-static int ppp_comm_enable(sdla_t * card)
+static int ppp_comm_enable(sdla_t *card)
{
ppp_mbox_t *mb = card->mbox;
int err;
+
memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
mb->cmd.command = PPP_COMM_ENABLE;
err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
- if (err != CMD_OK)
+
+ if (err != CMD_OK)
ppp_error(card, err, mb);
+
return err;
}
/*============================================================================
* Disable communications.
*/
-
-static int ppp_comm_disable(sdla_t * card)
+static int ppp_comm_disable(sdla_t *card)
{
ppp_mbox_t *mb = card->mbox;
int err;
+
memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
mb->cmd.command = PPP_COMM_DISABLE;
err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
- if (err != CMD_OK)
+ if (err != CMD_OK)
ppp_error(card, err, mb);
+
return err;
}
/*============================================================================
* Get communications error statistics.
*/
-
-static int ppp_get_err_stats(sdla_t * card)
+static int ppp_get_err_stats(sdla_t *card)
{
ppp_mbox_t *mb = card->mbox;
int err;
+
memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
mb->cmd.command = PPP_READ_ERROR_STATS;
err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
+
if (err == CMD_OK) {
- ppp_err_stats_t *stats = (void *) mb->data;
- card->wandev.stats.rx_over_errors = stats->rx_overrun;
- card->wandev.stats.rx_crc_errors = stats->rx_bad_crc;
- card->wandev.stats.rx_missed_errors = stats->rx_abort;
- card->wandev.stats.rx_length_errors = stats->rx_lost;
+
+ ppp_err_stats_t* stats = (void*)mb->data;
+ card->wandev.stats.rx_over_errors = stats->rx_overrun;
+ card->wandev.stats.rx_crc_errors = stats->rx_bad_crc;
+ card->wandev.stats.rx_missed_errors = stats->rx_abort;
+ card->wandev.stats.rx_length_errors = stats->rx_lost;
card->wandev.stats.tx_aborted_errors = stats->tx_abort;
- } else
+
+ } else
ppp_error(card, err, mb);
+
return err;
}
@@ -992,27 +1427,30 @@ static int ppp_get_err_stats(sdla_t * card)
* Return: 0 - o.k.
* 1 - no transmit buffers available
*/
-
-static int ppp_send(sdla_t * card, void *data, unsigned len, unsigned proto)
+static int ppp_send (sdla_t *card, void *data, unsigned len, unsigned proto)
{
ppp_buf_ctl_t *txbuf = card->u.p.txbuf;
- unsigned long addr;
+
if (txbuf->flag)
- return 1
- ;
- if (card->hw.fwid == SFID_PPP502)
- addr = (txbuf->buf.o_p[1] << 8) + txbuf->buf.o_p[0];
- else
- addr = txbuf->buf.ptr;
- sdla_poke(&card->hw, addr, data, len);
- txbuf->length = len; /* frame length */
- if (proto == ETH_P_IPX)
+ return 1;
+
+ sdla_poke(&card->hw, txbuf->buf.ptr, data, len);
+
+ txbuf->length = len; /* frame length */
+
+ if (proto == htons(ETH_P_IPX))
txbuf->proto = 0x01; /* protocol ID */
- txbuf->flag = 1; /* start transmission */
+ else
+ txbuf->proto = 0x00; /* protocol ID */
+
+ txbuf->flag = 1; /* start transmission */
+
/* Update transmit buffer control fields */
card->u.p.txbuf = ++txbuf;
- if ((void *) txbuf > card->u.p.txbuf_last)
+
+ if ((void*)txbuf > card->u.p.txbuf_last)
card->u.p.txbuf = card->u.p.txbuf_base;
+
return 0;
}
@@ -1025,19 +1463,22 @@ static int ppp_send(sdla_t * card, void *data, unsigned len, unsigned proto)
*
* Return zero if previous command has to be cancelled.
*/
-
-static int ppp_error(sdla_t * card, int err, ppp_mbox_t * mb)
+static int ppp_error(sdla_t *card, int err, ppp_mbox_t *mb)
{
unsigned cmd = mb->cmd.command;
+
switch (err) {
- case CMD_TIMEOUT:
- printk(KERN_ERR "%s: command 0x%02X timed out!\n",
- card->devname, cmd);
- break;
- default:
- printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n"
- ,card->devname, cmd, err);
+
+ case CMD_TIMEOUT:
+ printk(KERN_ERR "%s: command 0x%02X timed out!\n",
+ card->devname, cmd);
+ break;
+
+ default:
+ printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n"
+ , card->devname, cmd, err);
}
+
return 0;
}
@@ -1046,81 +1487,89 @@ static int ppp_error(sdla_t * card, int err, ppp_mbox_t * mb)
/*============================================================================
* PPP interrupt service routine.
*/
-
-STATIC void wpp_isr(sdla_t * card)
+STATIC void wpp_isr(sdla_t *card)
{
ppp_flags_t *flags = card->flags;
char *ptr = &flags->iflag;
- unsigned long host_cpu_flags;
struct net_device *dev = card->wandev.dev;
+
+
int i;
+
card->in_isr = 1;
+
++card->statistics.isr_entry;
- if (test_and_set_bit(0, (void *) &card->wandev.critical)) {
- ++card->statistics.isr_already_critical;
- printk(KERN_INFO "%s: Critical while in ISR!\n", card->devname);
- card->in_isr = 0;
- return;
+
+ //FIXME: Do we need this
+ card->force_enable_irq = 0;
+
+ if(card->hw.type != SDLA_S514){
+ if (test_and_set_bit(0, (void*)&card->wandev.critical)) {
+
+ ++card->statistics.isr_already_critical;
+ printk (KERN_INFO "%s: Critical while in ISR!\n",
+ card->devname);
+ card->in_isr = 0;
+ return;
+
+ }
}
- /* For all interrupts set the critical flag to CRITICAL_IN_ISR.
- * If the if_send routine is called with this flag set it will set
- * the enable transmit flag to 1. (for a delayed interrupt)
- */
- card->wandev.critical = CRITICAL_IN_ISR;
+
card->buff_int_mode_unbusy = 0;
+
switch (flags->iflag) {
- case 0x01: /* receive interrupt */
- ++card->statistics.isr_rx;
- rx_intr(card);
- break;
- case 0x02: /* transmit interrupt */
- ++card->statistics.isr_tx;
- flags->imask &= ~0x02;
- dev->tbusy = 0;
- card->buff_int_mode_unbusy = 1;
- break;
- case 0x08:
- ++Intr_test_counter;
- ++card->statistics.isr_intr_test;
- break;
- default: /* unexpected interrupt */
- ++card->statistics.isr_spurious;
- printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n",
- card->devname, flags->iflag);
- printk(KERN_INFO "%s: ID Bytes = ", card->devname);
- for (i = 0; i < 8; i++)
- printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));
- printk(KERN_INFO "\n");
- }
- /* The critical flag is set to CRITICAL_INTR_HANDLED to let the
- * if_send call know that the interrupt is handled so that
- * transmit interrupts are not enabled again.
- */
- card->wandev.critical = CRITICAL_INTR_HANDLED;
- /* If the enable transmit interrupt flag is set then enable transmit
- * interrupt on the board. This only goes through if if_send is called
- * and the critical flag is set due to an Interrupt.
- */
- if (card->wandev.enable_tx_int) {
- flags->imask |= 0x02;
- card->wandev.enable_tx_int = 0;
- ++card->statistics.isr_enable_tx_int;
+
+ case PPP_INTR_RXRDY: /* receive interrupt 0x01 (bit 0)*/
+ ++card->statistics.isr_rx;
+ rx_intr(card);
+ break;
+
+ case PPP_INTR_TXRDY: /* transmit interrupt 0x02 (bit 1)*/
+ ++card->statistics.isr_tx;
+ flags->imask &= ~PPP_INTR_TXRDY;
+ dev->tbusy = 0;
+ card->buff_int_mode_unbusy = 1;
+ break;
+
+ case PPP_INTR_CMD: /* interface command completed */
+ ++Intr_test_counter;
+ ++card->statistics.isr_intr_test;
+ break;
+
+ case PPP_INTR_MODEM: /* modem status change (DCD, CTS) 0x04 (bit 2)*/
+ case PPP_INTR_DISC: /* Data link disconnected 0x10 (bit 4)*/
+ case PPP_INTR_OPEN: /* Data link open 0x20 (bit 5)*/
+ case PPP_INTR_DROP_DTR: /* DTR drop timeout expired 0x40 bit 6 */
+ event_intr(card);
+ break;
+
+ case PPP_INTR_TIMER:
+ timer_intr(card);
+ break;
+
+ default: /* unexpected interrupt */
+ ++card->statistics.isr_spurious;
+ printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n",
+ card->devname, flags->iflag);
+ printk(KERN_INFO "%s: ID Bytes = ",card->devname);
+ for(i = 0; i < 8; i ++)
+ printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));
+ printk(KERN_INFO "\n");
}
- save_flags(host_cpu_flags);
- cli();
+
card->in_isr = 0;
flags->iflag = 0;
card->wandev.critical = 0;
- restore_flags(host_cpu_flags);
- if (card->buff_int_mode_unbusy)
+
+ if(card->buff_int_mode_unbusy) {
mark_bh(NET_BH);
+ }
}
/*============================================================================
* Receive interrupt handler.
*/
-
-static void rx_intr(sdla_t * card)
+static void rx_intr(sdla_t *card)
{
ppp_buf_ctl_t *rxbuf = card->rxmb;
struct net_device *dev = card->wandev.dev;
@@ -1128,160 +1577,338 @@ static void rx_intr(sdla_t * card)
struct sk_buff *skb;
unsigned len;
void *buf;
- int i, err;
- ppp_flags_t *flags = card->flags;
- char *ptr = &flags->iflag;
+ int i;
+ ppp_flags_t *flags = card->flags;
+ char *ptr = &flags->iflag;
int udp_type;
+
+
if (rxbuf->flag != 0x01) {
- printk(KERN_INFO
- "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n",
- card->devname, (unsigned) rxbuf, rxbuf->flag);
- printk(KERN_INFO "%s: ID Bytes = ", card->devname);
- for (i = 0; i < 8; i++)
+
+ printk(KERN_INFO
+ "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n",
+ card->devname, (unsigned)rxbuf, rxbuf->flag);
+
+ printk(KERN_INFO "%s: ID Bytes = ",card->devname);
+
+ for(i = 0; i < 8; i ++)
printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));
- printk(KERN_INFO "\n");
+ printk(KERN_INFO "\n");
+
++card->statistics.rx_intr_corrupt_rx_bfr;
return;
+
}
+
if (dev && dev->start) {
- len = rxbuf->length;
+
+ len = rxbuf->length;
ppp_priv_area = dev->priv;
+
/* Allocate socket buffer */
skb = dev_alloc_skb(len);
+
if (skb != NULL) {
+
/* Copy data to the socket buffer */
- if (card->hw.fwid == SFID_PPP502) {
- unsigned addr = (rxbuf->buf.o_p[1] << 8) +
- rxbuf->buf.o_p[0];
- buf = skb_put(skb, len);
- sdla_peek(&card->hw, addr, buf, len);
- } else {
- unsigned addr = rxbuf->buf.ptr;
- if ((addr + len) > card->u.p.rx_top + 1) {
- unsigned tmp = card->u.p.rx_top - addr
- + 1;
- buf = skb_put(skb, tmp);
- sdla_peek(&card->hw, addr, buf, tmp);
- addr = card->u.p.rx_base;
- len -= tmp;
- }
- buf = skb_put(skb, len);
- sdla_peek(&card->hw, addr, buf, len);
+ unsigned addr = rxbuf->buf.ptr;
+
+ if ((addr + len) > card->u.p.rx_top + 1) {
+
+ unsigned tmp = card->u.p.rx_top - addr + 1;
+ buf = skb_put(skb, tmp);
+ sdla_peek(&card->hw, addr, buf, tmp);
+ addr = card->u.p.rx_base;
+ len -= tmp;
}
+ buf = skb_put(skb, len);
+ sdla_peek(&card->hw, addr, buf, len);
+
/* Decapsulate packet */
- switch (rxbuf->proto) {
- case 0x00:
- skb->protocol = htons(ETH_P_IP);
- break;
- case 0x01:
- skb->protocol = htons(ETH_P_IPX);
- break;
+ switch (rxbuf->proto) {
+
+ case 0x00:
+ skb->protocol = htons(ETH_P_IP);
+ break;
+
+ case 0x01:
+ skb->protocol = htons(ETH_P_IPX);
+ break;
}
- udp_type = udp_pkt_type(skb, card);
- if (udp_type == UDP_DRVSTATS_TYPE) {
- ++ppp_priv_area->rx_intr_DRVSTATS_request;
- process_udp_driver_call(
- UDP_PKT_FRM_NETWORK, card, skb,
- dev, ppp_priv_area);
- dev_kfree_skb(skb);
- } else if (udp_type == UDP_PTPIPE_TYPE) {
- ++ppp_priv_area->rx_intr_PTPIPE_request;
- err = process_udp_mgmt_pkt(
- UDP_PKT_FRM_NETWORK, card,
- skb, dev, ppp_priv_area);
- dev_kfree_skb(skb);
- } else if (handle_IPXWAN(skb->data, card->devname, card->wandev.enable_IPX, card->wandev.network_number, skb->protocol)) {
- if (card->wandev.enable_IPX) {
- ppp_send(card, skb->data, skb->len, ETH_P_IPX);
- dev_kfree_skb(skb);
+
+ udp_type = udp_pkt_type( skb, card );
+
+ if (udp_type == UDP_PTPIPE_TYPE){
+
+ /* Handle a UDP Request in Timer Interrupt */
+ if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK, card, skb, dev,
+ ppp_priv_area)){
+ flags->imask |= PPP_INTR_TIMER;
+ }
+ ++ppp_priv_area->rx_intr_stat.rx_intr_PIPE_request;
+
+
+ } else if (handle_IPXWAN(skb->data,card->devname,
+ ppp_priv_area->enable_IPX,
+ ppp_priv_area->network_number,
+ skb->protocol)) {
+
+ /* Handle an IPXWAN packet */
+ if( ppp_priv_area->enable_IPX) {
+ ppp_send(card, skb->data, skb->len, htons(ETH_P_IPX));
+ dev_kfree_skb(skb);
+
+
} else {
++card->wandev.stats.rx_dropped;
}
} else {
- /* Pass it up the protocol stack */
- skb->dev = dev;
- skb->mac.raw = skb->data;
+ /* Pass data up the protocol stack */
+ skb->dev = dev;
+ skb->mac.raw = skb->data;
+
+ ++card->wandev.stats.rx_packets;
+ card->wandev.stats.rx_bytes += skb->len;
+ ++ppp_priv_area->rx_intr_stat.rx_intr_bfr_passed_to_stack;
netif_rx(skb);
- ++card->wandev.stats.rx_packets;
- card->wandev.stats.rx_bytes += skb->len;
- ++ppp_priv_area->rx_intr_bfr_passed_to_stack;
}
+
} else {
+
printk(KERN_INFO "%s: no socket buffers available!\n",
- card->devname);
+ card->devname);
++card->wandev.stats.rx_dropped;
- ++ppp_priv_area->rx_intr_no_socket;
+ ++ppp_priv_area->rx_intr_stat.rx_intr_no_socket;
+
+ dev_kfree_skb(skb);
}
- } else
+
+ } else {
++card->statistics.rx_intr_dev_not_started;
+ }
+
/* Release buffer element and calculate a pointer to the next one */
- rxbuf->flag = (card->hw.fwid == SFID_PPP502) ? 0xFF : 0x00;
+ rxbuf->flag = 0x00;
card->rxmb = ++rxbuf;
- if ((void *) rxbuf > card->u.p.rxbuf_last)
+ if ((void*)rxbuf > card->u.p.rxbuf_last)
card->rxmb = card->u.p.rxbuf_base;
}
-/*============================================================================
- * Transmit interrupt handler.
- */
-static void tx_intr(sdla_t * card)
+void event_intr (sdla_t *card)
{
- struct net_device *dev = card->wandev.dev;
- if (!dev || !dev->start) {
- ++card->statistics.tx_intr_dev_not_started;
- return;
+
+ struct net_device* dev = card->wandev.dev;
+ ppp_private_area_t* ppp_priv_area = dev->priv;
+ volatile ppp_flags_t *flags = card->flags;
+
+ switch (flags->iflag){
+
+ case PPP_INTR_MODEM: /* modem status change (DCD, CTS) 0x04 (bit 2)*/
+ printk (KERN_INFO "%s: Modem status: DCD=%s CTS=%s\n",
+ card->devname, DCD(flags->mstatus), CTS(flags->mstatus));
+
+ break;
+
+ case PPP_INTR_DISC: /* Data link disconnected 0x10 (bit 4)*/
+
+ NEX_PRINTK (KERN_INFO "Data link disconnected intr Cause %X\n",
+ flags->disc_cause);
+
+ if (flags->disc_cause &
+ (PPP_LOCAL_TERMINATION | PPP_DCD_CTS_DROP |
+ PPP_REMOTE_TERMINATION)) {
+ if (card->u.p.ip_mode == WANOPT_PPP_PEER) {
+ Read_connection_info = 1;
+ remove_route (card);
+ }
+ wanpipe_set_state(card, WAN_DISCONNECTED);
+ show_disc_cause(card, flags->disc_cause);
+ ppp_priv_area->timer_int_enabled |=
+ TMR_INT_ENABLED_PPP_EVENT;
+ flags->imask |= PPP_INTR_TIMER;
+ }
+ break;
+
+ case PPP_INTR_OPEN: /* Data link open 0x20 (bit 5)*/
+
+ NEX_PRINTK (KERN_INFO "%s: PPP Link Open, LCP=%s IP=%s\n",
+ card->devname,LCP(flags->lcp_state),
+ IP(flags->ip_state));
+
+ if (flags->lcp_state == 0x09 &&
+ (flags->ip_state == 0x09 || flags->ipx_state == 0x09)){
+ /* Initialize the polling timer and set the state
+ * to WAN_CONNNECTED
+ */
+ card->state_tick = jiffies;
+ wanpipe_set_state(card, WAN_CONNECTED);
+ ppp_priv_area->timer_int_enabled |=
+ TMR_INT_ENABLED_PPP_EVENT;
+ flags->imask |= PPP_INTR_TIMER;
+
+ }
+ break;
+
+ case PPP_INTR_DROP_DTR: /* DTR drop timeout expired 0x40 bit 6 */
+
+ NEX_PRINTK(KERN_INFO "DTR Drop Timeout Interrrupt \n");
+ if (card->u.p.ip_mode == WANOPT_PPP_PEER) {
+ Read_connection_info = 1;
+ remove_route (card);
+ }
+ wanpipe_set_state(card, WAN_DISCONNECTED);
+ show_disc_cause(card, flags->disc_cause);
+ ppp_priv_area->timer_int_enabled |=
+ TMR_INT_ENABLED_PPP_EVENT;
+ flags->imask |= PPP_INTR_TIMER;
+ break;
+
+ default:
+ printk(KERN_INFO "%s: Error, Invalid PPP Event\n",card->devname);
}
- dev->tbusy = 0;
- mark_bh(NET_BH);
}
+
+
+/* TIMER INTERRUPT */
+
+void timer_intr (sdla_t *card)
+{
+
+ struct net_device* dev = card->wandev.dev;
+ ppp_private_area_t* ppp_priv_area = dev->priv;
+ ppp_flags_t *flags = card->flags;
+
+ /* Update statistics */
+ if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE){
+ ppp_get_err_stats(card);
+ if(!(--ppp_priv_area->update_comms_stats)){
+ ppp_priv_area->timer_int_enabled &=
+ ~TMR_INT_ENABLED_UPDATE;
+ }
+ }
+
+ /* PPIPEMON UDP request */
+
+ if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP){
+ process_udp_mgmt_pkt(card,dev, ppp_priv_area);
+ ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP;
+ }
+
+
+ /* PPP Event */
+ if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_PPP_EVENT){
+
+ if (card->wandev.state == WAN_DISCONNECTED){
+ poll_disconnected(card);
+ }
+
+ /* If the state is CONNECTING, it means that communicatins were
+ * enabled. When the remote side enables its comminication we
+ * should get an interrupt PPP_INTR_OPEN, thus turn off polling
+ */
+
+ else if (card->wandev.state == WAN_CONNECTING){
+ /* Turn off the timer interrupt */
+ ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_PPP_EVENT;
+ }
+
+ /* If state is connected and we are in PEER mode
+ * poll for an IP address which will be provided by remote end.
+ */
+ else if ((card->wandev.state == WAN_CONNECTED &&
+ card->u.p.ip_mode == WANOPT_PPP_PEER) &&
+ Read_connection_info){
+
+ card->state_tick = jiffies;
+ if (!read_connection_info (card)){
+ card->poll = &process_route;
+ }
+
+ }else{
+ /* If we are using Static IP,no need to poll for
+ * an IP address.
+ */
+ NEX_PRINTK(KERN_INFO "Turning off TIMER \n");
+ ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_PPP_EVENT;
+ }
+
+ }/* End of PPP_EVENT */
+
+
+ /* Only disable the timer interrupt if there are no udp, statistic */
+ /* updates or events pending */
+ if(!ppp_priv_area->timer_int_enabled) {
+ flags->imask &= ~PPP_INTR_TIMER;
+ }
+}
+
+
static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number, unsigned short proto)
{
int i;
- if (proto == htons(ETH_P_IPX)) {
- /* It's an IPX packet */
- if (!enable_IPX) {
- /* Return 1 so we don't pass it up the stack. */
+
+ if( proto == htons(ETH_P_IPX) ) {
+ //It's an IPX packet
+ if(!enable_IPX) {
+ //Return 1 so we don't pass it up the stack.
return 1;
}
} else {
- /* It's not IPX so pass it up the stack. */
+ //It's not IPX so pass it up the stack.
return 0;
}
- if (sendpacket[16] == 0x90 &&
- sendpacket[17] == 0x04) {
- /* It's IPXWAN */
- if (sendpacket[2] == 0x02 &&
- sendpacket[34] == 0x00) {
- /* It's a timer request packet */
- printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n", devname);
- /* Go through the routing options and answer no to every */
- /* option except Unnumbered RIP/SAP */
- for (i = 41; sendpacket[i] == 0x00; i += 5) {
- /* 0x02 is the option for Unnumbered RIP/SAP */
- if (sendpacket[i + 4] != 0x02) {
+
+ if( sendpacket[16] == 0x90 &&
+ sendpacket[17] == 0x04)
+ {
+ //It's IPXWAN
+
+ if( sendpacket[2] == 0x02 &&
+ sendpacket[34] == 0x00)
+ {
+ //It's a timer request packet
+ printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n",devname);
+
+ //Go through the routing options and answer no to every
+ //option except Unnumbered RIP/SAP
+ for(i = 41; sendpacket[i] == 0x00; i += 5)
+ {
+ //0x02 is the option for Unnumbered RIP/SAP
+ if( sendpacket[i + 4] != 0x02)
+ {
sendpacket[i + 1] = 0;
}
}
- /* Skip over the extended Node ID option */
- if (sendpacket[i] == 0x04) {
+
+ //Skip over the extended Node ID option
+ if( sendpacket[i] == 0x04 )
+ {
i += 8;
}
- /* We also want to turn off all header compression opt. */
- for (; sendpacket[i] == 0x80;) {
+
+ //We also want to turn off all header compression opt.
+ for(; sendpacket[i] == 0x80 ;)
+ {
sendpacket[i + 1] = 0;
i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4;
}
- /* Set the packet type to timer response */
+
+ //Set the packet type to timer response
sendpacket[34] = 0x01;
- printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n", devname);
- } else if (sendpacket[34] == 0x02) {
- /* This is an information request packet */
- printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n", devname);
- /* Set the packet type to information response */
+
+ printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n",devname);
+ }
+ else if( sendpacket[34] == 0x02 )
+ {
+ //This is an information request packet
+ printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n",devname);
+
+ //Set the packet type to information response
sendpacket[34] = 0x03;
- /* Set the router name */
+
+ //Set the router name
sendpacket[51] = 'P';
sendpacket[52] = 'T';
sendpacket[53] = 'P';
@@ -1290,136 +1917,81 @@ static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char
sendpacket[56] = 'E';
sendpacket[57] = '-';
sendpacket[58] = CVHexToAscii(network_number >> 28);
- sendpacket[59] = CVHexToAscii((network_number & 0x0F000000) >> 24);
- sendpacket[60] = CVHexToAscii((network_number & 0x00F00000) >> 20);
- sendpacket[61] = CVHexToAscii((network_number & 0x000F0000) >> 16);
- sendpacket[62] = CVHexToAscii((network_number & 0x0000F000) >> 12);
- sendpacket[63] = CVHexToAscii((network_number & 0x00000F00) >> 8);
- sendpacket[64] = CVHexToAscii((network_number & 0x000000F0) >> 4);
+ sendpacket[59] = CVHexToAscii((network_number & 0x0F000000)>> 24);
+ sendpacket[60] = CVHexToAscii((network_number & 0x00F00000)>> 20);
+ sendpacket[61] = CVHexToAscii((network_number & 0x000F0000)>> 16);
+ sendpacket[62] = CVHexToAscii((network_number & 0x0000F000)>> 12);
+ sendpacket[63] = CVHexToAscii((network_number & 0x00000F00)>> 8);
+ sendpacket[64] = CVHexToAscii((network_number & 0x000000F0)>> 4);
sendpacket[65] = CVHexToAscii(network_number & 0x0000000F);
- for (i = 66; i < 99; i += 1)
+ for(i = 66; i < 99; i+= 1)
+ {
sendpacket[i] = 0;
- printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n", devname);
- } else {
- printk(KERN_INFO "%s: Unknown IPXWAN packet!\n", devname);
+ }
+
+ printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n",devname);
+ }
+ else
+ {
+ printk(KERN_INFO "%s: Unknown IPXWAN packet!\n",devname);
return 0;
}
- /* Set the WNodeID to our network address */
- sendpacket[35] = (unsigned char) (network_number >> 24);
- sendpacket[36] = (unsigned char) ((network_number & 0x00FF0000) >> 16);
- sendpacket[37] = (unsigned char) ((network_number & 0x0000FF00) >> 8);
- sendpacket[38] = (unsigned char) (network_number & 0x000000FF);
+
+ //Set the WNodeID to our network address
+ sendpacket[35] = (unsigned char)(network_number >> 24);
+ sendpacket[36] = (unsigned char)((network_number & 0x00FF0000) >> 16);
+ sendpacket[37] = (unsigned char)((network_number & 0x0000FF00) >> 8);
+ sendpacket[38] = (unsigned char)(network_number & 0x000000FF);
+
return 1;
} else {
- /* If we get here's its an IPX-data packet, so it'll get passed up the stack. */
- /* switch the network numbers */
- switch_net_numbers(sendpacket, network_number, 1);
+ //If we get here's its an IPX-data packet, so it'll get passed up the stack.
+
+ //switch the network numbers
+ switch_net_numbers(sendpacket, network_number, 1);
return 0;
}
}
/****** Background Polling Routines ****************************************/
-/*============================================================================
- * Main polling routine.
- * This routine is repeatedly called by the WANPIPE 'thread' to allow for
- * time-dependent housekeeping work.
- *
- * Notes:
- * 1. This routine may be called on interrupt context with all interrupts
- * enabled. Beware!
+/* All polling functions are invoked by the TIMER interrupt in the wpp_isr
+ * routine.
*/
-static void wpp_poll(sdla_t * card)
-{
- struct net_device *dev = card->wandev.dev;
- ppp_flags_t *adptr_flags = card->flags;
- unsigned long host_cpu_flags;
- ++card->statistics.poll_entry;
- /* The wpp_poll is called continously by the WANPIPE thread to allow
- * for line state housekeeping. However if we are in a connected state
- * then we do not need to go through all the checks everytime. When in
- * connected state execute wpp_poll once every second.
- */
- if (card->wandev.state == WAN_CONNECTED) {
- if ((jiffies - card->state_tick) < HZ)
- return;
- }
- disable_irq(card->hw.irq);
- ++card->irq_dis_poll_count;
- if (test_and_set_bit(0, (void *) &card->wandev.critical)) {
- ++card->statistics.poll_already_critical;
- printk(KERN_INFO "%s: critical inside wpp_poll\n",
- card->devname);
- save_flags(host_cpu_flags);
- cli();
- if ((!card->irq_dis_if_send_count) &&
- (!(--card->irq_dis_poll_count)))
- enable_irq(card->hw.irq);
- restore_flags(host_cpu_flags);
- return;
- }
- ++card->statistics.poll_processed;
- if (dev && dev->tbusy && !(adptr_flags->imask & 0x02)) {
- ++card->statistics.poll_tbusy_bad_status;
- printk(KERN_INFO "%s: Wpp_Poll: tbusy = 0x01, imask = 0x%02X\n"
- ,card->devname, adptr_flags->imask);
- }
- switch (card->wandev.state) {
- case WAN_CONNECTED:
- card->state_tick = jiffies;
- poll_active(card);
- break;
- case WAN_CONNECTING:
- poll_connecting(card);
- break;
- case WAN_DISCONNECTED:
- poll_disconnected(card);
- break;
- default:
- printk(KERN_INFO "%s: Unknown Poll State 0x%02X\n",
- card->devname, card->wandev.state);
- break;
- }
- card->wandev.critical = 0;
- save_flags(host_cpu_flags);
- cli();
- if ((!card->irq_dis_if_send_count) && (!(--card->irq_dis_poll_count)))
- enable_irq(card->hw.irq);
- restore_flags(host_cpu_flags);
-}
-
/*============================================================================
* Monitor active link phase.
*/
-
-static void poll_active(sdla_t * card)
+static void process_route (sdla_t *card)
{
ppp_flags_t *flags = card->flags;
- /* We check the lcp_state to see if we are in DISCONNECTED state.
- * We are considered to be connected for lcp states 0x06, 0x07, 0x08
- * and 0x09.
- */
- if ((flags->lcp_state <= 0x05) || (flags->disc_cause & 0x03)) {
- wanpipe_set_state(card, WAN_DISCONNECTED);
- show_disc_cause(card, flags->disc_cause);
+ struct net_device *dev = card->wandev.dev;
+ struct in_device *in_dev = dev->ip_ptr;
+
+ if (in_dev != NULL ) {
+ if ((card->u.p.ip_mode == WANOPT_PPP_PEER) &&
+ (Read_connection_info && flags->ip_state == 0x09)){
+
+ printk(KERN_INFO "%s: IPCP State Opened.\n", card->devname);
+ if (read_info( card )) {
+ printk(KERN_INFO
+ "%s: An error occurred in IP assignment.\n",
+ card->devname);
+ } else {
+ struct in_ifaddr *ifa = in_dev->ifa_list;
+ printk(KERN_INFO "%s: Assigned Lcl. Addr: %s\n",
+ card->devname, in_ntoa(ifa->ifa_local));
+ printk(KERN_INFO "%s: Assigned Rmt. Addr: %s\n",
+ card->devname, in_ntoa(ifa->ifa_address));
+ }
+ Read_connection_info = 0;
+ }
+ }else{
+ printk(KERN_INFO "%s: Error: Null pointer in Poll Active\n",
+ card->devname);
}
-}
-
-/*============================================================================
- * Monitor link establishment phase.
- * o if connection timed out, disconnect the link.
- */
+ card->poll = NULL;
-static void poll_connecting(sdla_t * card)
-{
- ppp_flags_t *flags = card->flags;
- if (flags->lcp_state == 0x09) {
- wanpipe_set_state(card, WAN_CONNECTED);
- } else if (flags->disc_cause & 0x03) {
- wanpipe_set_state(card, WAN_DISCONNECTED);
- show_disc_cause(card, flags->disc_cause);
- }
}
/*============================================================================
@@ -1427,794 +1999,796 @@ static void poll_connecting(sdla_t * card)
* o if interface is up and the hold-down timeout has expired, then retry
* connection.
*/
-
-static void poll_disconnected(sdla_t * card)
+static void poll_disconnected(sdla_t *card)
{
struct net_device *dev = card->wandev.dev;
+
if (dev && dev->start &&
((jiffies - card->state_tick) > HOLD_DOWN_TIME)) {
+
wanpipe_set_state(card, WAN_CONNECTING);
- if (ppp_comm_enable(card) == CMD_OK)
- init_ppp_tx_rx_buff(card);
+
+ if(ppp_comm_enable(card) == CMD_OK){
+ init_ppp_tx_rx_buff( card );
+ }
+
}
}
/****** Miscellaneous Functions *********************************************/
/*============================================================================
- * Configure S502 adapter.
- */
-
-static int config502(sdla_t * card)
-{
- ppp502_conf_t cfg;
- /* Prepare PPP configuration structure */
- memset(&cfg, 0, sizeof(ppp502_conf_t));
- if (card->wandev.clocking)
- cfg.line_speed = bps_to_speed_code(card->wandev.bps);
- cfg.txbuf_num = 4;
- cfg.mtu_local = card->wandev.mtu;
- cfg.mtu_remote = card->wandev.mtu;
- cfg.restart_tmr = 30;
- cfg.auth_rsrt_tmr = 30;
- cfg.auth_wait_tmr = 300;
- cfg.mdm_fail_tmr = 5;
- cfg.dtr_drop_tmr = 1;
- cfg.connect_tmout = 0; /* changed it from 900 */
- cfg.conf_retry = 10;
- cfg.term_retry = 2;
- cfg.fail_retry = 5;
- cfg.auth_retry = 10;
- cfg.ip_options = 0x80;
- cfg.ipx_options = 0xA0;
- cfg.conf_flags |= 0x0E;
-/*
- cfg.ip_local = dev->pa_addr;
- cfg.ip_remote = dev->pa_dstaddr;
- */
- return ppp_configure(card, &cfg);
-}
-
-/*============================================================================
* Configure S508 adapter.
*/
-
-static int config508(sdla_t * card)
+static int config508(ppp_private_area_t *ppp_priv_area, sdla_t *card)
{
ppp508_conf_t cfg;
+ struct net_device *dev = card->wandev.dev;
+ struct in_device *in_dev = dev->ip_ptr;
+
/* Prepare PPP configuration structure */
memset(&cfg, 0, sizeof(ppp508_conf_t));
+
if (card->wandev.clocking)
cfg.line_speed = card->wandev.bps;
+
if (card->wandev.interface == WANOPT_RS232)
- cfg.conf_flags |= 0x0020;
- cfg.conf_flags |= 0x300; /*send Configure-Request packets forever */
- cfg.txbuf_percent = 60; /* % of Tx bufs */
- cfg.mtu_local = card->wandev.mtu;
- cfg.mtu_remote = card->wandev.mtu;
- cfg.restart_tmr = 30;
- cfg.auth_rsrt_tmr = 30;
- cfg.auth_wait_tmr = 300;
- cfg.mdm_fail_tmr = 100;
- cfg.dtr_drop_tmr = 1;
- cfg.connect_tmout = 0; /* changed it from 900 */
- cfg.conf_retry = 10;
- cfg.term_retry = 2;
- cfg.fail_retry = 5;
- cfg.auth_retry = 10;
- cfg.ip_options = 0x80;
- cfg.ipx_options = 0xA0;
-/*
- cfg.ip_local = dev->pa_addr;
- cfg.ip_remote = dev->pa_dstaddr;
- */
+ cfg.conf_flags |= INTERFACE_LEVEL_RS232;
+
+ cfg.conf_flags |= DONT_TERMINATE_LNK_MAX_CONFIG; /*send Configure-Request packets forever*/
+ cfg.txbuf_percent = PERCENT_TX_BUFF; /* % of Tx bufs */
+ cfg.mtu_local = card->wandev.mtu;
+ cfg.mtu_remote = card->wandev.mtu; /* Default */
+ cfg.restart_tmr = TIME_BETWEEN_CONF_REQ; /* 30 = 3sec */
+ cfg.auth_rsrt_tmr = TIME_BETWEEN_PAP_CHAP_REQ; /* 30 = 3sec */
+ cfg.auth_wait_tmr = WAIT_PAP_CHAP_WITHOUT_REPLY; /* 300 = 30s */
+ cfg.mdm_fail_tmr = WAIT_AFTER_DCD_CTS_LOW; /* 5 = 0.5s */
+ cfg.dtr_drop_tmr = TIME_DCD_CTS_LOW_AFTER_LNK_DOWN; /* 10 = 1s */
+ cfg.connect_tmout = WAIT_DCD_HIGH_AFTER_ENABLE_COMM; /* 900 = 90s */
+ cfg.conf_retry = MAX_CONF_REQ_WITHOUT_REPLY; /* 10 = 1s */
+ cfg.term_retry = MAX_TERM_REQ_WITHOUT_REPLY; /* 2 times */
+ cfg.fail_retry = NUM_CONF_NAK_WITHOUT_REPLY; /* 5 times */
+ cfg.auth_retry = NUM_AUTH_REQ_WITHOUT_REPLY; /* 10 times */
+
+
+ if( !card->u.p.authenticator ) {
+ printk(KERN_INFO "%s: Device is not configured as an authenticator\n",
+ card->devname);
+ cfg.auth_options = NO_AUTHENTICATION;
+ }else{
+ printk(KERN_INFO "%s: Device is configured as an authenticator\n",
+ card->devname);
+ cfg.auth_options = INBOUND_AUTH;
+ }
+ if( ppp_priv_area->pap == WANOPT_YES){
+ cfg.auth_options |=PAP_AUTH;
+ printk(KERN_INFO "%s: Pap enabled\n", card->devname);
+ }
+ if( ppp_priv_area->chap == WANOPT_YES){
+ cfg.auth_options |= CHAP_AUTH;
+ printk(KERN_INFO "%s: Chap enabled\n", card->devname);
+ }
+
+
+ if (ppp_priv_area->enable_IPX == WANOPT_YES){
+ cfg.ipx_options = ENABLE_IPX | ROUTING_PROT_DEFAULT;
+ }else{
+ cfg.ipx_options = DISABLE_IPX;
+ }
+
+ switch (card->u.p.ip_mode) {
+
+ case WANOPT_PPP_STATIC:
+
+ cfg.ip_options = L_AND_R_IP_NO_ASSIG |
+ ENABLE_IP;
+ cfg.ip_local = in_dev->ifa_list->ifa_local;
+ cfg.ip_remote = in_dev->ifa_list->ifa_address;
+ NEX_PRINTK(KERN_INFO "Local %s Remote %s Name %s\n",
+ in_ntoa(cfg.ip_local),
+ in_ntoa(cfg.ip_remote),
+ dev->name);
+ break;
+
+ case WANOPT_PPP_PEER:
+ cfg.ip_options = L_IP_REMOTE_ASSIG |
+ R_IP_REMOTE_ASSIG |
+ ENABLE_IP;
+ cfg.ip_local = 0x00;
+ cfg.ip_remote = 0x00;
+ break;
+
+ }
return ppp_configure(card, &cfg);
}
/*============================================================================
* Show disconnection cause.
*/
-
-static void show_disc_cause(sdla_t * card, unsigned cause)
+static void show_disc_cause(sdla_t *card, unsigned cause)
{
- if (cause & 0x0002)
- printk(KERN_INFO "%s: link terminated by peer\n",
- card->devname);
- else if (cause & 0x0004)
- printk(KERN_INFO "%s: link terminated by user\n",
- card->devname);
- else if (cause & 0x0008)
+ if (cause & 0x0802)
+
+ printk(KERN_INFO "%s: link terminated by peer\n",
+ card->devname);
+
+ else if (cause & 0x0004)
+
+ printk(KERN_INFO "%s: link terminated by user\n",
+ card->devname);
+
+ else if (cause & 0x0008)
+
printk(KERN_INFO "%s: authentication failed\n", card->devname);
- else if (cause & 0x0010)
- printk(KERN_INFO
- "%s: authentication protocol negotiation failed\n",
- card->devname);
- else if (cause & 0x0020)
- printk(KERN_INFO
- "%s: peer's request for authentication rejected\n",
- card->devname);
- else if (cause & 0x0040)
- printk(KERN_INFO "%s: MRU option rejected by peer\n",
- card->devname);
- else if (cause & 0x0080)
- printk(KERN_INFO "%s: peer's MRU was too small\n",
- card->devname);
- else if (cause & 0x0100)
- printk(KERN_INFO "%s: failed to negotiate peer's LCP options\n",
- card->devname);
- else if (cause & 0x0200)
- printk(KERN_INFO "%s: failed to negotiate peer's IPCP options\n"
- ,card->devname);
- else if (cause & 0x0400)
+
+ else if (cause & 0x0010)
+
+ printk(KERN_INFO
+ "%s: authentication protocol negotiation failed\n",
+ card->devname);
+
+ else if (cause & 0x0020)
+
printk(KERN_INFO
- "%s: failed to negotiate peer's IPXCP options\n",
- card->devname);
-}
+ "%s: peer's request for authentication rejected\n",
+ card->devname);
-/*============================================================================
- * Convert line speed in bps to a number used by S502 code.
- */
+ else if (cause & 0x0040)
+
+ printk(KERN_INFO "%s: MRU option rejected by peer\n",
+ card->devname);
-static unsigned char bps_to_speed_code(unsigned long bps)
-{
- unsigned char number;
- if (bps <= 1200)
- number = 0x01;
- else if (bps <= 2400)
- number = 0x02;
- else if (bps <= 4800)
- number = 0x03;
- else if (bps <= 9600)
- number = 0x04;
- else if (bps <= 19200)
- number = 0x05;
- else if (bps <= 38400)
- number = 0x06;
- else if (bps <= 45000)
- number = 0x07;
- else if (bps <= 56000)
- number = 0x08;
- else if (bps <= 64000)
- number = 0x09;
- else if (bps <= 74000)
- number = 0x0A;
- else if (bps <= 112000)
- number = 0x0B;
- else if (bps <= 128000)
- number = 0x0C;
- else
- number = 0x0D;
- return number;
-}
+ else if (cause & 0x0080)
+
+ printk(KERN_INFO "%s: peer's MRU was too small\n",
+ card->devname);
-/*============================================================================
- * Process UDP call of type DRVSTATS.
- */
+ else if (cause & 0x0100)
-static int process_udp_driver_call(char udp_pkt_src, sdla_t * card, struct sk_buff *skb, struct net_device *dev, ppp_private_area_t * ppp_priv_area)
-{
- unsigned char *sendpacket;
- unsigned char buf2[5];
- unsigned char *data;
- unsigned char *buf;
- unsigned int len;
- ppp_mbox_t *mbox = card->mbox;
- struct sk_buff *new_skb;
- int err;
- sendpacket = skb->data;
- memcpy(&buf2, &card->wandev.udp_port, 2);
- if ((data = kmalloc(2000, GFP_ATOMIC)) == NULL) {
- printk(KERN_INFO
- "%s: Error allocating memory for UDP DRIVER STATS cmnd0x%02X"
- ,card->devname, data[45]);
- ++ppp_priv_area->UDP_DRVSTATS_mgmt_kmalloc_err;
- return 1;
- }
- memcpy(data, sendpacket, skb->len);
- switch (data[45]) {
- /* PPIPE_DRIVER_STATISTICS */
- case 0x26:
- *(unsigned long *) &data[60] =
- ppp_priv_area->if_send_entry;
- *(unsigned long *) &data[64] =
- ppp_priv_area->if_send_skb_null;
- *(unsigned long *) &data[68] =
- ppp_priv_area->if_send_broadcast;
- *(unsigned long *) &data[72] =
- ppp_priv_area->if_send_multicast;
- *(unsigned long *) &data[76] =
- ppp_priv_area->if_send_critical_ISR;
- *(unsigned long *) &data[80] =
- ppp_priv_area->if_send_critical_non_ISR;
- *(unsigned long *) &data[84] =
- ppp_priv_area->if_send_busy;
- *(unsigned long *) &data[88] =
- ppp_priv_area->if_send_busy_timeout;
- *(unsigned long *) &data[92] =
- ppp_priv_area->if_send_DRVSTATS_request;
- *(unsigned long *) &data[96] =
- ppp_priv_area->if_send_PTPIPE_request;
- *(unsigned long *) &data[100] =
- ppp_priv_area->if_send_wan_disconnected;
- *(unsigned long *) &data[104] =
- ppp_priv_area->if_send_adptr_bfrs_full;
- *(unsigned long *) &data[108] =
- ppp_priv_area->if_send_protocol_error;
- *(unsigned long *) &data[112] =
- ppp_priv_area->if_send_tx_int_enabled;
- *(unsigned long *) &data[116] =
- ppp_priv_area->if_send_bfr_passed_to_adptr;
- *(unsigned long *) &data[118] =
- card->irq_dis_if_send_count;
- mbox->cmd.length = 62;
- break;
- case 0x27:
- *(unsigned long *) &data[60] = card->statistics.isr_entry;
- *(unsigned long *) &data[64] =
- card->statistics.isr_already_critical;
- *(unsigned long *) &data[68] = card->statistics.isr_rx;
- *(unsigned long *) &data[72] = card->statistics.isr_tx;
- *(unsigned long *) &data[76] =
- card->statistics.isr_intr_test;
- *(unsigned long *) &data[80] =
- card->statistics.isr_spurious;
- *(unsigned long *) &data[84] =
- card->statistics.isr_enable_tx_int;
- *(unsigned long *) &data[88] =
- card->statistics.rx_intr_corrupt_rx_bfr;
- *(unsigned long *) &data[92] =
- ppp_priv_area->rx_intr_no_socket;
- *(unsigned long *) &data[96] =
- ppp_priv_area->rx_intr_DRVSTATS_request;
- *(unsigned long *) &data[100] =
- ppp_priv_area->rx_intr_PTPIPE_request;
- *(unsigned long *) &data[104] =
- ppp_priv_area->rx_intr_bfr_passed_to_stack;
- *(unsigned long *) &data[108] =
- card->statistics.rx_intr_dev_not_started;
- *(unsigned long *) &data[112] =
- card->statistics.tx_intr_dev_not_started;
- mbox->cmd.length = 56;
- break;
- case 0x28:
- *(unsigned long *) &data[60] =
- ppp_priv_area->UDP_PTPIPE_mgmt_kmalloc_err;
- *(unsigned long *) &data[64] =
- ppp_priv_area->UDP_PTPIPE_mgmt_adptr_type_err;
- *(unsigned long *) &data[68] =
- ppp_priv_area->UDP_PTPIPE_mgmt_direction_err;
- *(unsigned long *) &data[72] =
- ppp_priv_area->
- UDP_PTPIPE_mgmt_adptr_cmnd_timeout;
- *(unsigned long *) &data[76] =
- ppp_priv_area->UDP_PTPIPE_mgmt_adptr_cmnd_OK;
- *(unsigned long *) &data[80] =
- ppp_priv_area->UDP_PTPIPE_mgmt_passed_to_adptr;
- *(unsigned long *) &data[84] =
- ppp_priv_area->UDP_PTPIPE_mgmt_passed_to_stack;
- *(unsigned long *) &data[88] =
- ppp_priv_area->UDP_PTPIPE_mgmt_no_socket;
- *(unsigned long *) &data[92] =
- ppp_priv_area->UDP_DRVSTATS_mgmt_kmalloc_err;
- *(unsigned long *) &data[96] =
- ppp_priv_area->
- UDP_DRVSTATS_mgmt_adptr_cmnd_timeout;
- *(unsigned long *) &data[100] =
- ppp_priv_area->UDP_DRVSTATS_mgmt_adptr_cmnd_OK;
- *(unsigned long *) &data[104] =
- ppp_priv_area->
- UDP_DRVSTATS_mgmt_passed_to_adptr;
- *(unsigned long *) &data[108] =
- ppp_priv_area->
- UDP_DRVSTATS_mgmt_passed_to_stack;
- *(unsigned long *) &data[112] =
- ppp_priv_area->UDP_DRVSTATS_mgmt_no_socket;
- *(unsigned long *) &data[116] =
- card->statistics.poll_entry;
- *(unsigned long *) &data[120] =
- card->statistics.poll_already_critical;
- *(unsigned long *) &data[124] =
- card->statistics.poll_processed;
- *(unsigned long *) &data[126] =
- card->irq_dis_poll_count;
- mbox->cmd.length = 70;
- break;
- default:
- /* it's a board command */
- memcpy(&mbox->cmd, &sendpacket[45], sizeof(ppp_cmd_t));
- if (mbox->cmd.length) {
- memcpy(&mbox->data, &sendpacket[60],
- mbox->cmd.length);
- }
- /* run the command on the board */
- err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- if (err != CMD_OK) {
- ppp_error(card, err, mbox);
- ++ppp_priv_area->
- UDP_DRVSTATS_mgmt_adptr_cmnd_timeout;
- break;
- }
- ++ppp_priv_area->UDP_DRVSTATS_mgmt_adptr_cmnd_OK;
- /* copy the result back to our buffer */
- memcpy(data, sendpacket, skb->len);
- memcpy(&data[45], &mbox->cmd, sizeof(ppp_cmd_t));
- if (mbox->cmd.length) {
- memcpy(&data[60], &mbox->data, mbox->cmd.length);
- }
- }
- /* Fill UDP TTL */
- data[8] = card->wandev.ttl;
- len = reply_udp(data, mbox->cmd.length);
- if (udp_pkt_src == UDP_PKT_FRM_NETWORK) {
- ++ppp_priv_area->UDP_DRVSTATS_mgmt_passed_to_adptr;
- ppp_send(card, data, len, skb->protocol);
- } else {
- /* Pass it up the stack
- Allocate socket buffer */
- if ((new_skb = dev_alloc_skb(len)) != NULL) {
- /* copy data into new_skb */
- buf = skb_put(new_skb, len);
- memcpy(buf, data, len);
- ++ppp_priv_area->UDP_DRVSTATS_mgmt_passed_to_stack;
- /* Decapsulate packet and pass it up the protocol
- stack */
- new_skb->protocol = htons(ETH_P_IP);
- new_skb->dev = dev;
- new_skb->mac.raw = new_skb->data;
- netif_rx(new_skb);
- } else {
- ++ppp_priv_area->UDP_DRVSTATS_mgmt_no_socket;
- printk(KERN_INFO "no socket buffers available!\n");
- }
- }
- kfree(data);
- return 0;
+ printk(KERN_INFO "%s: failed to negotiate peer's LCP options\n",
+ card->devname);
+
+ else if (cause & 0x0200)
+
+ printk(KERN_INFO "%s: failed to negotiate peer's IPCP options\n"
+ , card->devname);
+
+ else if (cause & 0x0400)
+
+ printk(KERN_INFO
+ "%s: failed to negotiate peer's IPXCP options\n",
+ card->devname);
}
/*=============================================================================
* Process UDP call of type PTPIPEAB.
*/
-
-static int process_udp_mgmt_pkt(char udp_pkt_src, sdla_t * card,
- struct sk_buff *skb, struct net_device *dev,
- ppp_private_area_t * ppp_priv_area)
+static void process_udp_mgmt_pkt(sdla_t *card, struct net_device *dev,
+ ppp_private_area_t *ppp_priv_area )
{
- unsigned char *sendpacket;
unsigned char buf2[5];
- unsigned char *data;
unsigned char *buf;
unsigned int frames, len;
struct sk_buff *new_skb;
- unsigned short buffer_length, real_len;
+ unsigned short data_length, buffer_length, real_len;
unsigned long data_ptr;
int udp_mgmt_req_valid = 1;
ppp_mbox_t *mbox = card->mbox;
struct timeval tv;
int err;
- sendpacket = skb->data;
- memcpy(&buf2, &card->wandev.udp_port, 2);
- if ((data = kmalloc(2000, GFP_ATOMIC)) == NULL) {
- printk(KERN_INFO
- "%s: Error allocating memory for UDP management cmnd0x%02X"
- ,card->devname, data[45]);
- ++ppp_priv_area->UDP_PTPIPE_mgmt_kmalloc_err;
- return 1;
- }
- memcpy(data, sendpacket, skb->len);
- switch (data[45]) {
+ ppp_udp_pkt_t *ppp_udp_pkt = (ppp_udp_pkt_t*)&ppp_priv_area->udp_pkt_data;
+
+ memcpy(&buf2, &card->wandev.udp_port, 2 );
+
+
+ switch(ppp_udp_pkt->cblock.command) {
+
/* FT1 MONITOR STATUS */
- case 0x80:
- if (card->hw.fwid != SFID_PPP508) {
- ++ppp_priv_area->UDP_PTPIPE_mgmt_adptr_type_err;
- udp_mgmt_req_valid = 0;
- break;
- }
+ case FT1_MONITOR_STATUS_CTRL:
+
/* PPIPE_ENABLE_TRACING */
- case 0x20:
+ case PPIPE_ENABLE_TRACING:
+
/* PPIPE_DISABLE_TRACING */
- case 0x21:
+ case PPIPE_DISABLE_TRACING:
+
/* PPIPE_GET_TRACE_INFO */
- case 0x22:
+ case PPIPE_GET_TRACE_INFO:
+
/* SET FT1 MODE */
- case 0x81:
- if (udp_pkt_src == UDP_PKT_FRM_NETWORK) {
- ++ppp_priv_area->UDP_PTPIPE_mgmt_direction_err;
- udp_mgmt_req_valid = 0;
- }
- break;
- default:
- break;
- }
- if (!udp_mgmt_req_valid) {
+ case SET_FT1_MODE:
+ if(ppp_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) {
+
+ ++ppp_priv_area->pipe_mgmt_stat.
+ UDP_PIPE_mgmt_direction_err;
+ udp_mgmt_req_valid = 0;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if(!udp_mgmt_req_valid) {
+
/* set length to 0 */
- data[46] = data[47] = 0;
- /* set return code */
- data[48] = 0xCD;
- } else {
- switch (data[45]) {
- /* PPIPE_ENABLE_TRACING */
- case 0x20:
- if (!TracingEnabled) {
+ ppp_udp_pkt->cblock.length = 0x00;
+
+ /* set return code */
+ ppp_udp_pkt->cblock.result = 0xCD;
+
+ } else {
+ /* Initialize the trace element */
+ trace_element_t trace_element;
+
+ switch (ppp_udp_pkt->cblock.command){
+
+ /* PPIPE_ENABLE_TRACING */
+ case PPIPE_ENABLE_TRACING:
+ if (!card->TracingEnabled) {
+
/* OPERATE_DATALINE_MONITOR */
- mbox->cmd.command = 0x33;
- mbox->cmd.length = 1;
- mbox->data[0] = 0x03;
- err = sdla_exec(mbox) ?
- mbox->cmd.result : CMD_TIMEOUT;
- if (err != CMD_OK) {
+ mbox->cmd.command = PPP_DATALINE_MONITOR;
+ mbox->cmd.length = 0x01;
+ mbox->data[0] = ppp_udp_pkt->data[0];
+ err = sdla_exec(mbox) ?
+ mbox->cmd.result : CMD_TIMEOUT;
+
+ if (err != CMD_OK) {
+
ppp_error(card, err, mbox);
- TracingEnabled = 0;
+ card->TracingEnabled = 0;
+
/* set the return code */
- data[48] = mbox->cmd.result;
- mbox->cmd.length = 0;
- break;
- }
- if (card->hw.fwid == SFID_PPP502) {
- sdla_peek(&card->hw, 0x9000, &buf2, 2);
- } else {
- sdla_peek(&card->hw, 0xC000, &buf2, 2);
- }
- curr_trace_addr = 0;
- memcpy(&curr_trace_addr, &buf2, 2);
- start_trace_addr = curr_trace_addr;
- /* MAX_SEND_BUFFER_SIZE -sizeof(UDP_MGMT_PACKET)
- - 41 */
- available_buffer_space = 1926;
- }
- data[48] = 0;
- mbox->cmd.length = 0;
- TracingEnabled = 1;
- break;
- /* PPIPE_DISABLE_TRACING */
- case 0x21:
- if (TracingEnabled) {
+
+ ppp_udp_pkt->cblock.result = mbox->cmd.result;
+ mbox->cmd.length = 0;
+ break;
+ }
+
+ sdla_peek(&card->hw, 0xC000, &buf2, 2);
+
+ ppp_priv_area->curr_trace_addr = 0;
+ memcpy(&ppp_priv_area->curr_trace_addr, &buf2, 2);
+ ppp_priv_area->start_trace_addr =
+ ppp_priv_area->curr_trace_addr;
+ ppp_priv_area->end_trace_addr =
+ ppp_priv_area->start_trace_addr + END_OFFSET;
+
+ /* MAX_SEND_BUFFER_SIZE - 28 (IP header)
+ - 32 (ppipemon CBLOCK) */
+ available_buffer_space = MAX_LGTH_UDP_MGNT_PKT -
+ sizeof(ip_pkt_t)-
+ sizeof(udp_pkt_t)-
+ sizeof(wp_mgmt_t)-
+ sizeof(cblock_t);
+ }
+ ppp_udp_pkt->cblock.result = 0;
+ mbox->cmd.length = 0;
+ card->TracingEnabled = 1;
+ break;
+
+ /* PPIPE_DISABLE_TRACING */
+ case PPIPE_DISABLE_TRACING:
+
+ if(card->TracingEnabled) {
+
/* OPERATE_DATALINE_MONITOR */
- mbox->cmd.command = 0x3;
- mbox->cmd.length = 1;
- mbox->data[0] = 0x00;
- err = sdla_exec(mbox) ?
- mbox->cmd.result : CMD_TIMEOUT;
- }
- /*set return code */
- data[48] = 0;
+ mbox->cmd.command = 0x33;
+ mbox->cmd.length = 1;
+ mbox->data[0] = 0x00;
+ err = sdla_exec(mbox) ?
+ mbox->cmd.result : CMD_TIMEOUT;
+
+ }
+
+ /*set return code*/
+ ppp_udp_pkt->cblock.result = 0;
mbox->cmd.length = 0;
- TracingEnabled = 0;
+ card->TracingEnabled = 0;
break;
- /* PPIPE_GET_TRACE_INFO */
- case 0x22:
- if (TracingEnabled) {
- buffer_length = 0;
- /* frames < NUM_TRACE_FRAMES */
- for (frames = 0; frames < 62; frames += 1) {
- sdla_peek(&card->hw, curr_trace_addr,
- &buf2, 1);
- /* no data on board so exit */
- if (buf2[0] == 0x00)
- break;
- /*1+sizeof(FRAME_DATA) = 9 */
- if ((available_buffer_space -
- buffer_length) < 9) {
- /*indicate we have more frames
- on board and exit */
- data[60] |= 0x02;
+
+ /* PPIPE_GET_TRACE_INFO */
+ case PPIPE_GET_TRACE_INFO:
+
+ if(!card->TracingEnabled) {
+ /* set return code */
+ ppp_udp_pkt->cblock.result = 1;
+ mbox->cmd.length = 0;
+ }
+
+ buffer_length = 0;
+
+ /* frames < 62, where 62 is the number of trace
+ information elements. There is in total 496
+ bytes of space and each trace information
+ element is 8 bytes.
+ */
+ for ( frames=0; frames<62; frames++) {
+
+ trace_pkt_t *trace_pkt = (trace_pkt_t *)
+ &ppp_udp_pkt->data[buffer_length];
+
+ /* Read the whole trace packet */
+ sdla_peek(&card->hw, ppp_priv_area->curr_trace_addr,
+ &trace_element, sizeof(trace_element_t));
+
+ /* no data on board so exit */
+ if( trace_element.opp_flag == 0x00 )
+ break;
+
+ data_ptr = trace_element.trace_data_ptr;
+
+ /* See if there is actual data on the trace buffer */
+ if (data_ptr){
+ data_length = trace_element.trace_length;
+ }else{
+ data_length = 0;
+ ppp_udp_pkt->data[0] |= 0x02;
+ }
+
+ //FIXME: Do we need this check
+ if ((available_buffer_space - buffer_length)
+ < (sizeof(trace_element_t)+1)){
+
+ /*indicate we have more frames
+ * on board and exit
+ */
+ ppp_udp_pkt->data[0] |= 0x02;
+ break;
+ }
+
+ trace_pkt->status = trace_element.trace_type;
+ trace_pkt->time_stamp = trace_element.trace_time_stamp;
+ trace_pkt->real_length = trace_element.trace_length;
+
+ real_len = trace_element.trace_length;
+
+ if(data_ptr == 0){
+ trace_pkt->data_avail = 0x00;
+ }else{
+ /* we can take it next time */
+ if ((available_buffer_space - buffer_length)<
+ (real_len + sizeof(trace_pkt_t))){
+
+ ppp_udp_pkt->data[0] |= 0x02;
break;
- }
- /* get frame status */
- sdla_peek(&card->hw, curr_trace_addr +
- 0x01, &data[60 + buffer_length], 1);
- /* get time stamp */
- sdla_peek(&card->hw, curr_trace_addr +
- 0x06, &data[64 + buffer_length], 2);
- /* get frame length */
- sdla_peek(&card->hw, curr_trace_addr +
- 0x02, &data[62 + buffer_length], 2);
- /* get pointer to real data */
- sdla_peek(&card->hw, curr_trace_addr +
- 0x04, &buf2, 2);
- data_ptr = 0;
- memcpy(&data_ptr, &buf2, 2);
- /* see if we can fit the frame into the
- user buffer */
- memcpy(&real_len,
- &data[62 + buffer_length], 2);
- if ((data_ptr == 0) ||
- ((real_len + 8) >
- available_buffer_space)) {
- data[61 + buffer_length] = 0x00;
- } else {
- /* we can take it next time */
- if ((available_buffer_space -
- buffer_length) <
- (real_len + 8)) {
- data[60] |= 0x02;
- break;
- }
- /* ok, get the frame */
- data[61 + buffer_length] = 0x01;
- /* get the data */
- sdla_peek(&card->hw, data_ptr,
- &data[66 + buffer_length],
- real_len);
- /* zero the opp flag to
- show we got the frame */
- buf2[0] = 0x00;
- sdla_poke(&card->hw,
- curr_trace_addr, &buf2, 1);
- /* now move onto the next
- frame */
- curr_trace_addr += 8;
- /* check if we passed the last
- address */
- if (curr_trace_addr >=
- start_trace_addr + 0x1F0) {
- curr_trace_addr =
- start_trace_addr;
- }
- /* update buffer length and make sure its even */
- if (data[61 + buffer_length]
- == 0x01) {
- buffer_length +=
- real_len - 1;
- }
- /* for the header */
- buffer_length += 8;
- if (buffer_length & 0x0001)
- buffer_length += 1;
- }
+ }
+ trace_pkt->data_avail = 0x01;
+
+ /* get the data */
+ sdla_peek(&card->hw, data_ptr,
+ &trace_pkt->data,
+ real_len);
+ }
+ /* zero the opp flag to
+ show we got the frame */
+ buf2[0] = 0x00;
+ sdla_poke(&card->hw, ppp_priv_area->curr_trace_addr,
+ &buf2, 1);
+
+ /* now move onto the next
+ frame */
+ ppp_priv_area->curr_trace_addr += 8;
+
+ /* check if we passed the last address */
+ if ( ppp_priv_area->curr_trace_addr >=
+ ppp_priv_area->end_trace_addr){
+
+ ppp_priv_area->curr_trace_addr =
+ ppp_priv_area->start_trace_addr;
}
- /* ok now set the total number of frames passed
- in the high 5 bits */
- data[60] = (frames << 2) | data[60];
- /* set the data length */
- mbox->cmd.length = buffer_length;
- memcpy(&data[46], &buffer_length, 2);
- /* set return code */
- data[48] = 0;
- } else {
- /* set return code */
- data[48] = 1;
- mbox->cmd.length = 0;
+
+ /* update buffer length and make sure its even */
+
+ if ( trace_pkt->data_avail == 0x01 ) {
+ buffer_length += real_len - 1;
+ }
+
+ /* for the header */
+ buffer_length += 8;
+
+ if( buffer_length & 0x0001 )
+ buffer_length += 1;
}
- break;
- /* PPIPE_GET_IBA_DATA */
- case 0x23:
+
+ /* ok now set the total number of frames passed
+ in the high 5 bits */
+ ppp_udp_pkt->data[0] |= (frames << 2);
+
+ /* set the data length */
+ mbox->cmd.length = buffer_length;
+ ppp_udp_pkt->cblock.length = buffer_length;
+
+ /* set return code */
+ ppp_udp_pkt->cblock.result = 0;
+ break;
+
+ /* PPIPE_GET_IBA_DATA */
+ case PPIPE_GET_IBA_DATA:
+
mbox->cmd.length = 0x09;
- if (card->hw.fwid == SFID_PPP502) {
- sdla_peek(&card->hw, 0xA003, &data[60],
- mbox->cmd.length);
- } else {
- sdla_peek(&card->hw, 0xF003, &data[60],
- mbox->cmd.length);
- }
+
+ sdla_peek(&card->hw, 0xF003, &ppp_udp_pkt->data,
+ mbox->cmd.length);
+
/* set the length of the data */
- data[46] = 0x09;
+ ppp_udp_pkt->cblock.length = 0x09;
+
/* set return code */
- data[48] = 0x00;
+ ppp_udp_pkt->cblock.result = 0x00;
+
break;
- /* PPIPE_KILL_BOARD */
- case 0x24:
+
+ /* PPIPE_KILL_BOARD */
+ case PPIPE_KILL_BOARD:
break;
- /* PPIPE_FT1_READ_STATUS */
- case 0x25:
- sdla_peek(&card->hw, 0xF020, &data[60], 2);
- data[46] = 2;
- data[47] = 0;
- data[48] = 0;
+
+ /* PPIPE_FT1_READ_STATUS */
+ case PPIPE_FT1_READ_STATUS:
+ sdla_peek(&card->hw, 0xF020, &ppp_udp_pkt->data, 2);
+ ppp_udp_pkt->cblock.length = 2;
+ ppp_udp_pkt->cblock.result = 0;
mbox->cmd.length = 2;
break;
- case 0x29:
- init_ppp_priv_struct(ppp_priv_area);
- init_global_statistics(card);
+
+ case PPIPE_FLUSH_DRIVER_STATS:
+ init_ppp_priv_struct( ppp_priv_area );
+ init_global_statistics( card );
mbox->cmd.length = 0;
break;
- case 0x30:
- do_gettimeofday(&tv);
- ppp_priv_area->router_up_time = tv.tv_sec -
- ppp_priv_area->router_start_time;
- *(unsigned long *) &data[60] =
- ppp_priv_area->router_up_time;
+
+ case PPIPE_ROUTER_UP_TIME:
+
+ do_gettimeofday( &tv );
+ ppp_priv_area->router_up_time = tv.tv_sec -
+ ppp_priv_area->router_start_time;
+ *(unsigned long *)&ppp_udp_pkt->data = ppp_priv_area->router_up_time;
mbox->cmd.length = 4;
break;
- /* FT1 MONITOR STATUS */
- case 0x80:
+
+ /* FT1 MONITOR STATUS */
+ case FT1_MONITOR_STATUS_CTRL:
+
/* Enable FT1 MONITOR STATUS */
- if (data[60] == 1) {
- if (rCount++ != 0) {
- data[48] = 0;
- mbox->cmd.length = 1;
- break;
- }
- }
- /* Disable FT1 MONITOR STATUS */
- if (data[60] == 0) {
- if (--rCount != 0) {
- data[48] = 0;
- mbox->cmd.length = 1;
- break;
- }
- }
+ if( ppp_udp_pkt->data[0] == 1) {
+
+ if( rCount++ != 0 ) {
+ ppp_udp_pkt->cblock.result = 0;
+ mbox->cmd.length = 1;
+ break;
+ }
+ }
+
+ /* Disable FT1 MONITOR STATUS */
+ if( ppp_udp_pkt->data[0] == 0) {
+
+ if( --rCount != 0) {
+ ppp_udp_pkt->cblock.result = 0;
+ mbox->cmd.length = 1;
+ break;
+ }
+ }
+
+ /* PPIPE_DRIVER_STATISTICS */
+ case PPIPE_DRIVER_STAT_IFSEND:
+ printk(KERN_INFO "Getting IF_SEND Drivers Statistics\n");
+ memcpy(&ppp_udp_pkt->data, &ppp_priv_area->if_send_stat,
+ sizeof(if_send_stat_t));
+
+
+ ppp_udp_pkt->cblock.result = 0;
+ ppp_udp_pkt->cblock.length = sizeof(if_send_stat_t);
+ mbox->cmd.length = sizeof(if_send_stat_t);
+ break;
+
+ case PPIPE_DRIVER_STAT_INTR:
+ memcpy(&ppp_udp_pkt->data, &card->statistics,
+ sizeof(global_stats_t));
+
+ memcpy(&ppp_udp_pkt->data+sizeof(global_stats_t),
+ &ppp_priv_area->rx_intr_stat,
+ sizeof(rx_intr_stat_t));
+
+ ppp_udp_pkt->cblock.result = 0;
+ ppp_udp_pkt->cblock.length = sizeof(global_stats_t)+
+ sizeof(rx_intr_stat_t);
+ mbox->cmd.length = ppp_udp_pkt->cblock.length;
+ break;
+
+ case PPIPE_DRIVER_STAT_GEN:
+ memcpy( &ppp_udp_pkt->data,
+ &ppp_priv_area->pipe_mgmt_stat,
+ sizeof(pipe_mgmt_stat_t));
+
+ memcpy(&ppp_udp_pkt->data+sizeof(pipe_mgmt_stat_t),
+ &card->statistics, sizeof(global_stats_t));
+
+ ppp_udp_pkt->cblock.result = 0;
+ ppp_udp_pkt->cblock.length = sizeof(global_stats_t)+
+ sizeof(rx_intr_stat_t);
+ mbox->cmd.length = ppp_udp_pkt->cblock.length;
+ break;
+
+
default:
+
/* it's a board command */
- memcpy(&mbox->cmd, &sendpacket[45], sizeof(ppp_cmd_t));
- if (mbox->cmd.length) {
- memcpy(&mbox->data, &sendpacket[60],
+ mbox->cmd.command = ppp_udp_pkt->cblock.command;
+ mbox->cmd.length = ppp_udp_pkt->cblock.length;
+
+ if(mbox->cmd.length) {
+ memcpy(&mbox->data,(unsigned char *)ppp_udp_pkt->data,
mbox->cmd.length);
- }
+ }
+
/* run the command on the board */
err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
+
if (err != CMD_OK) {
- ppp_error(card, err, mbox);
- ++ppp_priv_area->
- UDP_PTPIPE_mgmt_adptr_cmnd_timeout;
+
+ ppp_error(card, err, mbox);
+ ++ppp_priv_area->pipe_mgmt_stat.
+ UDP_PIPE_mgmt_adptr_cmnd_timeout;
break;
}
- ++ppp_priv_area->UDP_PTPIPE_mgmt_adptr_cmnd_OK;
+
+ ++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_adptr_cmnd_OK;
+
/* copy the result back to our buffer */
- memcpy(data, sendpacket, skb->len);
- memcpy(&data[45], &mbox->cmd, sizeof(ppp_cmd_t));
- if (mbox->cmd.length) {
- memcpy(&data[60], &mbox->data, mbox->cmd.length);
- }
- } /* end of switch */
- } /* end of else */
- /* Fill UDP TTL */
- data[8] = card->wandev.ttl;
- len = reply_udp(data, mbox->cmd.length);
- if (udp_pkt_src == UDP_PKT_FRM_NETWORK) {
- ++ppp_priv_area->UDP_PTPIPE_mgmt_passed_to_adptr;
- ppp_send(card, data, len, skb->protocol);
- } else {
+ memcpy(&ppp_udp_pkt->cblock,mbox, sizeof(cblock_t));
+
+ if(mbox->cmd.length) {
+ memcpy(&ppp_udp_pkt->data,&mbox->data,mbox->cmd.length);
+ }
+
+ } /* end of switch */
+ } /* end of else */
+
+ /* Fill UDP TTL */
+ ppp_udp_pkt->ip_pkt.ttl = card->wandev.ttl;
+ len = reply_udp(ppp_priv_area->udp_pkt_data, mbox->cmd.length);
+
+ if (ppp_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) {
+
+ ++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_passed_to_adptr;
+ ppp_send(card,ppp_priv_area->udp_pkt_data,len,ppp_priv_area->protocol);
+
+ } else {
+
/* Pass it up the stack
- Allocate socket buffer */
+ Allocate socket buffer */
if ((new_skb = dev_alloc_skb(len)) != NULL) {
+
/* copy data into new_skb */
- buf = skb_put(new_skb, len);
- memcpy(buf, data, len);
- ++ppp_priv_area->UDP_PTPIPE_mgmt_passed_to_stack;
- /* Decapsulate packet and pass it up the protocol
+
+ buf = skb_put(new_skb, len);
+ memcpy(buf,ppp_priv_area->udp_pkt_data, len);
+
+ ++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_passed_to_stack;
+
+ /* Decapsulate packet and pass it up the protocol
stack */
- new_skb->protocol = htons(ETH_P_IP);
- new_skb->dev = dev;
- new_skb->mac.raw = new_skb->data;
+ new_skb->protocol = htons(ETH_P_IP);
+ new_skb->dev = dev;
+ new_skb->mac.raw = new_skb->data;
netif_rx(new_skb);
+
} else {
- ++ppp_priv_area->UDP_PTPIPE_mgmt_no_socket;
+
+ ++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_no_socket;
printk(KERN_INFO "no socket buffers available!\n");
- }
- }
- kfree(data);
- return 0;
+ }
+ }
+
+ ppp_priv_area->udp_pkt_lgth = 0;
+
+ return;
}
/*=============================================================================
* Initial the ppp_private_area structure.
*/
-
-static void init_ppp_priv_struct(ppp_private_area_t * ppp_priv_area)
+static void init_ppp_priv_struct( ppp_private_area_t *ppp_priv_area )
{
- ppp_priv_area->if_send_entry = 0;
- ppp_priv_area->if_send_skb_null = 0;
- ppp_priv_area->if_send_broadcast = 0;
- ppp_priv_area->if_send_multicast = 0;
- ppp_priv_area->if_send_critical_ISR = 0;
- ppp_priv_area->if_send_critical_non_ISR = 0;
- ppp_priv_area->if_send_busy = 0;
- ppp_priv_area->if_send_busy_timeout = 0;
- ppp_priv_area->if_send_DRVSTATS_request = 0;
- ppp_priv_area->if_send_PTPIPE_request = 0;
- ppp_priv_area->if_send_wan_disconnected = 0;
- ppp_priv_area->if_send_adptr_bfrs_full = 0;
- ppp_priv_area->if_send_bfr_passed_to_adptr = 0;
- ppp_priv_area->rx_intr_no_socket = 0;
- ppp_priv_area->rx_intr_DRVSTATS_request = 0;
- ppp_priv_area->rx_intr_PTPIPE_request = 0;
- ppp_priv_area->rx_intr_bfr_not_passed_to_stack = 0;
- ppp_priv_area->rx_intr_bfr_passed_to_stack = 0;
- ppp_priv_area->UDP_PTPIPE_mgmt_kmalloc_err = 0;
- ppp_priv_area->UDP_PTPIPE_mgmt_adptr_type_err = 0;
- ppp_priv_area->UDP_PTPIPE_mgmt_direction_err = 0;
- ppp_priv_area->UDP_PTPIPE_mgmt_adptr_cmnd_timeout = 0;
- ppp_priv_area->UDP_PTPIPE_mgmt_adptr_cmnd_OK = 0;
- ppp_priv_area->UDP_PTPIPE_mgmt_passed_to_adptr = 0;
- ppp_priv_area->UDP_PTPIPE_mgmt_passed_to_stack = 0;
- ppp_priv_area->UDP_PTPIPE_mgmt_no_socket = 0;
- ppp_priv_area->UDP_DRVSTATS_mgmt_kmalloc_err = 0;
- ppp_priv_area->UDP_DRVSTATS_mgmt_adptr_type_err = 0;
- ppp_priv_area->UDP_DRVSTATS_mgmt_direction_err = 0;
- ppp_priv_area->UDP_DRVSTATS_mgmt_adptr_cmnd_timeout = 0;
- ppp_priv_area->UDP_DRVSTATS_mgmt_adptr_cmnd_OK = 0;
- ppp_priv_area->UDP_DRVSTATS_mgmt_passed_to_adptr = 0;
- ppp_priv_area->UDP_DRVSTATS_mgmt_passed_to_stack = 0;
- ppp_priv_area->UDP_DRVSTATS_mgmt_no_socket = 0;
+
+ memset(&ppp_priv_area->if_send_stat, 0, sizeof(if_send_stat_t));
+ memset(&ppp_priv_area->rx_intr_stat, 0, sizeof(rx_intr_stat_t));
+ memset(&ppp_priv_area->pipe_mgmt_stat, 0, sizeof(pipe_mgmt_stat_t));
}
/*============================================================================
* Initialize Global Statistics
*/
-
-static void init_global_statistics(sdla_t * card)
+static void init_global_statistics( sdla_t *card )
{
- card->statistics.isr_entry = 0;
- card->statistics.isr_already_critical = 0;
- card->statistics.isr_tx = 0;
- card->statistics.isr_rx = 0;
- card->statistics.isr_intr_test = 0;
- card->statistics.isr_spurious = 0;
- card->statistics.isr_enable_tx_int = 0;
- card->statistics.rx_intr_corrupt_rx_bfr = 0;
- card->statistics.rx_intr_dev_not_started = 0;
- card->statistics.tx_intr_dev_not_started = 0;
- card->statistics.poll_entry = 0;
- card->statistics.poll_already_critical = 0;
- card->statistics.poll_processed = 0;
- card->statistics.poll_tbusy_bad_status = 0;
+ memset(&card->statistics, 0, sizeof(global_stats_t));
}
/*============================================================================
* Initialize Receive and Transmit Buffers.
*/
-
-static void init_ppp_tx_rx_buff(sdla_t * card)
+static void init_ppp_tx_rx_buff( sdla_t *card )
{
- if (card->hw.fwid == SFID_PPP502) {
- ppp502_buf_info_t *info =
- (void *) (card->hw.dpmbase + PPP502_BUF_OFFS);
- card->u.p.txbuf_base =
- (void *) (card->hw.dpmbase + info->txb_offs);
- card->u.p.txbuf_last = (ppp_buf_ctl_t *) card->u.p.txbuf_base +
- (info->txb_num - 1);
- card->u.p.rxbuf_base =
- (void *) (card->hw.dpmbase + info->rxb_offs);
- card->u.p.rxbuf_last = (ppp_buf_ctl_t *) card->u.p.rxbuf_base +
- (info->rxb_num - 1);
+ ppp508_buf_info_t* info;
+
+ if (card->hw.type == SDLA_S514) {
+
+ info = (void*)(card->hw.dpmbase + PPP514_BUF_OFFS);
+
+ card->u.p.txbuf_base = (void*)(card->hw.dpmbase +
+ info->txb_ptr);
+
+ card->u.p.txbuf_last = (ppp_buf_ctl_t*)card->u.p.txbuf_base +
+ (info->txb_num - 1);
+
+ card->u.p.rxbuf_base = (void*)(card->hw.dpmbase +
+ info->rxb_ptr);
+
+ card->u.p.rxbuf_last = (ppp_buf_ctl_t*)card->u.p.rxbuf_base +
+ (info->rxb_num - 1);
+
} else {
- ppp508_buf_info_t *info =
- (void *) (card->hw.dpmbase + PPP508_BUF_OFFS);
- card->u.p.txbuf_base = (void *) (card->hw.dpmbase +
- (info->txb_ptr - PPP508_MB_VECT));
- card->u.p.txbuf_last = (ppp_buf_ctl_t *) card->u.p.txbuf_base +
- (info->txb_num - 1);
- card->u.p.rxbuf_base = (void *) (card->hw.dpmbase +
- (info->rxb_ptr - PPP508_MB_VECT));
- card->u.p.rxbuf_last = (ppp_buf_ctl_t *) card->u.p.rxbuf_base +
- (info->rxb_num - 1);
- card->u.p.rx_base = info->rxb_base;
- card->u.p.rx_top = info->rxb_end;
+
+ info = (void*)(card->hw.dpmbase + PPP508_BUF_OFFS);
+
+ card->u.p.txbuf_base = (void*)(card->hw.dpmbase +
+ (info->txb_ptr - PPP508_MB_VECT));
+
+ card->u.p.txbuf_last = (ppp_buf_ctl_t*)card->u.p.txbuf_base +
+ (info->txb_num - 1);
+
+ card->u.p.rxbuf_base = (void*)(card->hw.dpmbase +
+ (info->rxb_ptr - PPP508_MB_VECT));
+
+ card->u.p.rxbuf_last = (ppp_buf_ctl_t*)card->u.p.rxbuf_base +
+ (info->rxb_num - 1);
}
+
+ card->u.p.rx_base = info->rxb_base;
+ card->u.p.rx_top = info->rxb_end;
+
card->u.p.txbuf = card->u.p.txbuf_base;
card->rxmb = card->u.p.rxbuf_base;
+
+}
+
+/*=============================================================================
+ * Read Connection Information (ie for Remote IP address assginment).
+ * Called when ppp interface connected.
+ */
+static int read_info( sdla_t *card )
+{
+ struct net_device *dev = card->wandev.dev;
+ ppp_private_area_t *ppp_priv_area = dev->priv;
+ int err;
+ struct ifreq if_info;
+ struct sockaddr_in *if_data1, *if_data2;
+ mm_segment_t fs;
+
+ /* Set Local and remote addresses */
+ memset(&if_info, 0, sizeof(if_info));
+ strcpy(if_info.ifr_name, dev->name);
+
+ fs = get_fs();
+ set_fs(get_ds()); /* get user space block */
+
+
+ /* Change the local and remote ip address of the interface.
+ * This will also add in the destination route.
+ */
+ if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
+ if_data1->sin_addr.s_addr = ppp_priv_area->ip_local;
+ if_data1->sin_family = AF_INET;
+ err = devinet_ioctl( SIOCSIFADDR, &if_info );
+ if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
+ if_data2->sin_addr.s_addr = ppp_priv_area->ip_remote;
+ if_data2->sin_family = AF_INET;
+ err = devinet_ioctl( SIOCSIFDSTADDR, &if_info );
+
+ set_fs(fs); /* restore old block */
+
+
+ if (err) {
+ printk (KERN_INFO "%s: Adding of route failed:\n",
+ card->devname);
+ printk (KERN_INFO "%s: Local : %s\n",
+ card->devname,in_ntoa(ppp_priv_area->ip_local));
+ printk (KERN_INFO "%s: Remote: %s\n",
+ card->devname,in_ntoa(ppp_priv_area->ip_remote));
+ }
+ return err;
+}
+
+/*=============================================================================
+ * Remove Dynamic Route.
+ * Called when ppp interface disconnected.
+ */
+
+static int remove_route( sdla_t *card )
+{
+
+ struct net_device *dev = card->wandev.dev;
+ long ip_addr;
+ int err;
+
+ mm_segment_t fs;
+ struct ifreq if_info;
+ struct sockaddr_in *if_data1;
+ struct in_device *in_dev = dev->ip_ptr;
+ struct in_ifaddr *ifa = in_dev->ifa_list;
+
+
+ ip_addr = ifa->ifa_local;
+
+ /* Set Local and remote addresses */
+ memset(&if_info, 0, sizeof(if_info));
+ strcpy(if_info.ifr_name, dev->name);
+
+
+ fs = get_fs();
+ set_fs(get_ds()); /* get user space block */
+
+
+ /* Change the local ip address of the interface to 0.
+ * This will also delete the destination route.
+ */
+ if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
+ if_data1->sin_addr.s_addr = 0;
+ if_data1->sin_family = AF_INET;
+ err = devinet_ioctl( SIOCSIFADDR, &if_info );
+
+ set_fs(fs); /* restore old block */
+
+
+ if (err) {
+ printk (KERN_INFO "%s: Deleting dynamic route failed %d!\n",
+ card->devname, err);
+ return err;
+ }else
+ printk (KERN_INFO "%s: PPP Deleting dynamic route %s successfuly\n",
+ card->devname, in_ntoa(ip_addr));
+
+
+ return 0;
}
/*=============================================================================
* Perform the Interrupt Test by running the READ_CODE_VERSION command MAX_INTR
* _TEST_COUNTER times.
*/
-
-static int intr_test(sdla_t * card)
+static int intr_test( sdla_t *card )
{
ppp_mbox_t *mb = card->mbox;
- int err, i;
- /* The critical flag is unset because during initialization (if_open)
+ int err,i;
+
+ /* The critical flag is unset because during intialization (if_open)
* we want the interrupts to be enabled so that when the wpp_isr is
* called it does not exit due to critical flag set.
- */
+ */
+
card->wandev.critical = 0;
- err = ppp_set_intr_mode(card, 0x08);
- if (err == CMD_OK) {
- for (i = 0; i < MAX_INTR_TEST_COUNTER; i++) {
+
+ err = ppp_set_intr_mode( card, 0x08 );
+
+ if (err == CMD_OK) {
+
+ for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) {
/* Run command READ_CODE_VERSION */
memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
- mb->cmd.length = 0;
- mb->cmd.command = 0x10;
+ mb->cmd.length = 0;
+ mb->cmd.command = PPP_READ_CODE_VERSION;
err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
- if (err != CMD_OK)
+ if (err != CMD_OK)
ppp_error(card, err, mb);
}
- } else
- return err;
- err = ppp_set_intr_mode(card, 0);
- if (err != CMD_OK)
+ }
+ else return err;
+
+ err = ppp_set_intr_mode( card, 0 );
+ if (err != CMD_OK)
return err;
+
card->wandev.critical = 1;
return 0;
}
@@ -2222,40 +2796,140 @@ static int intr_test(sdla_t * card)
/*==============================================================================
* Determine what type of UDP call it is. DRVSTATS or PTPIPEAB ?
*/
-
-static int udp_pkt_type(struct sk_buff *skb, sdla_t * card)
+static int udp_pkt_type( struct sk_buff *skb, sdla_t *card )
{
unsigned char *sendpacket;
- unsigned char buf2[5];
+ unsigned char buf2[5];
+ //FIXME: Use the structure
+ ppp_udp_pkt_t *ppp_udp_pkt = (ppp_udp_pkt_t *)skb->data;
+
sendpacket = skb->data;
memcpy(&buf2, &card->wandev.udp_port, 2);
- if (sendpacket[0] == 0x45 && /* IP packet */
- sendpacket[9] == 0x11 && /* UDP packet */
- sendpacket[22] == buf2[1] && /* UDP Port */
- sendpacket[23] == buf2[0] &&
- sendpacket[36] == 0x01) {
- if (sendpacket[28] == 0x50 && /* PTPIPEAB: Signature */
- sendpacket[29] == 0x54 &&
- sendpacket[30] == 0x50 &&
- sendpacket[31] == 0x49 &&
- sendpacket[32] == 0x50 &&
- sendpacket[33] == 0x45 &&
- sendpacket[34] == 0x41 &&
- sendpacket[35] == 0x42) {
+
+ if( ppp_udp_pkt->ip_pkt.ver_inet_hdr_length == 0x45 && /* IP packet */
+ sendpacket[9] == 0x11 && /* UDP packet */
+ sendpacket[22] == buf2[1] && /* UDP Port */
+ sendpacket[23] == buf2[0] &&
+ sendpacket[36] == 0x01 ) {
+
+ if ( sendpacket[28] == 0x50 && /* PTPIPEAB: Signature */
+ sendpacket[29] == 0x54 &&
+ sendpacket[30] == 0x50 &&
+ sendpacket[31] == 0x49 &&
+ sendpacket[32] == 0x50 &&
+ sendpacket[33] == 0x45 &&
+ sendpacket[34] == 0x41 &&
+ sendpacket[35] == 0x42 ){
+
return UDP_PTPIPE_TYPE;
- } else if (sendpacket[28] == 0x44 && /* DRVSTATS: Signature */
- sendpacket[29] == 0x52 &&
- sendpacket[30] == 0x56 &&
- sendpacket[31] == 0x53 &&
- sendpacket[32] == 0x54 &&
- sendpacket[33] == 0x41 &&
- sendpacket[34] == 0x54 &&
- sendpacket[35] == 0x53) {
+
+ } else if(sendpacket[28] == 0x44 && /* DRVSTATS: Signature */
+ sendpacket[29] == 0x52 &&
+ sendpacket[30] == 0x56 &&
+ sendpacket[31] == 0x53 &&
+ sendpacket[32] == 0x54 &&
+ sendpacket[33] == 0x41 &&
+ sendpacket[34] == 0x54 &&
+ sendpacket[35] == 0x53 ){
+
return UDP_DRVSTATS_TYPE;
+
} else
return UDP_INVALID_TYPE;
+
} else
return UDP_INVALID_TYPE;
+
+}
+
+/*============================================================================
+ * Check to see if the packet to be transmitted contains a broadcast or
+ * multicast source IP address.
+ */
+
+static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev,
+ struct sk_buff *skb)
+{
+ u32 src_ip_addr;
+ u32 broadcast_ip_addr = 0;
+ struct in_device *in_dev;
+ /* read the IP source address from the outgoing packet */
+ src_ip_addr = *(u32 *)(skb->data + 12);
+
+ /* read the IP broadcast address for the device */
+ in_dev = dev->ip_ptr;
+ if(in_dev != NULL) {
+ struct in_ifaddr *ifa= in_dev->ifa_list;
+ if(ifa != NULL)
+ broadcast_ip_addr = ifa->ifa_broadcast;
+ else
+ return 0;
+ }
+
+ /* check if the IP Source Address is a Broadcast address */
+ if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) {
+ printk(KERN_INFO "%s: Broadcast Source Address silently discarded\n",
+ card->devname);
+ dev_kfree_skb(skb);
+ ++card->wandev.stats.tx_dropped;
+ return 1;
+ }
+
+ /* check if the IP Source Address is a Multicast address */
+ if((ntohl(src_ip_addr) >= 0xE0000001) &&
+ (ntohl(src_ip_addr) <= 0xFFFFFFFE)) {
+ printk(KERN_INFO "%s: Multicast Source Address silently discarded\n",
+ card->devname);
+ dev_kfree_skb(skb);
+ ++card->wandev.stats.tx_dropped;
+ return 1;
+ }
+
+ return 0;
+}
+
+void s508_lock (sdla_t *card, unsigned long *smp_flags)
+{
+#ifdef __SMP__
+ spin_lock_irqsave(&card->lock, *smp_flags);
+#else
+ disable_irq(card->hw.irq);
+#endif
+}
+
+void s508_unlock (sdla_t *card, unsigned long *smp_flags)
+{
+#ifdef __SMP__
+ spin_unlock_irqrestore(&card->lock, *smp_flags);
+#else
+ enable_irq(card->hw.irq);
+#endif
+}
+
+static int read_connection_info (sdla_t *card)
+{
+ ppp_mbox_t *mb = card->mbox;
+ struct net_device *dev = card->wandev.dev;
+ ppp_private_area_t *ppp_priv_area = dev->priv;
+ ppp508_connect_info_t *ppp508_connect_info;
+ int err;
+
+ memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
+ mb->cmd.length = 0;
+ mb->cmd.command = PPP_GET_CONNECTION_INFO;
+ err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
+
+ if (err != CMD_OK) {
+ ppp_error(card, err, mb);
+ }
+ else {
+ ppp508_connect_info = (ppp508_connect_info_t *)mb->data;
+
+ ppp_priv_area->ip_remote = ppp508_connect_info->ip_remote;
+ ppp_priv_area->ip_local = ppp508_connect_info->ip_local;
+ }
+
+ return err;
}
/****** End *****************************************************************/
diff --git a/drivers/net/wan/sdladrv.c b/drivers/net/wan/sdladrv.c
index 5e1f6b99e..06e86de82 100644
--- a/drivers/net/wan/sdladrv.c
+++ b/drivers/net/wan/sdladrv.c
@@ -4,17 +4,18 @@
* This module is a library of common hardware-specific functions
* used by all Sangoma drivers.
*
-* Author: Gene Kozin <genek@compuserve.com>
-* Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+* Author: Gideon Hack
*
-* Copyright: (c) 1995-1996 Sangoma Technologies Inc.
+* Copyright: (c) 1995-1999 Sangoma Technologies 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.
* ============================================================================
-* May 19, 1999 Arnaldo Melo wanpipe_init belongs to sdlamain.c
+* Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
+* Updates for Linux 2.2.X kernels.
+* Sep 17, 1998 Jaspreet Singh Updates for linux 2.2.X kernels
* Dec 20, 1996 Gene Kozin Version 3.0.0. Complete overhaul.
* Jul 12, 1996 Gene Kozin Changes for Linux 2.0 compatibility.
* Jun 12, 1996 Gene Kozin Added support for S503 card.
@@ -83,6 +84,8 @@
#if defined(_LINUX_) /****** Linux *******************************/
+#include <linux/config.h>
+#include <linux/version.h>
#include <linux/kernel.h> /* printk(), and other useful stuff */
#include <linux/stddef.h> /* offsetof(), etc. */
#include <linux/errno.h> /* return codes */
@@ -91,12 +94,18 @@
#include <linux/sched.h> /* for jiffies, HZ, etc. */
#include <linux/sdladrv.h> /* API definitions */
#include <linux/sdlasfm.h> /* SDLA firmware module definitions */
+#include <linux/sdlapci.h> /* SDLA PCI hardware definitions */
+#include <linux/pci.h> /* PCI defines and function prototypes */
#include <asm/io.h> /* for inb(), outb(), etc. */
+
#define _INB(port) (inb(port))
#define _OUTB(port, byte) (outb((byte),(port)))
#define SYSTEM_TICK jiffies
+#include <linux/init.h>
+
#elif defined(_SCO_UNIX_) /****** SCO Unix ****************************/
+
#if !defined(INKERNEL)
#error This code MUST be compiled in kernel mode!
#endif
@@ -136,6 +145,11 @@
#define S503_MINMEM 0x8000L
#define S507_MINMEM 0x20000L
#define S508_MINMEM 0x20000L
+#define NO_PORT -1
+
+
+
+
/****** Function Prototypes *************************************************/
@@ -159,14 +173,18 @@ static int init_s502e (sdlahw_t* hw);
static int init_s503 (sdlahw_t* hw);
static int init_s507 (sdlahw_t* hw);
static int init_s508 (sdlahw_t* hw);
-
+
static int detect_s502a (int port);
static int detect_s502e (int port);
static int detect_s503 (int port);
static int detect_s507 (int port);
static int detect_s508 (int port);
+static int detect_s514 (sdlahw_t* hw);
+static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card);
/* Miscellaneous functions */
+static void peek_by_4 (unsigned long src, void* buf, unsigned len);
+static void poke_by_4 (unsigned long dest, void* buf, unsigned len);
static int calibrate_delay (int mks);
static int get_option_index (unsigned* optlist, unsigned optval);
static unsigned check_memregion (void* ptr, unsigned len);
@@ -180,7 +198,7 @@ static unsigned short checksum (unsigned char* buf, unsigned len);
/* private data */
static char modname[] = "sdladrv";
static char fullname[] = "SDLA Support Module";
-static char copyright[] = "(c) 1995-1996 Sangoma Technologies Inc.";
+static char copyright[] = "(c) 1995-1999 Sangoma Technologies Inc.";
static unsigned exec_idle;
/* Hardware configuration options.
@@ -289,6 +307,9 @@ static unsigned char s507_irqmask[] =
#ifdef MODULE
int init_module (void)
+#else
+__initfunc(int wanpipe_init(void))
+#endif
{
printk(KERN_INFO "%s v%u.%u %s\n",
fullname, MOD_VERSION, MOD_RELEASE, copyright);
@@ -299,6 +320,7 @@ int init_module (void)
return 0;
}
+#ifdef MODULE
/*============================================================================
* Module 'remove' entry point.
* o release all remaining system resources
@@ -321,7 +343,7 @@ void cleanup_module (void)
* Return: 0 ok.
* < 0 error
*/
-
+
EXPORT_SYMBOL(sdla_setup);
int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len)
@@ -329,118 +351,123 @@ int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len)
unsigned* irq_opt = NULL; /* IRQ options */
unsigned* dpmbase_opt = NULL; /* DPM window base options */
unsigned* pclk_opt = NULL; /* CPU clock rate options */
- int err;
+ int err=0;
- if (sdla_detect(hw))
- {
- printk(KERN_ERR "%s: adapter S%04u not found at port 0x%X!\n",
- modname, hw->type, hw->port)
- ;
+ if (sdla_detect(hw)) {
+ if(hw->type != SDLA_S514)
+ printk(KERN_ERR "%s: no SDLA card found at port 0x%X\n",
+ modname, hw->port);
return -EINVAL;
}
- printk(KERN_INFO "%s: found S%04u card at port 0x%X.\n",
- modname, hw->type, hw->port)
- ;
-
- hw->dpmsize = SDLA_WINDOWSIZE;
- switch (hw->type)
- {
- case SDLA_S502A:
- hw->io_range = S502A_IORANGE;
- irq_opt = s502a_irq_options;
- dpmbase_opt = s502a_dpmbase_options;
- pclk_opt = s502a_pclk_options;
- break;
-
- case SDLA_S502E:
- hw->io_range = S502E_IORANGE;
- irq_opt = s502e_irq_options;
- dpmbase_opt = s508_dpmbase_options;
- pclk_opt = s502e_pclk_options;
- break;
-
- case SDLA_S503:
- hw->io_range = S503_IORANGE;
- irq_opt = s503_irq_options;
- dpmbase_opt = s508_dpmbase_options;
- pclk_opt = s503_pclk_options;
- break;
-
- case SDLA_S507:
- hw->io_range = S507_IORANGE;
- irq_opt = s508_irq_options;
- dpmbase_opt = s507_dpmbase_options;
- pclk_opt = s507_pclk_options;
- break;
-
- case SDLA_S508:
- hw->io_range = S508_IORANGE;
- irq_opt = s508_irq_options;
- dpmbase_opt = s508_dpmbase_options;
- pclk_opt = s508_pclk_options;
- break;
- }
-
- /* Verify IRQ configuration options */
- if (!get_option_index(irq_opt, hw->irq))
- {
- printk(KERN_ERR "%s: IRQ %d is illegal!\n",
- modname, hw->irq)
- ;
- return -EINVAL;
- }
- /* Verify CPU clock rate configuration options */
- if (hw->pclk == 0)
- hw->pclk = pclk_opt[1] /* use default */
- ;
- else if (!get_option_index(pclk_opt, hw->pclk))
- {
- printk(KERN_ERR "%s: CPU clock %u is illegal!\n",
- modname, hw->pclk)
- ;
- return -EINVAL;
- }
- printk(KERN_INFO "%s: assuming CPU clock rate of %u kHz.\n",
- modname, hw->pclk)
- ;
-
- /* Setup adapter dual-port memory window and test memory */
- if (hw->dpmbase == 0)
- {
- err = sdla_autodpm(hw);
- if (err)
- {
- printk(KERN_ERR
+ if(hw->type != SDLA_S514) {
+ printk(KERN_INFO "%s: found S%04u card at port 0x%X.\n",
+ modname, hw->type, hw->port);
+
+ hw->dpmsize = SDLA_WINDOWSIZE;
+ switch (hw->type) {
+ case SDLA_S502A:
+ hw->io_range = S502A_IORANGE;
+ irq_opt = s502a_irq_options;
+ dpmbase_opt = s502a_dpmbase_options;
+ pclk_opt = s502a_pclk_options;
+ break;
+
+ case SDLA_S502E:
+ hw->io_range = S502E_IORANGE;
+ irq_opt = s502e_irq_options;
+ dpmbase_opt = s508_dpmbase_options;
+ pclk_opt = s502e_pclk_options;
+ break;
+
+ case SDLA_S503:
+ hw->io_range = S503_IORANGE;
+ irq_opt = s503_irq_options;
+ dpmbase_opt = s508_dpmbase_options;
+ pclk_opt = s503_pclk_options;
+ break;
+
+ case SDLA_S507:
+ hw->io_range = S507_IORANGE;
+ irq_opt = s508_irq_options;
+ dpmbase_opt = s507_dpmbase_options;
+ pclk_opt = s507_pclk_options;
+ break;
+
+ case SDLA_S508:
+ hw->io_range = S508_IORANGE;
+ irq_opt = s508_irq_options;
+ dpmbase_opt = s508_dpmbase_options;
+ pclk_opt = s508_pclk_options;
+ break;
+ }
+
+ /* Verify IRQ configuration options */
+ if (!get_option_index(irq_opt, hw->irq)) {
+ printk(KERN_ERR "%s: IRQ %d is illegal!\n",
+ modname, hw->irq);
+ return -EINVAL;
+ }
+
+ /* Verify CPU clock rate configuration options */
+ if (hw->pclk == 0)
+ hw->pclk = pclk_opt[1]; /* use default */
+
+ else if (!get_option_index(pclk_opt, hw->pclk)) {
+ printk(KERN_ERR "%s: CPU clock %u is illegal!\n",
+ modname, hw->pclk);
+ return -EINVAL;
+ }
+ printk(KERN_INFO "%s: assuming CPU clock rate of %u kHz.\n",
+ modname, hw->pclk);
+
+ /* Setup adapter dual-port memory window and test memory */
+ if (hw->dpmbase == 0) {
+ err = sdla_autodpm(hw);
+ if (err) {
+ printk(KERN_ERR
"%s: can't find available memory region!\n",
- modname)
- ;
- return err;
+ modname);
+ return err;
+ }
+ }
+ else if (!get_option_index(dpmbase_opt,
+ virt_to_phys(hw->dpmbase))) {
+ printk(KERN_ERR
+ "%s: memory address 0x%lX is illegal!\n",
+ modname, virt_to_phys(hw->dpmbase));
+ return -EINVAL;
+ }
+ else if (sdla_setdpm(hw)) {
+ printk(KERN_ERR
+ "%s: 8K memory region at 0x%lX is not available!\n",
+ modname, virt_to_phys(hw->dpmbase));
+ return -EINVAL;
+ }
+ printk(KERN_INFO
+ "%s: dual-port memory window is set at 0x%lX.\n",
+ modname, virt_to_phys(hw->dpmbase));
+ }
+
+ else {
+ hw->memory = test_memregion((void*)hw->dpmbase,
+ MAX_SIZEOF_S514_MEMORY);
+ if(hw->memory < (256 * 1024)) {
+ printk(KERN_ERR
+ "%s: error in testing S514 memory (0x%lX)\n",
+ modname, hw->memory);
+ sdla_down(hw);
+ return -EINVAL;
}
}
- else if (!get_option_index(dpmbase_opt, virt_to_phys(hw->dpmbase)))
- {
- printk(KERN_ERR "%s: memory address 0x%lX is illegal!\n",
- modname, virt_to_phys(hw->dpmbase))
- ;
- return -EINVAL;
- }
- else if (sdla_setdpm(hw))
- {
- printk(KERN_ERR
- "%s: 8K memory region at 0x%lX is not available!\n",
- modname, virt_to_phys(hw->dpmbase));
- return -EINVAL;
- }
- printk(KERN_INFO "%s: dual-port memory window is set at 0x%lX.\n",
- modname, virt_to_phys(hw->dpmbase));
-
- printk(KERN_INFO "%s: found %luK bytes of on-board memory.\n",
+
+ printk(KERN_INFO "%s: found %luK bytes of on-board memory\n",
modname, hw->memory / 1024);
/* Load firmware. If loader fails then shut down adapter */
err = sdla_load(hw, sfm, len);
if (err) sdla_down(hw); /* shutdown adapter */
+
return err;
}
@@ -454,11 +481,13 @@ int sdla_down (sdlahw_t* hw)
{
unsigned port = hw->port;
int i;
+ unsigned char CPU_no;
+ u32 int_config, int_status;
- if (!port) return -EFAULT;
+ if(!port && (hw->type != SDLA_S514))
+ return -EFAULT;
- switch (hw->type)
- {
+ switch (hw->type) {
case SDLA_S502A:
_OUTB(port, 0x08); /* halt CPU */
_OUTB(port, 0x08);
@@ -483,6 +512,30 @@ int sdla_down (sdlahw_t* hw)
hw->regs[0] = 0;
break;
+ case SDLA_S514:
+ /* halt the adapter */
+ *(char *)hw->vector = S514_CPU_HALT;
+ CPU_no = hw->S514_cpu_no[0];
+
+ /* disable the PCI IRQ and disable memory access */
+ pci_read_config_dword(hw->pci_dev, PCI_INT_CONFIG, &int_config);
+ int_config &= (CPU_no == S514_CPU_A) ? ~PCI_DISABLE_IRQ_CPU_A : ~PCI_DISABLE_IRQ_CPU_B;
+ pci_write_config_dword(hw->pci_dev, PCI_INT_CONFIG, int_config);
+ read_S514_int_stat(hw, &int_status);
+ S514_intack(hw, int_status);
+ if(CPU_no == S514_CPU_A)
+ pci_write_config_dword(hw->pci_dev, PCI_MAP0_DWORD,
+ PCI_CPU_A_MEM_DISABLE);
+ else
+ pci_write_config_dword(hw->pci_dev, PCI_MAP1_DWORD,
+ PCI_CPU_B_MEM_DISABLE);
+
+ /* free up the allocated virtual memory */
+ iounmap((void *)hw->dpmbase);
+ iounmap((void *)hw->vector);
+ break;
+
+
default:
return -EINVAL;
}
@@ -500,12 +553,10 @@ int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
unsigned port = hw->port;
register int tmp;
- switch (hw->type)
- {
+ switch (hw->type) {
case SDLA_S502A:
case SDLA_S502E:
- if (addr < S502_MAXMEM) /* verify parameter */
- {
+ if (addr < S502_MAXMEM) { /* verify parameter */
tmp = addr >> 13; /* convert to register mask */
_OUTB(port + 2, tmp);
hw->regs[2] = tmp;
@@ -514,8 +565,7 @@ int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
break;
case SDLA_S503:
- if (addr < S503_MAXMEM) /* verify parameter */
- {
+ if (addr < S503_MAXMEM) { /* verify parameter */
tmp = (hw->regs[0] & 0x8F) | ((addr >> 9) & 0x70);
_OUTB(port, tmp);
hw->regs[0] = tmp;
@@ -524,11 +574,9 @@ int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
break;
case SDLA_S507:
- if (addr < S507_MAXMEM)
- {
+ if (addr < S507_MAXMEM) {
if (!(_INB(port) & 0x02))
- return -EIO
- ;
+ return -EIO;
tmp = addr >> 13; /* convert to register mask */
_OUTB(port + 2, tmp);
hw->regs[2] = tmp;
@@ -537,8 +585,7 @@ int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
break;
case SDLA_S508:
- if (addr < S508_MAXMEM)
- {
+ if (addr < S508_MAXMEM) {
tmp = addr >> 13; /* convert to register mask */
_OUTB(port + 2, tmp);
hw->regs[2] = tmp;
@@ -546,7 +593,10 @@ int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
else return -EINVAL;
break;
- default:
+ case SDLA_S514:
+ return 0;
+
+ default:
return -EINVAL;
}
hw->vector = addr & 0xFFFFE000L;
@@ -556,7 +606,7 @@ int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
/*============================================================================
* Enable interrupt generation.
*/
-
+
EXPORT_SYMBOL(sdla_inten);
int sdla_inten (sdlahw_t* hw)
@@ -564,14 +614,12 @@ int sdla_inten (sdlahw_t* hw)
unsigned port = hw->port;
int tmp, i;
- switch (hw->type)
- {
+ switch (hw->type) {
case SDLA_S502E:
/* Note thar interrupt control operations on S502E are allowed
* only if CPU is enabled (bit 0 of status register is set).
*/
- if (_INB(port) & 0x01)
- {
+ if (_INB(port) & 0x01) {
_OUTB(port, 0x02); /* bit1 = 1, bit2 = 0 */
_OUTB(port, 0x06); /* bit1 = 1, bit2 = 1 */
hw->regs[0] = 0x06;
@@ -585,8 +633,7 @@ int sdla_inten (sdlahw_t* hw)
hw->regs[0] = tmp; /* update mirror */
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if (!(_INB(port) & 0x02)) /* verify */
- return -EIO
- ;
+ return -EIO;
break;
case SDLA_S508:
@@ -595,14 +642,16 @@ int sdla_inten (sdlahw_t* hw)
hw->regs[0] = tmp; /* update mirror */
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if (!(_INB(port + 1) & 0x10)) /* verify */
- return -EIO
- ;
+ return -EIO;
break;
case SDLA_S502A:
case SDLA_S507:
break;
+ case SDLA_S514:
+ break;
+
default:
return -EINVAL;
@@ -621,8 +670,7 @@ int sdla_intde (sdlahw_t* hw)
unsigned port = hw->port;
int tmp, i;
- switch (hw->type)
- {
+ switch (hw->type) {
case SDLA_S502E:
/* Notes:
* 1) interrupt control operations are allowed only if CPU is
@@ -631,8 +679,7 @@ int sdla_intde (sdlahw_t* hw)
* causes IRQ line go high, therefore we are going to use
* 0x04 instead: lower it to inhibit interrupts to PC.
*/
- if (_INB(port) & 0x01)
- {
+ if (_INB(port) & 0x01) {
_OUTB(port, hw->regs[0] & ~0x04);
hw->regs[0] &= ~0x04;
}
@@ -645,8 +692,7 @@ int sdla_intde (sdlahw_t* hw)
hw->regs[0] = tmp; /* update mirror */
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if (_INB(port) & 0x02) /* verify */
- return -EIO
- ;
+ return -EIO;
break;
case SDLA_S508:
@@ -655,8 +701,7 @@ int sdla_intde (sdlahw_t* hw)
hw->regs[0] = tmp; /* update mirror */
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if (_INB(port) & 0x10) /* verify */
- return -EIO
- ;
+ return -EIO;
break;
case SDLA_S502A:
@@ -680,16 +725,14 @@ int sdla_intack (sdlahw_t* hw)
unsigned port = hw->port;
int tmp;
- switch (hw->type)
- {
+ switch (hw->type) {
case SDLA_S502E:
/* To acknoledge hardware interrupt we have to toggle bit 3 of
* control register: \_/
* Note that interrupt control operations on S502E are allowed
* only if CPU is enabled (bit 1 of status register is set).
*/
- if (_INB(port) & 0x01)
- {
+ if (_INB(port) & 0x01) {
tmp = hw->regs[0] & ~0x04;
_OUTB(port, tmp);
tmp |= 0x04;
@@ -700,8 +743,7 @@ int sdla_intack (sdlahw_t* hw)
break;
case SDLA_S503:
- if (_INB(port) & 0x04)
- {
+ if (_INB(port) & 0x04) {
tmp = hw->regs[0] & ~0x08;
_OUTB(port, tmp);
tmp |= 0x08;
@@ -721,6 +763,31 @@ int sdla_intack (sdlahw_t* hw)
return 0;
}
+
+/*============================================================================
+ * Acknowledge S514 hardware interrupt.
+ */
+
+EXPORT_SYMBOL(S514_intack);
+
+void S514_intack (sdlahw_t* hw, u32 int_status)
+{
+ pci_write_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status);
+}
+
+
+/*============================================================================
+ * Read the S514 hardware interrupt status.
+ */
+
+EXPORT_SYMBOL(read_S514_int_stat);
+
+void read_S514_int_stat (sdlahw_t* hw, u32* int_status)
+{
+ pci_read_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status);
+}
+
+
/*============================================================================
* Generate an interrupt to adapter's CPU.
*/
@@ -731,11 +798,9 @@ int sdla_intr (sdlahw_t* hw)
{
unsigned port = hw->port;
- switch (hw->type)
- {
+ switch (hw->type) {
case SDLA_S502A:
- if (!(_INB(port) & 0x40))
- {
+ if (!(_INB(port) & 0x40)) {
_OUTB(port, 0x10); /* issue NMI to CPU */
hw->regs[0] = 0x10;
}
@@ -743,16 +808,14 @@ int sdla_intr (sdlahw_t* hw)
break;
case SDLA_S507:
- if ((_INB(port) & 0x06) == 0x06)
- {
+ if ((_INB(port) & 0x06) == 0x06) {
_OUTB(port + 3, 0);
}
else return -EIO;
break;
case SDLA_S508:
- if (_INB(port + 1) & 0x02)
- {
+ if (_INB(port + 1) & 0x02) {
_OUTB(port, 0x08);
}
else return -EIO;
@@ -781,14 +844,19 @@ int sdla_exec (void* opflag)
unsigned long tstop;
int nloops;
- if (*flag) return 0; /* ???? */
+ if(readb(flag) != 0x00) {
+ printk(KERN_INFO
+ "WANPIPE: opp flag set on entry to sdla_exec\n");
+ return 0;
+ }
+
+ writeb(0x01, flag);
- *flag = 1;
tstop = SYSTEM_TICK + EXEC_TIMEOUT;
- for (nloops = 1; *flag; ++nloops)
- {
+
+ for (nloops = 1; (readb(flag) == 0x01); ++ nloops) {
unsigned delay = exec_idle;
- while (--delay); /* delay */
+ while (-- delay); /* delay */
if (SYSTEM_TICK > tstop) return 0; /* time is up! */
}
return nloops;
@@ -803,39 +871,79 @@ int sdla_exec (void* opflag)
* This function is not atomic, so caller must disable interrupt if
* interrupt routines are accessing adapter shared memory.
*/
-
+
EXPORT_SYMBOL(sdla_peek);
int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
{
- unsigned long oldvec = hw->vector;
- unsigned winsize = hw->dpmsize;
- unsigned curpos, curlen; /* current offset and block size */
- unsigned long curvec; /* current DPM window vector */
- int err = 0;
if (addr + len > hw->memory) /* verify arguments */
- return -EINVAL
- ;
- while (len && !err)
- {
- curpos = addr % winsize; /* current window offset */
- curvec = addr - curpos; /* current window vector */
- curlen = (len > (winsize - curpos)) ? (winsize - curpos) : len;
-
- /* Relocate window and copy block of data */
- err = sdla_mapmem(hw, curvec);
- memcpy(buf, (void *)((u8 *)hw->dpmbase + curpos), curlen);
- addr += curlen;
- (char*)buf += curlen;
- len -= curlen;
+ return -EINVAL;
+
+ if(hw->type == SDLA_S514) { /* copy data for the S514 adapter */
+ peek_by_4 ((unsigned long)hw->dpmbase + addr, buf, len);
+ return 0;
}
- /* Restore DPM window position */
- sdla_mapmem(hw, oldvec);
- return err;
+ else { /* copy data for the S508 adapter */
+ unsigned long oldvec = hw->vector;
+ unsigned winsize = hw->dpmsize;
+ unsigned curpos, curlen; /* current offset and block size */
+ unsigned long curvec; /* current DPM window vector */
+ int err = 0;
+
+ while (len && !err) {
+ curpos = addr % winsize; /* current window offset */
+ curvec = addr - curpos; /* current window vector */
+ curlen = (len > (winsize - curpos)) ?
+ (winsize - curpos) : len;
+ /* Relocate window and copy block of data */
+ err = sdla_mapmem(hw, curvec);
+ peek_by_4 ((unsigned long)hw->dpmbase + curpos, buf,
+ curlen);
+ addr += curlen;
+ (char*)buf += curlen;
+ len -= curlen;
+ }
+
+ /* Restore DPM window position */
+ sdla_mapmem(hw, oldvec);
+ return err;
+ }
}
+
+/*============================================================================
+ * Read data from adapter's memory to a data buffer in 4-byte chunks.
+ * Note that we ensure that the SDLA memory address is on a 4-byte boundary
+ * before we begin moving the data in 4-byte chunks.
+*/
+
+static void peek_by_4 (unsigned long src, void* buf, unsigned len)
+{
+
+ /* byte copy data until we get to a 4-byte boundary */
+ while (len && (src & 0x03)) {
+ *(char *)buf ++ = readb(src ++);
+ len --;
+ }
+
+ /* copy data in 4-byte chunks */
+ while (len >= 4) {
+ *(unsigned long *)buf = readl(src);
+ buf += 4;
+ src += 4;
+ len -= 4;
+ }
+
+ /* byte copy any remaining data */
+ while (len) {
+ *(char *)buf ++ = readb(src ++);
+ len --;
+ }
+}
+
+
/*============================================================================
* Write Absolute Adapter Memory.
* Transfer data from data buffer to adapter's memory.
@@ -845,39 +953,79 @@ int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
* This function is not atomic, so caller must disable interrupt if
* interrupt routines are accessing adapter shared memory.
*/
-
+
EXPORT_SYMBOL(sdla_poke);
int sdla_poke (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
{
- unsigned long oldvec = hw->vector;
- unsigned winsize = hw->dpmsize;
- unsigned curpos, curlen; /* current offset and block size */
- unsigned long curvec; /* current DPM window vector */
- int err = 0;
if (addr + len > hw->memory) /* verify arguments */
- return -EINVAL
- ;
- while (len && !err)
- {
- curpos = addr % winsize; /* current window offset */
- curvec = addr - curpos; /* current window vector */
- curlen = (len > (winsize - curpos)) ? (winsize - curpos) : len;
-
- /* Relocate window and copy block of data */
- sdla_mapmem(hw, curvec);
- memcpy((void*)((u8 *)hw->dpmbase + curpos), buf, curlen);
- addr += curlen;
- (char*)buf += curlen;
- len -= curlen;
+ return -EINVAL;
+
+ if(hw->type == SDLA_S514) { /* copy data for the S514 adapter */
+ poke_by_4 ((unsigned long)hw->dpmbase + addr, buf, len);
+ return 0;
}
+
+ else { /* copy data for the S508 adapter */
+ unsigned long oldvec = hw->vector;
+ unsigned winsize = hw->dpmsize;
+ unsigned curpos, curlen; /* current offset and block size */
+ unsigned long curvec; /* current DPM window vector */
+ int err = 0;
+
+ while (len && !err) {
+ curpos = addr % winsize; /* current window offset */
+ curvec = addr - curpos; /* current window vector */
+ curlen = (len > (winsize - curpos)) ?
+ (winsize - curpos) : len;
+ /* Relocate window and copy block of data */
+ sdla_mapmem(hw, curvec);
+ poke_by_4 ((unsigned long)hw->dpmbase + curpos, buf,
+ curlen);
+ addr += curlen;
+ (char*)buf += curlen;
+ len -= curlen;
+ }
+
+ /* Restore DPM window position */
+ sdla_mapmem(hw, oldvec);
+ return err;
+ }
+}
- /* Restore DPM window position */
- sdla_mapmem(hw, oldvec);
- return err;
+
+/*============================================================================
+ * Write from a data buffer to adapter's memory in 4-byte chunks.
+ * Note that we ensure that the SDLA memory address is on a 4-byte boundary
+ * before we begin moving the data in 4-byte chunks.
+*/
+
+static void poke_by_4 (unsigned long dest, void* buf, unsigned len)
+{
+
+ /* byte copy data until we get to a 4-byte boundary */
+ while (len && (dest & 0x03)) {
+ writeb (*(char *)buf ++, dest ++);
+ len --;
+ }
+
+ /* copy data in 4-byte chunks */
+ while (len >= 4) {
+ writel (*(unsigned long *)buf, dest);
+ dest += 4;
+ buf += 4;
+ len -= 4;
+ }
+
+ /* byte copy any remaining data */
+ while (len) {
+ writeb (*(char *)buf ++ , dest ++);
+ len --;
+ }
}
+
#ifdef DONT_COMPIPLE_THIS
#endif /* DONT_COMPIPLE_THIS */
@@ -898,11 +1046,10 @@ static int sdla_detect (sdlahw_t* hw)
unsigned port = hw->port;
int err = 0;
- if (!port)
- return -EFAULT
- ;
- switch (hw->type)
- {
+ if (!port && (hw->type != SDLA_S514))
+ return -EFAULT;
+
+ switch (hw->type) {
case SDLA_S502A:
if (!detect_s502a(port)) err = -ENODEV;
break;
@@ -923,22 +1070,21 @@ static int sdla_detect (sdlahw_t* hw)
if (!detect_s508(port)) err = -ENODEV;
break;
+ case SDLA_S514:
+ if (!detect_s514(hw)) err = -ENODEV;
+ break;
+
default:
if (detect_s502a(port))
- hw->type = SDLA_S502A
- ;
+ hw->type = SDLA_S502A;
else if (detect_s502e(port))
- hw->type = SDLA_S502E
- ;
+ hw->type = SDLA_S502E;
else if (detect_s503(port))
- hw->type = SDLA_S503
- ;
+ hw->type = SDLA_S503;
else if (detect_s507(port))
- hw->type = SDLA_S507
- ;
+ hw->type = SDLA_S507;
else if (detect_s508(port))
- hw->type = SDLA_S508
- ;
+ hw->type = SDLA_S508;
else err = -ENODEV;
}
return err;
@@ -953,8 +1099,7 @@ static int sdla_autodpm (sdlahw_t* hw)
int i, err = -EINVAL;
unsigned* opt;
- switch (hw->type)
- {
+ switch (hw->type) {
case SDLA_S502A:
opt = s502a_dpmbase_options;
break;
@@ -973,8 +1118,7 @@ static int sdla_autodpm (sdlahw_t* hw)
return -EINVAL;
}
- for (i = opt[0]; i && err; --i)
- {
+ for (i = opt[0]; i && err; --i) {
hw->dpmbase = phys_to_virt(opt[i]);
err = sdla_setdpm(hw);
}
@@ -997,8 +1141,7 @@ static int sdla_setdpm (sdlahw_t* hw)
/* Shut down card and verify memory region */
sdla_down(hw);
if (check_memregion(hw->dpmbase, hw->dpmsize))
- return -EINVAL
- ;
+ return -EINVAL;
/* Initialize adapter and test on-board memory segment by segment.
* If memory size appears to be less than shared memory window size,
@@ -1007,8 +1150,7 @@ static int sdla_setdpm (sdlahw_t* hw)
err = sdla_init(hw);
if (err) return err;
- if (sdla_memtest(hw) < hw->dpmsize) /* less than window size */
- {
+ if (sdla_memtest(hw) < hw->dpmsize) { /* less than window size */
sdla_down(hw);
return -EIO;
}
@@ -1023,32 +1165,28 @@ static int sdla_setdpm (sdlahw_t* hw)
*/
static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len)
{
+
int i;
/* Verify firmware signature */
- if (strcmp(sfm->signature, SFM_SIGNATURE))
- {
+ if (strcmp(sfm->signature, SFM_SIGNATURE)) {
printk(KERN_ERR "%s: not SDLA firmware!\n",
- modname)
- ;
+ modname);
return -EINVAL;
}
/* Verify firmware module format version */
- if (sfm->version != SFM_VERSION)
- {
+ if (sfm->version != SFM_VERSION) {
printk(KERN_ERR
"%s: firmware format %u rejected! Expecting %u.\n",
- modname, sfm->version, SFM_VERSION)
- ;
+ modname, sfm->version, SFM_VERSION);
return -EINVAL;
}
/* Verify firmware module length and checksum */
if ((len - offsetof(sfm_t, image) != sfm->info.codesize) ||
(checksum((void*)&sfm->info,
- sizeof(sfm_info_t) + sfm->info.codesize) != sfm->checksum))
- {
+ sizeof(sfm_info_t) + sfm->info.codesize) != sfm->checksum)) {
printk(KERN_ERR "%s: firmware corrupted!\n", modname);
return -EINVAL;
}
@@ -1056,8 +1194,11 @@ static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len)
/* Announce */
printk(KERN_INFO "%s: loading %s (ID=%u)...\n", modname,
(sfm->descr[0] != '\0') ? sfm->descr : "unknown firmware",
- sfm->info.codeid)
- ;
+ sfm->info.codeid);
+
+ if(hw->type == SDLA_S514)
+ printk(KERN_INFO "%s: loading S514 adapter, CPU %c\n",
+ modname, hw->S514_cpu_no[0]);
/* Scan through the list of compatible adapters and make sure our
* adapter type is listed.
@@ -1066,49 +1207,41 @@ static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len)
(i < SFM_MAX_SDLA) && (sfm->info.adapter[i] != hw->type);
++i)
;
- if (i == SFM_MAX_SDLA)
- {
+ if (i == SFM_MAX_SDLA) {
printk(KERN_ERR "%s: firmware is not compatible with S%u!\n",
- modname, hw->type)
+ modname, hw->type);
;
return -EINVAL;
}
+
/* Make sure there is enough on-board memory */
- if (hw->memory < sfm->info.memsize)
- {
+ if (hw->memory < sfm->info.memsize) {
printk(KERN_ERR
"%s: firmware needs %lu bytes of on-board memory!\n",
- modname, sfm->info.memsize)
- ;
+ modname, sfm->info.memsize);
return -EINVAL;
}
/* Move code onto adapter */
- if (sdla_poke(hw, sfm->info.codeoffs, sfm->image, sfm->info.codesize))
- {
+ if (sdla_poke(hw, sfm->info.codeoffs, sfm->image, sfm->info.codesize)) {
printk(KERN_ERR "%s: failed to load code segment!\n",
- modname)
- ;
+ modname);
return -EIO;
}
/* Prepare boot-time configuration data and kick-off CPU */
sdla_bootcfg(hw, &sfm->info);
- if (sdla_start(hw, sfm->info.startoffs))
- {
+ if (sdla_start(hw, sfm->info.startoffs)) {
printk(KERN_ERR "%s: Damn... Adapter won't start!\n",
- modname)
- ;
+ modname);
return -EIO;
}
/* position DPM window over the mailbox and enable interrupts */
- if (sdla_mapmem(hw, sfm->info.winoffs) || sdla_inten(hw))
- {
+ if (sdla_mapmem(hw, sfm->info.winoffs) || sdla_inten(hw)) {
printk(KERN_ERR "%s: adapter hardware failure!\n",
- modname)
- ;
+ modname);
return -EIO;
}
hw->fwid = sfm->info.codeid; /* set firmware ID */
@@ -1123,10 +1256,9 @@ static int sdla_init (sdlahw_t* hw)
int i;
for (i = 0; i < SDLA_MAXIORANGE; ++i)
- hw->regs[i] = 0
- ;
- switch (hw->type)
- {
+ hw->regs[i] = 0;
+
+ switch (hw->type) {
case SDLA_S502A: return init_s502a(hw);
case SDLA_S502E: return init_s502e(hw);
case SDLA_S503: return init_s503(hw);
@@ -1169,23 +1301,28 @@ static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo)
if (!sfminfo->datasize) return 0; /* nothing to do */
if (sdla_mapmem(hw, sfminfo->dataoffs) != 0)
- return -EIO
- ;
- data = (void*)((u8 *)hw->dpmbase + (sfminfo->dataoffs - hw->vector));
- memset(data, 0, sfminfo->datasize);
+ return -EIO;
+
+ if(hw->type == SDLA_S514)
+ data = (void*)(hw->dpmbase + sfminfo->dataoffs);
+ else
+ data = (void*)((u8 *)hw->dpmbase +
+ (sfminfo->dataoffs - hw->vector));
+
+ memset_io (data, 0, sfminfo->datasize);
- data[0x00] = make_config_byte(hw);
- switch (sfminfo->codeid)
- {
+ writeb (make_config_byte(hw), &data[0x00]);
+
+ switch (sfminfo->codeid) {
case SFID_X25_502:
case SFID_X25_508:
- data[0x01] = 3; /* T1 timer */
- data[0x03] = 10; /* N2 */
- data[0x06] = 7; /* HDLC window size */
- data[0x0B] = 1; /* DTE */
- data[0x0C] = 2; /* X.25 packet window size */
- *(short*)&data[0x0D] = 128; /* default X.25 data size */
- *(short*)&data[0x0F] = 128; /* maximum X.25 data size */
+ writeb (3, &data[0x01]); /* T1 timer */
+ writeb (10, &data[0x03]); /* N2 */
+ writeb (7, &data[0x06]); /* HDLC window size */
+ writeb (1, &data[0x0B]); /* DTE */
+ writeb (2, &data[0x0C]); /* X.25 packet window size */
+ writew (128, &data[0x0D]); /* default X.25 data size */
+ writew (128, &data[0x0F]); /* maximum X.25 data size */
break;
}
return 0;
@@ -1198,16 +1335,15 @@ static unsigned char make_config_byte (sdlahw_t* hw)
{
unsigned char byte = 0;
- switch (hw->pclk)
- {
+ switch (hw->pclk) {
case 5000: byte = 0x01; break;
case 7200: byte = 0x02; break;
case 8000: byte = 0x03; break;
case 10000: byte = 0x04; break;
case 16000: byte = 0x05; break;
}
- switch (hw->type)
- {
+
+ switch (hw->type) {
case SDLA_S502E: byte |= 0x80; break;
case SDLA_S503: byte |= 0x40; break;
}
@@ -1227,10 +1363,9 @@ static int sdla_start (sdlahw_t* hw, unsigned addr)
unsigned char *bootp;
int err, tmp, i;
- if (!port) return -EFAULT;
+ if (!port && (hw->type != SDLA_S514)) return -EFAULT;
- switch (hw->type)
- {
+ switch (hw->type) {
case SDLA_S502A:
bootp = hw->dpmbase;
bootp += 0x66;
@@ -1240,6 +1375,7 @@ static int sdla_start (sdlahw_t* hw, unsigned addr)
case SDLA_S503:
case SDLA_S507:
case SDLA_S508:
+ case SDLA_S514:
bootp = hw->dpmbase;
break;
@@ -1250,12 +1386,11 @@ static int sdla_start (sdlahw_t* hw, unsigned addr)
err = sdla_mapmem(hw, 0);
if (err) return err;
- *bootp = 0xC3; /* Z80: 'jp' opcode */
- bootp++;
- *((unsigned short*)(bootp)) = addr;
+ writeb (0xC3, bootp); /* Z80: 'jp' opcode */
+ bootp ++;
+ writew (addr, bootp);
- switch (hw->type)
- {
+ switch (hw->type) {
case SDLA_S502A:
_OUTB(port, 0x10); /* issue NMI to CPU */
hw->regs[0] = 0x10;
@@ -1265,8 +1400,7 @@ static int sdla_start (sdlahw_t* hw, unsigned addr)
_OUTB(port + 3, 0x01); /* start CPU */
hw->regs[3] = 0x01;
for (i = 0; i < SDLA_IODELAY; ++i);
- if (_INB(port) & 0x01) /* verify */
- {
+ if (_INB(port) & 0x01) { /* verify */
/*
* Enabling CPU changes functionality of the
* control register, so we have to reset its
@@ -1284,8 +1418,7 @@ static int sdla_start (sdlahw_t* hw, unsigned addr)
hw->regs[0] = tmp; /* update mirror */
for (i = 0; i < SDLA_IODELAY; ++i);
if (!(_INB(port) & 0x01)) /* verify */
- return -EIO
- ;
+ return -EIO;
break;
case SDLA_S507:
@@ -1294,8 +1427,7 @@ static int sdla_start (sdlahw_t* hw, unsigned addr)
hw->regs[0] = tmp; /* update mirror */
for (i = 0; i < SDLA_IODELAY; ++i);
if (!(_INB(port) & 0x04)) /* verify */
- return -EIO
- ;
+ return -EIO;
break;
case SDLA_S508:
@@ -1304,8 +1436,11 @@ static int sdla_start (sdlahw_t* hw, unsigned addr)
hw->regs[0] = tmp; /* update mirror */
for (i = 0; i < SDLA_IODELAY; ++i);
if (!(_INB(port + 1) & 0x02)) /* verify */
- return -EIO
- ;
+ return -EIO;
+ break;
+
+ case SDLA_S514:
+ writeb (S514_CPU_START, hw->vector);
break;
default:
@@ -1323,20 +1458,18 @@ static int init_s502a (sdlahw_t* hw)
int tmp, i;
if (!detect_s502a(port))
- return -ENODEV
- ;
+ return -ENODEV;
+
hw->regs[0] = 0x08;
hw->regs[1] = 0xFF;
/* Verify configuration options */
i = get_option_index(s502a_dpmbase_options, virt_to_phys(hw->dpmbase));
if (i == 0)
- return -EINVAL
- ;
+ return -EINVAL;
tmp = s502a_hmcr[i - 1];
- switch (hw->dpmsize)
- {
+ switch (hw->dpmsize) {
case 0x2000:
tmp |= 0x01;
break;
@@ -1364,18 +1497,15 @@ static int init_s502e (sdlahw_t* hw)
int tmp, i;
if (!detect_s502e(port))
- return -ENODEV
- ;
+ return -ENODEV;
/* Verify configuration options */
i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
if (i == 0)
- return -EINVAL
- ;
+ return -EINVAL;
tmp = s502e_hmcr[i - 1];
- switch (hw->dpmsize)
- {
+ switch (hw->dpmsize) {
case 0x2000:
tmp |= 0x01;
break;
@@ -1408,18 +1538,15 @@ static int init_s503 (sdlahw_t* hw)
int tmp, i;
if (!detect_s503(port))
- return -ENODEV
- ;
+ return -ENODEV;
/* Verify configuration options */
i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
if (i == 0)
- return -EINVAL
- ;
+ return -EINVAL;
tmp = s502e_hmcr[i - 1];
- switch (hw->dpmsize)
- {
+ switch (hw->dpmsize) {
case 0x2000:
tmp |= 0x01;
break;
@@ -1450,18 +1577,15 @@ static int init_s507 (sdlahw_t* hw)
int tmp, i;
if (!detect_s507(port))
- return -ENODEV
- ;
+ return -ENODEV;
/* Verify configuration options */
i = get_option_index(s507_dpmbase_options, virt_to_phys(hw->dpmbase));
if (i == 0)
- return -EINVAL
- ;
+ return -EINVAL;
tmp = s507_hmcr[i - 1];
- switch (hw->dpmsize)
- {
+ switch (hw->dpmsize) {
case 0x2000:
tmp |= 0x01;
break;
@@ -1478,8 +1602,7 @@ static int init_s507 (sdlahw_t* hw)
hw->regs[0] = 0x01;
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if (!(_INB(port) & 0x20))
- return -EIO
- ;
+ return -EIO;
/* Setup dual-port memory window */
_OUTB(port + 1, tmp);
@@ -1487,8 +1610,7 @@ static int init_s507 (sdlahw_t* hw)
/* Enable memory access */
tmp = hw->regs[0] | 0x04;
- if (hw->irq)
- {
+ if (hw->irq) {
i = get_option_index(s508_irq_options, hw->irq);
if (i) tmp |= s507_irqmask[i - 1];
}
@@ -1507,14 +1629,12 @@ static int init_s508 (sdlahw_t* hw)
int tmp, i;
if (!detect_s508(port))
- return -ENODEV
- ;
+ return -ENODEV;
/* Verify configuration options */
i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
if (i == 0)
- return -EINVAL
- ;
+ return -EINVAL;
/* Setup memory configuration */
tmp = s508_hmcr[i - 1];
@@ -1547,13 +1667,11 @@ static int detect_s502a (int port)
int i, j;
if (!get_option_index(s502_port_options, port))
- return 0
- ;
- for (j = 1; j < SDLA_MAXIORANGE; ++j)
- {
+ return 0;
+
+ for (j = 1; j < SDLA_MAXIORANGE; ++j) {
if (_INB(port + j) != 0xFF)
- return 0
- ;
+ return 0;
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
}
@@ -1562,18 +1680,15 @@ static int detect_s502a (int port)
_OUTB(port, 0x08);
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if (_INB(port) != 0x40)
- return 0
- ;
+ return 0;
_OUTB(port, 0x00);
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if (_INB(port) != 0x40)
- return 0
- ;
+ return 0;
_OUTB(port, 0x04);
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if (_INB(port) != 0x44)
- return 0
- ;
+ return 0;
/* Reset adapter */
_OUTB(port, 0x08);
@@ -1600,26 +1715,21 @@ static int detect_s502e (int port)
int i, j;
if (!get_option_index(s502_port_options, port))
- return 0
- ;
- for (j = 1; j < SDLA_MAXIORANGE; ++j)
- {
+ return 0;
+ for (j = 1; j < SDLA_MAXIORANGE; ++j) {
if (_INB(port + j) != 0xFF)
- return 0
- ;
+ return 0;
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
}
_OUTB(port + 3, 0); /* CPU control reg. */
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if (_INB(port) != 0xF8) /* read status */
- return 0
- ;
+ return 0;
_OUTB(port, 0x04); /* set bit 2 */
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if (_INB(port) != 0xFC) /* verify */
- return 0
- ;
+ return 0;
/* Reset adapter */
_OUTB(port, 0);
@@ -1643,26 +1753,21 @@ static int detect_s503 (int port)
int i, j;
if (!get_option_index(s503_port_options, port))
- return 0
- ;
- for (j = 1; j < SDLA_MAXIORANGE; ++j)
- {
+ return 0;
+ for (j = 1; j < SDLA_MAXIORANGE; ++j) {
if (_INB(port + j) != 0xFF)
- return 0
- ;
+ return 0;
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
}
_OUTB(port, 0); /* reset control reg.*/
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if (_INB(port) != 0xF0) /* read status */
- return 0
- ;
+ return 0;
_OUTB(port, 0x04); /* set bit 2 */
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if (_INB(port) != 0xF2) /* verify */
- return 0
- ;
+ return 0;
/* Reset adapter */
_OUTB(port, 0);
@@ -1686,27 +1791,22 @@ static int detect_s507 (int port)
int tmp, i, j;
if (!get_option_index(s508_port_options, port))
- return 0
- ;
+ return 0;
tmp = _INB(port);
- for (j = 1; j < S507_IORANGE; ++j)
- {
+ for (j = 1; j < S507_IORANGE; ++j) {
if (_INB(port + j) != tmp)
- return 0
- ;
+ return 0;
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
}
_OUTB(port, 0x00);
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if ((_INB(port) & 0x7E) != 0x30)
- return 0
- ;
+ return 0;
_OUTB(port, 0x01);
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if ((_INB(port) & 0x7E) != 0x32)
- return 0
- ;
+ return 0;
/* Reset adapter */
_OUTB(port, 0x00);
@@ -1729,24 +1829,205 @@ static int detect_s508 (int port)
int i;
if (!get_option_index(s508_port_options, port))
- return 0
- ;
+ return 0;
_OUTB(port, 0x00);
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if ((_INB(port + 1) & 0x3F) != 0x00)
- return 0
- ;
+ return 0;
_OUTB(port, 0x10);
for (i = 0; i < SDLA_IODELAY; ++i); /* delay */
if ((_INB(port + 1) & 0x3F) != 0x10)
- return 0
- ;
+ return 0;
/* Reset adapter */
_OUTB(port, 0x00);
return 1;
}
+/*============================================================================
+ * Detect s514 PCI adapter.
+ * Return 1 if detected o.k. or 0 if failed.
+ * Note: This test is destructive! Adapter will be left in shutdown
+ * state after the test.
+ */
+static int detect_s514 (sdlahw_t* hw)
+{
+ unsigned char CPU_no, slot_no;
+ int number_S514_cards = 0;
+ u32 S514_mem_base_addr = 0;
+ u32 ut_u32;
+
+ struct pci_dev *pci_dev;
+
+
+#ifdef CONFIG_PCI
+ if(!pci_present())
+ {
+ printk(KERN_ERR "%s: PCI BIOS not present!\n", modname);
+ return 0;
+ }
+#else
+ printk(KERN_ERR "%s: Linux not compiled for PCI usage!\n", modname);
+ return 0;
+#endif
+
+ /*
+ The 'setup()' procedure in 'sdlamain.c' passes the CPU number and the
+ slot number defined in 'router.conf' via the 'port' definition.
+ */
+ CPU_no = hw->S514_cpu_no[0];
+ slot_no = hw->S514_slot_no;
+
+ printk(KERN_INFO "%s: detecting S514 card, CPU %c, slot #%d\n",
+ modname, CPU_no, slot_no);
+
+ /* check to see that CPU A or B has been selected in 'router.conf' */
+ switch(CPU_no) {
+ case S514_CPU_A:
+ case S514_CPU_B:
+ break;
+
+ default:
+ printk(KERN_ERR "%s: S514 CPU definition invalid.\n",
+ modname);
+ printk(KERN_ERR "Must be 'A' or 'B'\n");
+ return 0;
+ }
+
+ number_S514_cards = find_s514_adapter(hw, 0);
+ if(!number_S514_cards)
+ return 0;
+
+ /* we are using a single S514 adapter with a slot of 0 so re-read the */ /* location of this adapter */
+ if((number_S514_cards == 1) && !slot_no) {
+ number_S514_cards = find_s514_adapter(hw, 1);
+ if(!number_S514_cards) {
+ printk(KERN_ERR "%s: Error finding PCI card\n",
+ modname);
+ return 0;
+ }
+ }
+
+ pci_dev = hw->pci_dev;
+ /* read the physical memory base address */
+ S514_mem_base_addr = (CPU_no == S514_CPU_A) ?
+ (pci_dev->resource[1].start) :
+ (pci_dev->resource[2].start);
+
+ printk(KERN_INFO "%s: S514 PCI memory at 0x%X\n",
+ modname, S514_mem_base_addr);
+ if(!S514_mem_base_addr) {
+ if(CPU_no == S514_CPU_B)
+ printk(KERN_ERR "%s: CPU #B not present on the card\n", modname);
+ else
+ printk(KERN_ERR "%s: No PCI memory allocated to card\n", modname);
+ return 0;
+ }
+
+ /* enable the PCI memory */
+ pci_read_config_dword(pci_dev,
+ (CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD,
+ &ut_u32);
+ pci_write_config_dword(pci_dev,
+ (CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD,
+ (ut_u32 | PCI_MEMORY_ENABLE));
+
+ /* check the IRQ allocated and enable IRQ usage */
+ if(!(hw->irq = pci_dev->irq)) {
+ printk(KERN_ERR "%s: IRQ not allocated to S514 adapter\n",
+ modname);
+ return 0;
+ }
+ pci_read_config_dword(pci_dev, PCI_INT_CONFIG, &ut_u32);
+ ut_u32 |= (CPU_no == S514_CPU_A) ?
+ PCI_ENABLE_IRQ_CPU_A : PCI_ENABLE_IRQ_CPU_B;
+ pci_write_config_dword(pci_dev, PCI_INT_CONFIG, ut_u32);
+
+ printk(KERN_INFO "%s: IRQ %d allocated to the S514 card\n",
+ modname, hw->irq);
+
+ /* map the physical PCI memory to virtual memory */
+ (void *)hw->dpmbase = ioremap((unsigned long)S514_mem_base_addr,
+ (unsigned long)MAX_SIZEOF_S514_MEMORY);
+ /* map the physical control register memory to virtual memory */
+ (void *)hw->vector = ioremap(
+ (unsigned long)(S514_mem_base_addr + S514_CTRL_REG_BYTE),
+ (unsigned long)16);
+
+ if(!hw->dpmbase || !hw->vector) {
+ printk(KERN_ERR "%s: PCI virtual memory allocation failed\n",
+ modname);
+ return 0;
+ }
+
+ /* halt the adapter */
+ writeb (S514_CPU_HALT, hw->vector);
+
+ return 1;
+}
+
+/*============================================================================
+ * Find the S514 PCI adapter in the PCI bus.
+ * Return the number of S514 adapters found (0 if no adapter found).
+ */
+static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card)
+{
+ unsigned char slot_no;
+ int number_S514_cards = 0;
+ char S514_found_in_slot = 0;
+ u16 PCI_subsys_vendor;
+
+ struct pci_dev *pci_dev = NULL;
+
+ slot_no = hw->S514_slot_no;
+
+ while ((pci_dev = pci_find_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev))
+ != NULL) {
+ pci_read_config_word(pci_dev, PCI_SUBSYS_VENDOR_WORD,
+ &PCI_subsys_vendor);
+ if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR)
+ continue;
+ hw->pci_dev = pci_dev;
+ if(find_first_S514_card)
+ return(1);
+ number_S514_cards ++;
+ printk(KERN_INFO
+ "%s: S514 card found, slot #%d (devfn 0x%X)\n",
+ modname, ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK),
+ pci_dev->devfn);
+ if(slot_no && (((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK) ==
+ slot_no)) {
+ S514_found_in_slot = 1;
+ break;
+ }
+ }
+
+ /* if no S514 adapter has been found, then exit */
+ if(!number_S514_cards) {
+ printk(KERN_ERR "%s: no S514 adapters found\n", modname);
+ return 0;
+ }
+ /* if more than one S514 card has been found, then the user must have */ /* defined a slot number so that the correct adapter is used */
+ else if((number_S514_cards > 1) && !slot_no) {
+ printk(KERN_ERR "%s: More than one S514 adapter found\n",
+ modname);
+ printk(KERN_ERR "Define a PCI slot number for this adapter\n");
+ return 0;
+ }
+ /* if the user has specified a slot number and the S514 adapter has */
+ /* not been found in that slot, then exit */
+ else if (slot_no && !S514_found_in_slot) {
+ printk(KERN_ERR
+ "%s: S514 card not found in specified slot #%d\n",
+ modname, slot_no);
+ return 0;
+ }
+
+ return (number_S514_cards);
+}
+
+
+
/******* Miscellaneous ******************************************************/
/*============================================================================
@@ -1772,8 +2053,8 @@ static int get_option_index (unsigned* optlist, unsigned optval)
int i;
for (i = 1; i <= optlist[0]; ++i)
- if ( optlist[i] == optval) return i
- ;
+ if ( optlist[i] == optval)
+ return i;
return 0;
}
@@ -1785,15 +2066,14 @@ static unsigned check_memregion (void* ptr, unsigned len)
{
volatile unsigned char* p = ptr;
- for (; len && (*p == 0xFF); --len, ++p)
- {
- *p = 0; /* attempt to write 0 */
- if (*p != 0xFF) /* still has to read 0xFF */
- {
- *p = 0xFF; /* restore original value */
- break; /* not good */
- }
- }
+ for (; len && (readb (p) == 0xFF); --len, ++p) {
+ writeb (0, p); /* attempt to write 0 */
+ if (readb(p) != 0xFF) { /* still has to read 0xFF */
+ writeb (0xFF, p);/* restore original value */
+ break; /* not good */
+ }
+ }
+
return len;
}
@@ -1808,28 +2088,28 @@ static unsigned test_memregion (void* ptr, unsigned len)
unsigned len_w = len >> 1; /* region len in words */
unsigned i;
+ for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
+ writew (0xAA55, w_ptr);
+
for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
- *w_ptr = 0xAA55
- ;
- for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
- if (*w_ptr != 0xAA55)
- {
- len_w = i;
- break;
- }
- ;
- for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
- *w_ptr = 0x55AA
- ;
- for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
- if (*w_ptr != 0x55AA)
- {
- len_w = i;
- break;
- }
- ;
- for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr) *w_ptr = 0;
- return len_w << 1;
+ if (readw (w_ptr) != 0xAA55) {
+ len_w = i;
+ break;
+ }
+
+ for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
+ writew (0x55AA, w_ptr);
+
+ for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
+ if (readw(w_ptr) != 0x55AA) {
+ len_w = i;
+ break;
+ }
+
+ for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
+ writew (0, w_ptr);
+
+ return len_w << 1;
}
/*============================================================================
@@ -1840,10 +2120,8 @@ static unsigned short checksum (unsigned char* buf, unsigned len)
unsigned short crc = 0;
unsigned mask, flag;
- for (; len; --len, ++buf)
- {
- for (mask = 0x80; mask; mask >>= 1)
- {
+ for (; len; --len, ++buf) {
+ for (mask = 0x80; mask; mask >>= 1) {
flag = (crc & 0x8000);
crc <<= 1;
crc |= ((*buf & mask) ? 1 : 0);
diff --git a/drivers/net/wan/sdlamain.c b/drivers/net/wan/sdlamain.c
index 23b811fc9..3565954e1 100644
--- a/drivers/net/wan/sdlamain.c
+++ b/drivers/net/wan/sdlamain.c
@@ -1,18 +1,21 @@
/*****************************************************************************
* sdlamain.c WANPIPE(tm) Multiprotocol WAN Link Driver. Main module.
*
-* Author: Gene Kozin <genek@compuserve.com>
-* Jaspreet Singh <jaspreet@sangoma.com>
-* Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+* Author: Nenad Corbic <ncorbic@sangoma.com>
+* Gideon Hack
*
-* Copyright: (c) 1995-1997 Sangoma Technologies Inc.
+* Copyright: (c) 1995-1999 Sangoma Technologies 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.
* ============================================================================
-* May 19, 1999 Arnaldo Melo __init for wanpipe_init
+* Sep 23, 1999 Nenad Corbic Added support for SMP
+* Sep 13, 1999 Nenad Corbic Each port is treated as a separate device.
+* Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
+* Updates for Linux 2.2.X kernels.
+* Sep 17, 1998 Jaspreet Singh Updated for 2.1.121+ kernel
* Nov 28, 1997 Jaspreet Singh Changed DRV_RELEASE to 1
* Nov 10, 1997 Jaspreet Singh Changed sti() to restore_flags();
* Nov 06, 1997 Jaspreet Singh Changed DRV_VERSION to 4 and DRV_RELEASE to 0
@@ -31,6 +34,7 @@
* Jan 02, 1997 Gene Kozin Initial version.
*****************************************************************************/
+#include <linux/version.h>
#include <linux/config.h> /* OS configuration options */
#include <linux/stddef.h> /* offsetof(), etc. */
#include <linux/errno.h> /* return codes */
@@ -44,8 +48,8 @@
#include <linux/wanpipe.h> /* WANPIPE common user API definitions */
#include <asm/uaccess.h> /* kernel <-> user copy */
#include <asm/io.h> /* phys_to_virt() */
-#include <linux/init.h> /* __init (when not using as a module) */
-
+#include <linux/pci.h>
+#include <linux/sdlapci.h>
/****** Defines & Macros ****************************************************/
@@ -55,8 +59,8 @@
#define STATIC static
#endif
-#define DRV_VERSION 4 /* version number */
-#define DRV_RELEASE 1 /* release (minor version) number */
+#define DRV_VERSION 5 /* version number */
+#define DRV_RELEASE 0 /* release (minor version) number */
#define MAX_CARDS 8 /* max number of adapters */
#ifndef CONFIG_WANPIPE_CARDS /* configurable option */
@@ -66,9 +70,11 @@
#define CMD_OK 0 /* normal firmware return code */
#define CMD_TIMEOUT 0xFF /* firmware command timed out */
#define MAX_CMD_RETRY 10 /* max number of firmware retries */
-
/****** Function Prototypes *************************************************/
+extern void disable_irq(unsigned int);
+extern void enable_irq(unsigned int);
+
/* Module entry points */
int init_module (void);
void cleanup_module (void);
@@ -78,13 +84,14 @@ static int setup (wan_device_t* wandev, wandev_conf_t* conf);
static int shutdown (wan_device_t* wandev);
static int ioctl (wan_device_t* wandev, unsigned cmd, unsigned long arg);
-/* IOCTL hanlers */
+/* IOCTL handlers */
static int ioctl_dump (sdla_t* card, sdla_dump_t* u_dump);
static int ioctl_exec (sdla_t* card, sdla_exec_t* u_exec);
/* Miscellaneous functions */
STATIC void sdla_isr (int irq, void* dev_id, struct pt_regs *regs);
STATIC void sdla_poll (void* data);
+static void release_hw (sdla_t *card);
/****** Global Data **********************************************************
* Note: All data must be explicitly initialized!!!
@@ -93,7 +100,7 @@ STATIC void sdla_poll (void* data);
/* private data */
static char drvname[] = "wanpipe";
static char fullname[] = "WANPIPE(tm) Multiprotocol Driver";
-static char copyright[] = "(c) 1995-1996 Sangoma Technologies Inc.";
+static char copyright[] = "(c) 1995-1999 Sangoma Technologies Inc.";
static int ncards = CONFIG_WANPIPE_CARDS;
static int active = 0; /* number of active cards */
static sdla_t* card_array = NULL; /* adapter data space */
@@ -107,6 +114,7 @@ static struct tq_struct sdla_tq =
NULL /* .data */
};
+
/******* Kernel Loadable Module Entry Points ********************************/
/*============================================================================
@@ -125,30 +133,29 @@ static struct tq_struct sdla_tq =
#ifdef MODULE
int init_module (void)
#else
-int __init wanpipe_init(void)
+int wanpipe_init2(void)
#endif
{
int cnt, err = 0;
printk(KERN_INFO "%s v%u.%u %s\n",
- fullname, DRV_VERSION, DRV_RELEASE, copyright)
- ;
+ fullname, DRV_VERSION, DRV_RELEASE, copyright);
/* Verify number of cards and allocate adapter data space */
ncards = min(ncards, MAX_CARDS);
ncards = max(ncards, 1);
card_array = kmalloc(sizeof(sdla_t) * ncards, GFP_KERNEL);
if (card_array == NULL)
- return -ENOMEM
- ;
+ return -ENOMEM;
+
memset(card_array, 0, sizeof(sdla_t) * ncards);
/* Register adapters with WAN router */
- for (cnt = 0; cnt < ncards; ++cnt)
- {
+ for (cnt = 0; cnt < ncards; ++ cnt) {
sdla_t* card = &card_array[cnt];
wan_device_t* wandev = &card->wandev;
+ card->next = NULL;
sprintf(card->devname, "%s%d", drvname, cnt + 1);
wandev->magic = ROUTER_MAGIC;
wandev->name = card->devname;
@@ -158,20 +165,18 @@ int __init wanpipe_init(void)
wandev->shutdown = &shutdown;
wandev->ioctl = &ioctl;
err = register_wan_device(wandev);
- if (err)
- {
+ if (err) {
printk(KERN_ERR
"%s: %s registration failed with error %d!\n",
- drvname, card->devname, err)
- ;
+ drvname, card->devname, err);
break;
}
}
- if (cnt)
+ if (cnt){
ncards = cnt; /* adjust actual number of cards */
- else
- {
+ }else {
kfree(card_array);
+ printk(KERN_INFO "IN Init Module: NO Cards registered\n");
err = -ENODEV;
}
return err;
@@ -187,8 +192,7 @@ void cleanup_module (void)
{
int i;
- for (i = 0; i < ncards; ++i)
- {
+ for (i = 0; i < ncards; ++i) {
sdla_t* card = &card_array[i];
unregister_wan_device(card->devname);
}
@@ -200,7 +204,7 @@ void cleanup_module (void)
/******* WAN Device Driver Entry Points *************************************/
/*============================================================================
- * Setup/confugure WAN link driver.
+ * Setup/configure WAN link driver.
* o check adapter state
* o make sure firmware is present in configuration
* o make sure I/O port and IRQ are specified
@@ -220,7 +224,8 @@ static int setup (wan_device_t* wandev, wandev_conf_t* conf)
{
sdla_t* card;
int err = 0;
- int irq;
+ int irq=0;
+ int i;
/* Sanity checks */
if ((wandev == NULL) || (wandev->private == NULL) || (conf == NULL))
@@ -230,80 +235,187 @@ static int setup (wan_device_t* wandev, wandev_conf_t* conf)
if (wandev->state != WAN_UNCONFIGURED)
return -EBUSY; /* already configured */
- if (!conf->data_size || (conf->data == NULL))
- {
+ printk(KERN_INFO "\nProcessing WAN device %s...\n", wandev->name);
+
+ /* Initialize the counters for each wandev
+ * Used for counting number of times new_if and
+ * del_if get called.
+ */
+ wandev->del_if_cnt = 0;
+ wandev->new_if_cnt = 0;
+ wandev->config_id = conf->config_id;
+
+ if (!conf->data_size || (conf->data == NULL)) {
printk(KERN_ERR
"%s: firmware not found in configuration data!\n",
wandev->name);
return -EINVAL;
}
- if (conf->ioport <= 0)
- {
- printk(KERN_ERR
+
+ /* only check I/O port and IRQ if not an S514 adapter */
+ if(!conf->S514_CPU_no[0]) {
+
+ if (conf->ioport <= 0) {
+ printk(KERN_ERR
"%s: can't configure without I/O port address!\n",
wandev->name);
- return -EINVAL;
- }
+ return -EINVAL;
+ }
- if (conf->irq <= 0)
- {
- printk(KERN_ERR "%s: can't configure without IRQ!\n",
+ if (conf->irq <= 0) {
+ printk(KERN_ERR "%s: can't configure without IRQ!\n",
wandev->name);
- return -EINVAL;
+ return -EINVAL;
+ }
+
+ /* Check for already loaded card with the same IO port and IRQ
+ * If found, copy its hardware configuration and use its
+ * resources (i.e. piggybacking)
+ */
+ if (!card->configured){
+ for (i = 0; i < ncards; i ++) {
+ sdla_t *nxt_card = &card_array[i];
+ if (nxt_card->hw.port == conf->ioport &&
+ nxt_card != card &&
+ conf->config_id == WANCONFIG_CHDLC &&
+ nxt_card->wandev.config_id == WANCONFIG_CHDLC){
+ irq = nxt_card->hw.irq;
+ memcpy(&card->hw, &nxt_card->hw, sizeof(sdlahw_t));
+ nxt_card->next = card;
+ card->next = nxt_card;
+ card->wandev.piggyback = WANOPT_YES;
+ }
+ }
+
+
+ /* Make sure I/O port region is available */
+ if (check_region(conf->ioport, SDLA_MAXIORANGE) &&
+ !card->wandev.piggyback) {
+ printk(KERN_ERR
+ "%s: I/O region 0x%X - 0x%X is in use!\n",
+ wandev->name, conf->ioport,
+ conf->ioport + SDLA_MAXIORANGE);
+ return -EINVAL;
+ }
+ }
}
- /* Make sure I/O port region is available */
- if (check_region(conf->ioport, SDLA_MAXIORANGE))
- {
- printk(KERN_ERR "%s: I/O region 0x%X - 0x%X is in use!\n",
- wandev->name, conf->ioport,
- conf->ioport + SDLA_MAXIORANGE);
- return -EINVAL;
+ /*
+ For a S514 adapter, check for a possible configuration error in that
+ we are loading an adapter in the same slot as a previously loaded S514
+ card.
+ */
+ else {
+ if (!card->configured){
+ for (i = 0; i < ncards; i ++) {
+ sdla_t* nxt_card = &card_array[i];
+ if(nxt_card == card)
+ continue;
+ if((nxt_card->hw.type == SDLA_S514) &&
+ (nxt_card->hw.S514_slot_no == conf->PCI_slot_no) &&
+ (nxt_card->hw.S514_cpu_no[0] == conf->S514_CPU_no[0])&&
+ (conf->config_id == WANCONFIG_CHDLC)&&
+ (nxt_card->wandev.config_id == WANCONFIG_CHDLC)){
+
+ irq = nxt_card->hw.irq;
+ memcpy(&card->hw, &nxt_card->hw, sizeof(sdlahw_t));
+ nxt_card->next = card;
+ card->next = nxt_card;
+ card->wandev.piggyback = WANOPT_YES;
+ }
+ }
+ }
}
- /* Allocate IRQ */
- irq = (conf->irq == 2) ? 9 : conf->irq; /* IRQ2 -> IRQ9 */
- if (request_irq(irq, sdla_isr, 0, wandev->name, card))
- {
- printk(KERN_ERR "%s: can't reserve IRQ %d!\n",
- wandev->name, irq);
- return -EINVAL;
- }
+ /* If the current card has already been configured
+ * or its a piggyback card, do not try to allocate
+ * resources.
+ */
+ if (!card->wandev.piggyback && !card->configured){
+
+ /* Configure hardware, load firmware, etc. */
+ memset(&card->hw, 0, sizeof(sdlahw_t));
+
+ /* for an S514 adapter, pass the CPU number and the slot number read */
+ /* from 'router.conf' to the 'sdla_setup()' function via the 'port' */
+ /* parameter */
+ if (conf->S514_CPU_no[0]){
+
+ card->hw.S514_cpu_no[0] = conf->S514_CPU_no[0];
+ card->hw.S514_slot_no = conf->PCI_slot_no;
+ printk(KERN_INFO "Setting CPU to %c and Slot to %i\n",
+ card->hw.S514_cpu_no[0], card->hw.S514_slot_no);
+
+ }else{
+ /* 508 Card io port and irq initialization */
+ card->hw.port = conf->ioport;
+ card->hw.irq = (conf->irq == 9) ? 2 : conf->irq;
+ }
- /* Configure hardware, load firmware, etc. */
- memset(&card->hw, 0, sizeof(sdlahw_t));
- card->hw.port = conf->ioport;
- card->hw.irq = (conf->irq == 9) ? 2 : conf->irq;
- /* Compute the virtual address of the card in kernel space */
- if(conf->maddr)
- card->hw.dpmbase = phys_to_virt(conf->maddr);
- else /* But 0 means NULL */
- card->hw.dpmbase = (void *)conf->maddr;
-
- card->hw.dpmsize = SDLA_WINDOWSIZE;
- card->hw.type = conf->hw_opt[0];
- card->hw.pclk = conf->hw_opt[1];
- err = sdla_setup(&card->hw, conf->data, conf->data_size);
- if (err)
- {
- free_irq(irq, card);
- return err;
- }
- /* Intialize WAN device data space */
- wandev->irq = irq;
- wandev->dma = 0;
- wandev->ioport = card->hw.port;
- wandev->maddr = card->hw.dpmbase;
- wandev->msize = card->hw.dpmsize;
- wandev->hw_opt[0] = card->hw.type;
- wandev->hw_opt[1] = card->hw.pclk;
- wandev->hw_opt[2] = card->hw.memory;
- wandev->hw_opt[3] = card->hw.fwid;
+ /* Compute the virtual address of the card in kernel space */
+ if(conf->maddr)
+ card->hw.dpmbase = phys_to_virt(conf->maddr);
+ else /* But 0 means NULL */
+ card->hw.dpmbase = (void *)conf->maddr;
+
+ card->hw.dpmsize = SDLA_WINDOWSIZE;
+ /* set the adapter type if using an S514 adapter */
+ card->hw.type = (conf->S514_CPU_no[0]) ? SDLA_S514 : conf->hw_opt[0];
+ card->hw.pclk = conf->hw_opt[1];
+
+ err = sdla_setup(&card->hw, conf->data, conf->data_size);
+ if (err){
+ return err;
+ }
+
+ if(card->hw.type != SDLA_S514)
+ irq = (conf->irq == 2) ? 9 : conf->irq; /* IRQ2 -> IRQ9 */
+ else
+ irq = card->hw.irq;
+
+ /* request an interrupt vector - note that interrupts may be shared */
+ /* when using the S514 PCI adapter */
+ if(request_irq(irq, sdla_isr,
+ (card->hw.type == SDLA_S514) ? SA_SHIRQ : 0, wandev->name, card)){
+
+ printk(KERN_ERR "%s: Can't reserve IRQ %d!\n", wandev->name, irq);
+ return -EINVAL;
+ }
+
+ }else{
+ printk(KERN_INFO "%s: Card Configured %i or Piggybacking %i!\n",
+ wandev->name,card->configured,card->wandev.piggyback);
+ }
+
+
+ if (!card->configured){
+
+ #ifdef __SMP__
+ /* Initialize the Spin lock */
+ printk(KERN_INFO "%s: Initializing SMP\n",wandev->name);
+ spin_lock_init(&card->lock);
+ #endif
+
+ /* Intialize WAN device data space */
+ wandev->irq = irq;
+ wandev->dma = 0;
+ if(card->hw.type != SDLA_S514){
+ wandev->ioport = card->hw.port;
+ }else{
+ wandev->S514_cpu_no[0] = card->hw.S514_cpu_no[0];
+ wandev->S514_slot_no = card->hw.S514_slot_no;
+ }
+ wandev->maddr = (unsigned long)card->hw.dpmbase;
+ wandev->msize = card->hw.dpmsize;
+ wandev->hw_opt[0] = card->hw.type;
+ wandev->hw_opt[1] = card->hw.pclk;
+ wandev->hw_opt[2] = card->hw.memory;
+ wandev->hw_opt[3] = card->hw.fwid;
+ }
/* Protocol-specific initialization */
- switch (card->hw.fwid)
- {
+ switch (card->hw.fwid) {
#ifdef CONFIG_WANPIPE_X25
case SFID_X25_502:
case SFID_X25_508:
@@ -325,22 +437,49 @@ static int setup (wan_device_t* wandev, wandev_conf_t* conf)
break;
#endif
+#ifdef CONFIG_WANPIPE_CHDLC
+ case SFID_CHDLC508:
+ case SFID_CHDLC514:
+// if (conf->ft1){
+// printk(KERN_INFO "%s: Starting FT1 Configurator\n",
+// card->devname);
+// err = wpft1_init(card, conf);
+// }else{
+ err = wpc_init(card, conf);
+// }
+ break;
+#endif
+
+#ifdef CONFIG_WANPIPE_BSTRM
+ case SFID_BSC502:
+ err = bsc_init(card, conf);
+ break;
+#endif
+
+#ifdef CONFIG_WANPIPE_HDLC
+ case SFID_HDLC508:
+ err = hdlc_init(card, conf);
+ break;
+#endif
+
default:
- printk(KERN_ERR "%s: this firmware is not supported!\n",
- wandev->name)
- ;
+ printk(KERN_ERR "%s: this firmware is not supported %X %X!\n",
+ wandev->name,card->hw.fwid,SFID_CHDLC508);
err = -EINVAL;
}
- if (err)
- {
- sdla_down(&card->hw);
- free_irq(irq, card);
+
+
+ if (err){
+ release_hw(card);
return err;
+
}
+
+
/* Reserve I/O region and schedule background task */
-/* printk(KERN_INFO "about to request\n");*/
- request_region(card->hw.port, card->hw.io_range, wandev->name);
-/* printk(KERN_INFO "request done\n");*/
+ if(card->hw.type != SDLA_S514 && !card->wandev.piggyback)
+ request_region(card->hw.port, card->hw.io_range, wandev->name);
+
if (++active == 1)
queue_task(&sdla_tq, &tq_scheduler);
@@ -358,7 +497,7 @@ static int setup (wan_device_t* wandev, wandev_conf_t* conf)
*/
static int shutdown (wan_device_t* wandev)
{
- sdla_t* card;
+ sdla_t *card;
/* sanity checks */
if ((wandev == NULL) || (wandev->private == NULL))
@@ -367,7 +506,7 @@ static int shutdown (wan_device_t* wandev)
if (wandev->state == WAN_UNCONFIGURED)
return 0;
- /* If wee are in a critical section we lose */
+ /* If we are in a critical section we lose */
if (test_and_set_bit(0, (void*)&wandev->critical))
return -EAGAIN;
@@ -376,22 +515,67 @@ static int shutdown (wan_device_t* wandev)
if (--active == 0)
schedule(); /* stop background thread */
-
-/* printk(KERN_INFO "active now %d\n", active);
-
- printk(KERN_INFO "About to call sdla_down\n");*/
- sdla_down(&card->hw);
-/* printk(KERN_INFO "sdla_down done\n");
- printk(KERN_INFO "About to call free_irq\n");*/
- free_irq(wandev->irq, card);
-/* printk(KERN_INFO "free_irq done\n");
- printk(KERN_INFO "About to call release_region\n");*/
- release_region(card->hw.port, card->hw.io_range);
-/* printk(KERN_INFO "release_region done\n");*/
+
+ /* Release Resources */
+ release_hw(card);
+
+ /* only free the allocated I/O range if not an S514 adapter */
+ if (wandev->hw_opt[0] != SDLA_S514 && !card->configured){
+ release_region(card->hw.port, card->hw.io_range);
+ }
+
+ if (!card->configured){
+ memset(&card->hw, 0, sizeof(sdlahw_t));
+ if (card->next){
+ memset(&card->next->hw, 0, sizeof(sdlahw_t));
+ }
+ }
+
wandev->critical = 0;
return 0;
}
+static void release_hw (sdla_t *card)
+{
+ sdla_t *nxt_card;
+
+ /* Check if next device exists */
+ if (card->next){
+ nxt_card = card->next;
+ /* If next device is down then release resources */
+ if (nxt_card->wandev.state == WAN_UNCONFIGURED){
+ if (card->wandev.piggyback){
+ /* If this device is piggyback then use
+ * information of the master device
+ */
+ printk(KERN_INFO "%s: Piggyback shutting down\n",card->devname);
+ sdla_down(&card->next->hw);
+ free_irq(card->wandev.irq, card->next);
+ card->configured = 0;
+ card->next->configured = 0;
+ card->wandev.piggyback = 0;
+ }else{
+ /* Master device shutting down */
+ printk(KERN_INFO "%s: Master shutting down\n",card->devname);
+ sdla_down(&card->hw);
+ free_irq(card->wandev.irq, card);
+ card->configured = 0;
+ card->next->configured = 0;
+ }
+ }else{
+ printk(KERN_INFO "%s: Device still running\n",
+ nxt_card->devname);
+ card->configured = 1;
+ }
+ }else{
+ printk(KERN_INFO "%s: Master shutting down\n",card->devname);
+ sdla_down(&card->hw);
+ free_irq(card->wandev.irq, card);
+ card->configured = 0;
+ }
+}
+
+
/*============================================================================
* Driver I/O control.
* o verify arguments
@@ -402,20 +586,29 @@ static int shutdown (wan_device_t* wandev)
*/
static int ioctl (wan_device_t* wandev, unsigned cmd, unsigned long arg)
{
+ sdla_t* card;
int err;
/* sanity checks */
if ((wandev == NULL) || (wandev->private == NULL))
- return -EFAULT
- ;
+ return -EFAULT;
if (wandev->state == WAN_UNCONFIGURED)
- return -ENODEV
- ;
- if (test_and_set_bit(0, (void*)&wandev->critical))
- return -EAGAIN
- ;
- switch (cmd)
- {
+ return -ENODEV;
+
+ card = wandev->private;
+
+ if(card->hw.type != SDLA_S514){
+ disable_irq(card->hw.irq);
+ }
+
+ if (test_and_set_bit(0, (void*)&wandev->critical)) {
+ if(card->hw.type != SDLA_S514){
+ enable_irq(card->hw.irq);
+ }
+ return -EAGAIN;
+ }
+
+ switch (cmd) {
case WANPIPE_DUMP:
err = ioctl_dump(wandev->private, (void*)arg);
break;
@@ -427,11 +620,16 @@ static int ioctl (wan_device_t* wandev, unsigned cmd, unsigned long arg)
default:
err = -EINVAL;
}
- wandev->critical = 0;
+
+ clear_bit(0, (void*)&wandev->critical);
+ if(card->hw.type != SDLA_S514){
+ enable_irq(card->hw.irq);
+ }
+
return err;
}
-/****** Driver IOCTL Hanlers ************************************************/
+/****** Driver IOCTL Handlers ***********************************************/
/*============================================================================
* Dump adapter memory to user buffer.
@@ -458,34 +656,47 @@ static int ioctl_dump (sdla_t* card, sdla_dump_t* u_dump)
if ((dump.magic != WANPIPE_MAGIC) ||
(dump.offset + dump.length > card->hw.memory))
return -EINVAL;
-
+
winsize = card->hw.dpmsize;
save_flags(flags);
cli(); /* >>> critical section start <<< */
- oldvec = card->hw.vector;
- while (dump.length)
- {
- unsigned pos = dump.offset % winsize; /* current offset */
- unsigned long vec = dump.offset - pos; /* current vector */
- unsigned len = (dump.length > (winsize - pos)) ?
- (winsize - pos) : dump.length
- ;
- if (sdla_mapmem(&card->hw, vec) != 0) /* relocate window */
- {
- err = -EIO;
- break;
- }
+
+ if(card->hw.type != SDLA_S514) {
+ oldvec = card->hw.vector;
+ while (dump.length) {
+ /* current offset */
+ unsigned pos = dump.offset % winsize;
+ /* current vector */
+ unsigned long vec = dump.offset - pos;
+ unsigned len = (dump.length > (winsize - pos)) ?
+ (winsize - pos) : dump.length;
+ /* relocate window */
+ if (sdla_mapmem(&card->hw, vec) != 0) {
+ err = -EIO;
+ break;
+ }
+ /* FIXME::: COPY TO KERNEL BUFFER FIRST ?? */
+ sti(); /* Not ideal but tough we have to do this */
+ if(copy_to_user((void *)dump.ptr,
+ (u8 *)card->hw.dpmbase + pos, len))
+ return -EFAULT;
+ cli();
+ dump.length -= len;
+ dump.offset += len;
+ (char*)dump.ptr += len;
+ }
+ sdla_mapmem(&card->hw, oldvec);/* restore DPM window position */
+ }
+
+ else {
/* FIXME::: COPY TO KERNEL BUFFER FIRST ?? */
- sti(); /* Not ideal but tough we have to do this */
- if(copy_to_user((void *)dump.ptr,
- (u8 *)card->hw.dpmbase + pos, len))
- return -EFAULT;
- cli();
- dump.length -= len;
- dump.offset += len;
- (char*)dump.ptr += len;
+ sti(); /* Not ideal but tough we have to do this */
+ if(copy_to_user((void *)dump.ptr,
+ (u8 *)card->hw.dpmbase + dump.offset, dump.length))
+ return -EFAULT;
+ cli();
}
- sdla_mapmem(&card->hw, oldvec); /* restore DPM window position */
+
restore_flags(flags); /* >>> critical section end <<< */
return err;
}
@@ -502,9 +713,10 @@ static int ioctl_exec (sdla_t* card, sdla_exec_t* u_exec)
if (card->exec == NULL)
return -ENODEV;
-
+
if(copy_from_user((void*)&exec, (void*)u_exec, sizeof(sdla_exec_t)))
return -EFAULT;
+
if ((exec.magic != WANPIPE_MAGIC) || (exec.cmd == NULL))
return -EINVAL;
return card->exec(card, exec.cmd, exec.data);
@@ -521,21 +733,110 @@ STATIC void sdla_isr (int irq, void* dev_id, struct pt_regs *regs)
{
#define card ((sdla_t*)dev_id)
- if (!card || (card->wandev.state == WAN_UNCONFIGURED))
- return
- ;
- if (card->in_isr)
- {
- printk(KERN_WARNING "%s: interrupt re-entrancy on IRQ %d!\n",
- card->devname, card->wandev.irq)
- ;
- return;
+ if(card->hw.type == SDLA_S514) { /* handle interrrupt on S514 */
+ u32 int_status;
+ unsigned char CPU_no = card->hw.S514_cpu_no[0];
+ unsigned char card_found_for_IRQ;
+ u8 IRQ_count = 0;
+
+ for(;;) {
+
+ read_S514_int_stat(&card->hw, &int_status);
+
+ /* check if the interrupt is for this device */
+ if(!((unsigned char)int_status &
+ (IRQ_CPU_A | IRQ_CPU_B)))
+ return;
+
+ /* if the IRQ is for both CPUs on the same adapter, */
+ /* then alter the interrupt status so as to handle */
+ /* one CPU at a time */
+ if(((unsigned char)int_status & (IRQ_CPU_A | IRQ_CPU_B))
+ == (IRQ_CPU_A | IRQ_CPU_B)) {
+ int_status &= (CPU_no == S514_CPU_A) ?
+ ~IRQ_CPU_B : ~IRQ_CPU_A;
+ }
+
+ card_found_for_IRQ = 0;
+
+ /* check to see that the CPU number for this device */
+ /* corresponds to the interrupt status read */
+ switch (CPU_no) {
+ case S514_CPU_A:
+ if((unsigned char)int_status &
+ IRQ_CPU_A)
+ card_found_for_IRQ = 1;
+ break;
+
+ case S514_CPU_B:
+ if((unsigned char)int_status &
+ IRQ_CPU_B)
+ card_found_for_IRQ = 1;
+ break;
+ }
+
+ /* exit if the interrupt is for another CPU on the */
+ /* same IRQ */
+ if(!card_found_for_IRQ)
+ return;
+
+ if (!card ||
+ (card->wandev.state == WAN_UNCONFIGURED && !card->configured)){
+ printk(KERN_INFO
+ "Received IRQ %d for CPU #%c\n",
+ irq, CPU_no);
+ printk(KERN_INFO
+ "IRQ for unconfigured adapter\n");
+ S514_intack(&card->hw, int_status);
+ return;
+ }
+
+ if (card->in_isr) {
+ printk(KERN_INFO
+ "%s: interrupt re-entrancy on IRQ %d\n",
+ card->devname, card->wandev.irq);
+ S514_intack(&card->hw, int_status);
+ return;
+ }
+
+ S514_intack(&card->hw, int_status);
+
+ if (card->isr)
+ card->isr(card);
+
+ /* handle a maximum of two interrupts (one for each */
+ /* CPU on the adapter) before returning */
+ if((++ IRQ_count) == 2)
+ return;
+ }
}
- sdla_intack(&card->hw);
- if (card->isr)
- card->isr(card);
+ else { /* handle interrupt on S508 adapter */
+
+ if (!card || ((card->wandev.state == WAN_UNCONFIGURED) && !card->configured))
+ return;
+ if (card->in_isr) {
+ printk(KERN_INFO
+ "%s: interrupt re-entrancy on IRQ %d!\n",
+ card->devname, card->wandev.irq);
+ return;
+ }
+
+ /* Use spin lock only for S508 */
+
+#ifdef __SMP__
+ spin_lock(&card->lock);
+#endif
+ sdla_intack(&card->hw);
+ if (card->isr)
+ card->isr(card);
+#ifdef __SMP__
+ spin_unlock(&card->lock);
+#endif
+
+ }
+
#undef card
}
@@ -550,13 +851,11 @@ STATIC void sdla_poll (void* data)
{
int i;
- for (i = 0; i < ncards; ++i)
- {
+ for (i = 0; i < ncards; ++i) {
sdla_t* card = &card_array[i];
if ((card->wandev.state != WAN_UNCONFIGURED) && card->poll &&
- !card->wandev.critical)
- {
+ !card->wandev.critical) {
card->poll(card);
}
}
@@ -597,26 +896,21 @@ void wanpipe_set_state (sdla_t* card, int state)
save_flags(flags);
cli();
- if (card->wandev.state != state)
- {
- switch (state)
- {
+ if (card->wandev.state != state) {
+ switch (state) {
case WAN_CONNECTED:
printk (KERN_INFO "%s: link connected!\n",
- card->devname)
- ;
+ card->devname);
break;
case WAN_CONNECTING:
printk (KERN_INFO "%s: link connecting...\n",
- card->devname)
- ;
+ card->devname);
break;
case WAN_DISCONNECTED:
printk (KERN_INFO "%s: link disconnected!\n",
- card->devname)
- ;
+ card->devname);
break;
}
card->wandev.state = state;
diff --git a/drivers/parport/init.c b/drivers/parport/init.c
index b2f4d4b06..a43d59dbe 100644
--- a/drivers/parport/init.c
+++ b/drivers/parport/init.c
@@ -26,6 +26,8 @@ static int dma[PARPORT_MAX] __initdata = { [0 ... PARPORT_MAX-1] = PARPORT_DMA_N
extern int parport_pc_init(int *io, int *io_hi, int *irq, int *dma);
extern int parport_sunbpp_init(void);
+extern int parport_amiga_init(void);
+extern int parport_mfc3_init(void);
static int parport_setup_ptr __initdata = 0;
diff --git a/drivers/parport/parport_amiga.c b/drivers/parport/parport_amiga.c
index 4405eea01..dc4fc6945 100644
--- a/drivers/parport/parport_amiga.c
+++ b/drivers/parport/parport_amiga.c
@@ -1,6 +1,6 @@
/* Low-level parallel port routines for the Amiga buildin port
*
- * Author: Joerg Dorchain <dorchain@wirbel.com>
+ * Author: Joerg Dorchain <joerg@dorchain.net>
*
* This is a complete rewrite of the code, but based heaviy upon the old
* lp_intern. code.
@@ -25,7 +25,7 @@
#ifdef DEBUG
#define DPRINTK printk
#else
-#define DPRINTK(format, args...)
+static inline void DPRINTK(void *nothing, ...) {}
#endif
static struct parport *this_port = NULL;
@@ -90,7 +90,7 @@ DPRINTK("frob_control mask %02x, value %02x\n",mask,val);
return old;
}
-
+#if 0 /* currently unused */
static unsigned char status_pc_to_amiga(unsigned char status)
{
unsigned char ret = 1;
@@ -107,6 +107,7 @@ static unsigned char status_pc_to_amiga(unsigned char status)
/* not connected */;
return ret;
}
+#endif
static unsigned char status_amiga_to_pc(unsigned char status)
{
@@ -138,6 +139,28 @@ static void amiga_interrupt(int irq, void *dev_id, struct pt_regs *regs)
parport_generic_irq(irq, (struct parport *) dev_id, regs);
}
+static void amiga_enable_irq(struct parport *p)
+{
+ enable_irq(IRQ_AMIGA_CIAA_FLG);
+}
+
+static void amiga_disable_irq(struct parport *p)
+{
+ disable_irq(IRQ_AMIGA_CIAA_FLG);
+}
+
+static void amiga_data_forward(struct parport *p)
+{
+ DPRINTK("forward\n");
+ ciaa.ddrb = 0xff; /* all pins output */
+}
+
+static void amiga_data_reverse(struct parport *p)
+{
+ DPRINTK("reverse\n");
+ ciaa.ddrb = 0; /* all pins input */
+}
+
static void amiga_init_state(struct pardevice *dev, struct parport_state *s)
{
s->u.amiga.data = 0;
@@ -162,16 +185,6 @@ static void amiga_restore_state(struct parport *p, struct parport_state *s)
ciab.ddra |= (ciab.ddra & 0xf8) | s->u.amiga.statusdir;
}
-static void amiga_enable_irq(struct parport *p)
-{
- enable_irq(IRQ_AMIGA_CIAA_FLG);
-}
-
-static void amiga_disable_irq(struct parport *p)
-{
- disable_irq(IRQ_AMIGA_CIAA_FLG);
-}
-
static void amiga_inc_use_count(void)
{
MOD_INC_USE_COUNT;
@@ -195,8 +208,8 @@ static struct parport_operations pp_amiga_ops = {
amiga_enable_irq,
amiga_disable_irq,
- NULL, /* data_forward */
- NULL, /* data_reverse */
+ amiga_data_forward,
+ amiga_data_reverse,
amiga_init_state,
amiga_save_state,
@@ -205,18 +218,18 @@ static struct parport_operations pp_amiga_ops = {
amiga_inc_use_count,
amiga_dec_use_count,
- NULL, /* epp_write_data */
- NULL, /* epp_read_data */
- NULL, /* epp_write_addr */
- NULL, /* epp_read_addr */
+ parport_ieee1284_epp_write_data,
+ parport_ieee1284_epp_read_data,
+ parport_ieee1284_epp_write_addr,
+ parport_ieee1284_epp_read_addr,
- NULL, /* ecp_write_data */
- NULL, /* ecp_read_data */
- NULL, /* ecp_write_addr */
+ parport_ieee1284_ecp_write_data,
+ parport_ieee1284_ecp_read_data,
+ parport_ieee1284_ecp_write_addr,
- NULL, /* compat_write_data */
- NULL, /* nibble_read_data */
- NULL, /* byte_read_data */
+ parport_ieee1284_write_compat,
+ parport_ieee1284_read_nibble,
+ parport_ieee1284_read_byte,
};
/* ----------- Initialisation code --------------------------------- */
@@ -252,7 +265,7 @@ int __init parport_amiga_init(void)
#ifdef MODULE
-MODULE_AUTHOR("Joerg Dorchain");
+MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port");
MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port");
diff --git a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c
index dfa3a1d93..054bb4d89 100644
--- a/drivers/parport/parport_mfc3.c
+++ b/drivers/parport/parport_mfc3.c
@@ -1,6 +1,6 @@
/* Low-level parallel port routines for the Multiface 3 card
*
- * Author: Joerg Dorchain <dorchain@wirbel.com>
+ * Author: Joerg Dorchain <joerg@dorchain.net>
*
* (C) The elitist m68k Users(TM)
*
@@ -46,6 +46,10 @@
* -------+-----+-----+---------------------------------------------------------
*
* Should be enough to understand some of the driver.
+ *
+ * Per convention for normal use the port registers are visible.
+ * If you need the data direction registers, restore the value in the
+ * control register.
*/
#include "multiface.h"
@@ -67,7 +71,7 @@
#ifdef DEBUG
#define DPRINTK printk
#else
-static inline int DPRINTK() {return 0;}
+static inline int DPRINTK(void *nothing, ...) {return 0;}
#endif
static struct parport *this_port[MAX_MFC] = {NULL, };
@@ -95,10 +99,6 @@ static unsigned char control_pc_to_mfc3(unsigned char control)
{
unsigned char ret = 32|64;
- if (control & PARPORT_CONTROL_DIRECTION) /* XXX: What is this? */
- ;
- if (control & PARPORT_CONTROL_INTEN) /* XXX: What is INTEN? */
- ;
if (control & PARPORT_CONTROL_SELECT) /* XXX: What is SELECP? */
ret &= ~32; /* /SELECT_IN */
if (control & PARPORT_CONTROL_INIT) /* INITP */
@@ -112,7 +112,7 @@ static unsigned char control_pc_to_mfc3(unsigned char control)
static unsigned char control_mfc3_to_pc(unsigned char control)
{
- unsigned char ret = PARPORT_CONTROL_INTEN | PARPORT_CONTROL_STROBE
+ unsigned char ret = PARPORT_CONTROL_STROBE
| PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_SELECT;
if (control & 128) /* /INITP */
@@ -146,7 +146,7 @@ DPRINTK("frob_control mask %02x, value %02x\n",mask,val);
return old;
}
-
+#if 0 /* currently unused */
static unsigned char status_pc_to_mfc3(unsigned char status)
{
unsigned char ret = 1;
@@ -163,6 +163,7 @@ static unsigned char status_pc_to_mfc3(unsigned char status)
ret |= 16;
return ret;
}
+#endif
static unsigned char status_mfc3_to_pc(unsigned char status)
{
@@ -182,11 +183,13 @@ static unsigned char status_mfc3_to_pc(unsigned char status)
return ret;
}
+#if 0 /* currently unused */
static void mfc3_write_status( struct parport *p, unsigned char status)
{
DPRINTK("write_status %02x\n",status);
pia(p)->ppra = (pia(p)->ppra & 0xe0) | status_pc_to_mfc3(status);
}
+#endif
static unsigned char mfc3_read_status(struct parport *p)
{
@@ -197,11 +200,13 @@ DPRINTK("read_status %02x\n", status);
return status;
}
+#if 0 /* currently unused */
static void mfc3_change_mode( struct parport *p, int m)
{
/* XXX: This port only has one mode, and I am
not sure about the corresponding PC-style mode*/
}
+#endif
static int use_cnt = 0;
@@ -217,12 +222,33 @@ static void mfc3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
}
-static int mfc3_claim_resources(struct parport *p)
+static void mfc3_enable_irq(struct parport *p)
+{
+ pia(p)->crb |= PIA_C1_ENABLE_IRQ;
+}
+
+static void mfc3_disable_irq(struct parport *p)
+{
+ pia(p)->crb &= ~PIA_C1_ENABLE_IRQ;
+}
+
+static void mfc3_data_forward(struct parport *p)
+{
+ DPRINTK("forward\n");
+ pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */
+ pia(p)->pddrb = 255; /* all pins output */
+ pia(p)->crb |= PIA_DDR; /* make data register visible - default */
+}
+
+static void mfc3_data_reverse(struct parport *p)
{
-DPRINTK("claim_resources\n");
+ DPRINTK("reverse\n");
+ pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */
+ pia(p)->pddrb = 0; /* all pins input */
+ pia(p)->crb |= PIA_DDR; /* make data register visible - default */
}
-static void mfc3_init_state(struct parport_state *s)
+static void mfc3_init_state(struct pardevice *dev, struct parport_state *s)
{
s->u.amiga.data = 0;
s->u.amiga.datadir = 255;
@@ -254,16 +280,6 @@ static void mfc3_restore_state(struct parport *p, struct parport_state *s)
pia(p)->cra |= PIA_DDR;
}
-static void mfc3_enable_irq(struct parport *p)
-{
- pia(p)->crb |= PIA_C1_ENABLE_IRQ;
-}
-
-static void mfc3_disable_irq(struct parport *p)
-{
- pia(p)->crb &= ~PIA_C1_ENABLE_IRQ;
-}
-
static void mfc3_inc_use_count(void)
{
MOD_INC_USE_COUNT;
@@ -287,8 +303,8 @@ static struct parport_operations pp_mfc3_ops = {
mfc3_enable_irq,
mfc3_disable_irq,
- NULL, /* data_forward - FIXME */
- NULL, /* data_reverse - FIXME */
+ mfc3_data_forward,
+ mfc3_data_reverse,
mfc3_init_state,
mfc3_save_state,
@@ -318,43 +334,43 @@ int __init parport_mfc3_init(void)
struct parport *p;
int pias = 0;
struct pia *pp;
- unsigned int key = 0;
- const struct ConfigDev *cd;
-
- if (MACH_IS_AMIGA) {
- while ((key = zorro_find(ZORRO_PROD_BSC_MULTIFACE_III, 0, key))) {
- cd = zorro_get_board(key);
- pp = (struct pia *)ZTWO_VADDR((((u_char *)cd->cd_BoardAddr)+PIABASE));
- if (pias < MAX_MFC) {
- pp->crb = 0;
- pp->pddrb = 255; /* all data pins output */
- pp->crb = PIA_DDR|32|8;
- dummy = pp->pddrb; /* reading clears interrupt */
- pp->cra = 0;
- pp->pddra = 0xe0; /* /RESET, /DIR ,/AUTO-FEED output */
- pp->cra = PIA_DDR;
- pp->ppra = 0; /* reset printer */
- udelay(10);
- pp->ppra = 128;
- if ((p = parport_register_port((unsigned long)pp,
- IRQ_AMIGA_PORTS, PARPORT_DMA_NONE,
- &pp_mfc3_ops))) {
- this_port[pias++] = p;
- printk(KERN_INFO "%s: Multiface III port using irq\n", p->name);
- /* XXX: set operating mode */
- parport_proc_register(p);
-
- if (p->irq != PARPORT_IRQ_NONE)
- if (use_cnt++ == 0)
- if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, SA_SHIRQ, p->name, &pp_mfc3_ops))
- use_cnt--;
-
- if (parport_probe_hook)
- (*parport_probe_hook)(p);
- zorro_config_board(key, 0);
- p->private_data = (void *)key;
- parport_announce_port (p);
- }
+ struct zorro_dev *z = NULL;
+
+ if (!MACH_IS_AMIGA)
+ return 0;
+
+ while ((z = zorro_find_device(ZORRO_PROD_BSC_MULTIFACE_III, z))) {
+ unsigned long piabase = z->resource.start+PIABASE;
+ if (!request_mem_region(piabase, sizeof(struct pia), "PIA"))
+ continue;
+ strcpy(z->name, "MultiFace III MC6821 PIA");
+ pp = (struct pia *)ZTWO_VADDR(piabase);
+ if (pias < MAX_MFC) {
+ pp->crb = 0;
+ pp->pddrb = 255; /* all data pins output */
+ pp->crb = PIA_DDR|32|8;
+ dummy = pp->pddrb; /* reading clears interrupt */
+ pp->cra = 0;
+ pp->pddra = 0xe0; /* /RESET, /DIR ,/AUTO-FEED output */
+ pp->cra = PIA_DDR;
+ pp->ppra = 0; /* reset printer */
+ udelay(10);
+ pp->ppra = 128;
+ if ((p = parport_register_port((unsigned long)pp,
+ IRQ_AMIGA_PORTS, PARPORT_DMA_NONE,
+ &pp_mfc3_ops))) {
+ this_port[pias++] = p;
+ printk(KERN_INFO "%s: Multiface III port using irq\n", p->name);
+ /* XXX: set operating mode */
+ parport_proc_register(p);
+
+ if (p->irq != PARPORT_IRQ_NONE)
+ if (use_cnt++ == 0)
+ if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, SA_SHIRQ, p->name, &pp_mfc3_ops))
+ use_cnt--;
+
+ p->private_data = (void *)piabase;
+ parport_announce_port (p);
}
}
}
@@ -363,7 +379,7 @@ int __init parport_mfc3_init(void)
#ifdef MODULE
-MODULE_AUTHOR("Joerg Dorchain");
+MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
MODULE_DESCRIPTION("Parport Driver for Multiface 3 expansion cards Paralllel Port");
MODULE_SUPPORTED_DEVICE("Multiface 3 Parallel Port");
@@ -383,7 +399,7 @@ void cleanup_module(void)
free_irq(IRQ_AMIGA_PORTS, &pp_mfc3_ops);
parport_proc_unregister(this_port[i]);
parport_unregister_port(this_port[i]);
- zorro_unconfig_board((unsigned int)this_port[i]->private_data, 0);
+ release_mem_region(ZTWO_PADDR(this_port[i]->private_data), sizeof(struct pia));
}
}
#endif
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 57e6ac684..0524cf40a 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -549,8 +549,24 @@ static size_t parport_pc_fifo_write_block_dma (struct parport *port,
{
int ret = 0;
unsigned long dmaflag;
- size_t left = length;
+ size_t left = length;
const struct parport_pc_private *priv = port->physport->private_data;
+ unsigned long dma_addr;
+ size_t maxlen = 0x10000; /* max 64k per DMA transfer */
+ unsigned long start = (unsigned long) buf;
+ unsigned long end = (unsigned long) buf + length - 1;
+
+ /* above 16 MB we use a bounce buffer as ISA-DMA is not possible */
+ if (end <= MAX_DMA_ADDRESS) {
+ /* If it would cross a 64k boundary, cap it at the end. */
+ if ((start ^ end) & ~0xffff)
+ maxlen = (0x10000 - start) & 0xffff;
+
+ dma_addr = virt_to_bus(buf);
+ } else {
+ dma_addr = priv->dma_handle;
+ maxlen = PAGE_SIZE; /* sizeof(priv->dma_buf) */
+ }
port = port->physport;
@@ -566,16 +582,17 @@ static size_t parport_pc_fifo_write_block_dma (struct parport *port,
size_t count = left;
- if (count > PAGE_SIZE)
- count = PAGE_SIZE;
+ if (count > maxlen)
+ count = maxlen;
- memcpy(priv->dma_buf, buf, count);
+ if (maxlen == PAGE_SIZE) /* bounce buffer ! */
+ memcpy(priv->dma_buf, buf, count);
dmaflag = claim_dma_lock();
disable_dma(port->dma);
clear_dma_ff(port->dma);
set_dma_mode(port->dma, DMA_MODE_WRITE);
- set_dma_addr(port->dma, virt_to_bus((volatile char *) priv->dma_buf));
+ set_dma_addr(port->dma, dma_addr);
set_dma_count(port->dma, count);
/* Set DMA mode */
@@ -1499,7 +1516,8 @@ static int __maybe_init parport_dma_probe (struct parport *p)
struct parport *__maybe_init parport_pc_probe_port (unsigned long int base,
unsigned long int base_hi,
- int irq, int dma)
+ int irq, int dma,
+ struct pci_dev *dev)
{
struct parport_pc_private *priv;
struct parport_operations *ops;
@@ -1525,6 +1543,8 @@ struct parport *__maybe_init parport_pc_probe_port (unsigned long int base,
priv->ecr = 0;
priv->fifo_depth = 0;
priv->dma_buf = 0;
+ priv->dma_handle = 0;
+ priv->dev = dev;
p->base = base;
p->base_hi = base_hi;
p->irq = irq;
@@ -1649,7 +1669,9 @@ struct parport *__maybe_init parport_pc_probe_port (unsigned long int base,
p->dma = PARPORT_DMA_NONE;
} else {
priv->dma_buf =
- (char *)__get_dma_pages(GFP_KERNEL, 0);
+ pci_alloc_consistent(priv->dev,
+ PAGE_SIZE,
+ &priv->dma_handle);
if (! priv->dma_buf) {
printk (KERN_WARNING "%s: "
"cannot get buffer for DMA, "
@@ -1805,10 +1827,12 @@ static int __init parport_pc_init_pci (int irq, int dma)
if (parport_pc_probe_port (io_lo,
io_hi,
pcidev->irq,
- dma))
+ dma,
+ pcidev))
count++;
} else if (parport_pc_probe_port (io_lo, io_hi,
- irq, dma))
+ irq, dma,
+ pcidev))
count++;
}
}
@@ -1913,7 +1937,9 @@ void cleanup_module(void)
release_region(p->base_hi, 3);
parport_proc_unregister(p);
if (priv->dma_buf)
- free_page((unsigned long) priv->dma_buf);
+ pci_free_consistent(priv->dev, PAGE_SIZE,
+ priv->dma_buf,
+ priv->dma_handle);
kfree (p->private_data);
parport_unregister_port(p);
kfree (ops); /* hope no-one cached it */
diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c
index 29a3a7e29..07b30b009 100644
--- a/drivers/parport/procfs.c
+++ b/drivers/parport/procfs.c
@@ -224,7 +224,7 @@ static const struct parport_sysctl_table parport_sysctl_template = {
#endif /* IEEE 1284 support */
{0}
},
- { {DEV_PARPORT_DEVICES_ACTIVE, "active", NULL, 0, 444, NULL,
+ { {DEV_PARPORT_DEVICES_ACTIVE, "active", NULL, 0, 0444, NULL,
&do_active_device }, {0}},
{ PARPORT_PORT_DIR(NULL), {0}},
{ PARPORT_PARPORT_DIR(NULL), {0}},
diff --git a/drivers/pci/compat.c b/drivers/pci/compat.c
index b59da5041..ce058cc0e 100644
--- a/drivers/pci/compat.c
+++ b/drivers/pci/compat.c
@@ -19,7 +19,7 @@ pcibios_present(void)
int
pcibios_find_class(unsigned int class, unsigned short index, unsigned char *bus, unsigned char *devfn)
{
- struct pci_dev *dev = NULL;
+ const struct pci_dev *dev = NULL;
int cnt = 0;
while ((dev = pci_find_class(class, dev)))
@@ -36,7 +36,7 @@ int
pcibios_find_device(unsigned short vendor, unsigned short device, unsigned short index,
unsigned char *bus, unsigned char *devfn)
{
- struct pci_dev *dev = NULL;
+ const struct pci_dev *dev = NULL;
int cnt = 0;
while ((dev = pci_find_device(vendor, device, dev)))
diff --git a/drivers/pci/gen-devlist.c b/drivers/pci/gen-devlist.c
index 9337d80b0..ed0bcba16 100644
--- a/drivers/pci/gen-devlist.c
+++ b/drivers/pci/gen-devlist.c
@@ -8,7 +8,7 @@
#include <string.h>
static void
-pq(FILE *f, char *c)
+pq(FILE *f, const char *c)
{
while (*c) {
if (*c == '"')
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index f109cef46..e31a9046f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -47,7 +47,7 @@ pci_find_slot(unsigned int bus, unsigned int devfn)
struct pci_dev *
pci_find_subsys(unsigned int vendor, unsigned int device,
unsigned int ss_vendor, unsigned int ss_device,
- struct pci_dev *from)
+ const struct pci_dev *from)
{
struct list_head *n = from ? from->global_list.next : pci_devices.next;
@@ -65,14 +65,14 @@ pci_find_subsys(unsigned int vendor, unsigned int device,
struct pci_dev *
-pci_find_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
+pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from)
{
return pci_find_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
}
struct pci_dev *
-pci_find_class(unsigned int class, struct pci_dev *from)
+pci_find_class(unsigned int class, const struct pci_dev *from)
{
struct list_head *n = from ? from->global_list.next : pci_devices.next;
@@ -116,9 +116,9 @@ pci_find_capability(struct pci_dev *dev, int cap)
* it should be allocated from.
*/
struct resource *
-pci_find_parent_resource(struct pci_dev *dev, struct resource *res)
+pci_find_parent_resource(const struct pci_dev *dev, struct resource *res)
{
- struct pci_bus *bus = dev->bus;
+ const struct pci_bus *bus = dev->bus;
int i;
struct resource *best = NULL;
@@ -203,7 +203,7 @@ pci_enable_device(struct pci_dev *dev)
static LIST_HEAD(pci_drivers);
const struct pci_device_id *
-pci_match_device(const struct pci_device_id *ids, struct pci_dev *dev)
+pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev)
{
while (ids->vendor || ids->subvendor || ids->class_mask) {
if ((ids->vendor == PCI_ANY_ID || ids->vendor == dev->vendor) &&
@@ -315,7 +315,7 @@ static struct pci_driver pci_compat_driver = {
};
struct pci_driver *
-pci_dev_driver(struct pci_dev *dev)
+pci_dev_driver(const struct pci_dev *dev)
{
if (dev->driver)
return dev->driver;
@@ -808,6 +808,10 @@ static struct pci_dev * __init pci_scan_device(struct pci_dev *temp)
memcpy(dev, temp, sizeof(*dev));
dev->vendor = l & 0xffff;
dev->device = (l >> 16) & 0xffff;
+
+ /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
+ set this higher, assuming the system even supports it. */
+ dev->dma_mask = 0xffffffff;
if (pci_setup_device(dev) < 0) {
kfree(dev);
dev = NULL;
@@ -902,12 +906,12 @@ static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
return max;
}
-static int __init pci_bus_exists(struct list_head *list, int nr)
+static int __init pci_bus_exists(const struct list_head *list, int nr)
{
- struct list_head *l;
+ const struct list_head *l;
for(l=list->next; l != list; l = l->next) {
- struct pci_bus *b = pci_bus_b(l);
+ const struct pci_bus *b = pci_bus_b(l);
if (b->number == nr || pci_bus_exists(&b->children, nr))
return 1;
}
diff --git a/drivers/pci/pcisyms.c b/drivers/pci/pcisyms.c
index 64b6a0f3e..0d0063783 100644
--- a/drivers/pci/pcisyms.c
+++ b/drivers/pci/pcisyms.c
@@ -28,6 +28,7 @@ EXPORT_SYMBOL(pci_set_power_state);
EXPORT_SYMBOL(pci_assign_resource);
EXPORT_SYMBOL(pci_register_driver);
EXPORT_SYMBOL(pci_unregister_driver);
+EXPORT_SYMBOL(pci_match_device);
#ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL(pci_setup_device);
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index b687d6122..36c3be081 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -43,8 +43,8 @@ proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
static ssize_t
proc_bus_pci_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
{
- struct inode *ino = file->f_dentry->d_inode;
- struct proc_dir_entry *dp = ino->u.generic_ip;
+ const struct inode *ino = file->f_dentry->d_inode;
+ const struct proc_dir_entry *dp = ino->u.generic_ip;
struct pci_dev *dev = dp->data;
int pos = *ppos;
int cnt, size;
@@ -125,8 +125,8 @@ proc_bus_pci_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
static ssize_t
proc_bus_pci_write(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
{
- struct inode *ino = file->f_dentry->d_inode;
- struct proc_dir_entry *dp = ino->u.generic_ip;
+ const struct inode *ino = file->f_dentry->d_inode;
+ const struct proc_dir_entry *dp = ino->u.generic_ip;
struct pci_dev *dev = dp->data;
int pos = *ppos;
int cnt;
@@ -192,17 +192,9 @@ proc_bus_pci_write(struct file *file, const char *buf, size_t nbytes, loff_t *pp
}
static struct file_operations proc_bus_pci_operations = {
- proc_bus_pci_lseek,
- proc_bus_pci_read,
- proc_bus_pci_write,
- NULL, /* readdir */
- NULL, /* poll */
- NULL, /* ioctl */
- NULL, /* mmap */
- NULL, /* no special open code */
- NULL, /* flush */
- NULL, /* no special release code */
- NULL /* can't fsync */
+ llseek: proc_bus_pci_lseek,
+ read: proc_bus_pci_read,
+ write: proc_bus_pci_write,
};
static struct inode_operations proc_bus_pci_inode_operations = {
@@ -218,13 +210,13 @@ static struct inode_operations proc_bus_pci_inode_operations = {
static int
get_pci_dev_info(char *buf, char **start, off_t pos, int count)
{
- struct pci_dev *dev;
+ const struct pci_dev *dev;
off_t at = 0;
int len, i, cnt;
cnt = 0;
pci_for_each_dev(dev) {
- struct pci_driver *drv = pci_dev_driver(dev);
+ const struct pci_driver *drv = pci_dev_driver(dev);
len = sprintf(buf, "%02x%02x\t%04x%04x\t%x",
dev->bus->number,
dev->devfn,
diff --git a/drivers/pcmcia/ricoh.h b/drivers/pcmcia/ricoh.h
index 3084dd5b9..3165d715d 100644
--- a/drivers/pcmcia/ricoh.h
+++ b/drivers/pcmcia/ricoh.h
@@ -30,7 +30,6 @@
#ifndef _LINUX_RICOH_H
#define _LINUX_RICOH_H
-#include <linux/config.h>
#define RF5C_MODE_CTL 0x1f /* Mode control */
#define RF5C_PWR_CTL 0x2f /* Mixed voltage control */
diff --git a/drivers/pnp/Makefile b/drivers/pnp/Makefile
index 9c024342a..d9b6fe96b 100644
--- a/drivers/pnp/Makefile
+++ b/drivers/pnp/Makefile
@@ -25,7 +25,7 @@ ifeq ($(CONFIG_ISAPNP),m)
endif
ifeq ($(CONFIG_ISAPNP),y)
- O_TARGET := isa-pnp.o
+ O_TARGET := pnp.o
OX_OBJS := isapnp.o
O_OBJS := quirks.o $(PROC_OBJS)
endif
@@ -33,5 +33,5 @@ endif
include $(TOPDIR)/Rules.make
-isa-pnp.o: isapnp.o quirks.o $(PROC_OBJS)
- $(LD) $(LD_RFLAG) -r -o $@ isapnp.o quirks.o $(PROC_OBJS)
+isa-pnp.o: $(MIX_OBJS) $(MI_OBJS)
+ $(LD) $(LD_RFLAG) -r -o $@ $(MIX_OBJS) $(MI_OBJS)
diff --git a/drivers/pnp/isapnp.c b/drivers/pnp/isapnp.c
index ec81da498..073248758 100644
--- a/drivers/pnp/isapnp.c
+++ b/drivers/pnp/isapnp.c
@@ -436,6 +436,7 @@ static struct pci_dev * __init isapnp_parse_device(struct pci_bus *card, int siz
dev = isapnp_alloc(sizeof(struct pci_dev));
if (!dev)
return NULL;
+ dev->dma_mask = 0x00ffffff;
dev->devfn = number;
dev->vendor = (tmp[1] << 8) | tmp[0];
dev->device = (tmp[3] << 8) | tmp[2];
diff --git a/drivers/sbus/audio/amd7930.c b/drivers/sbus/audio/amd7930.c
index 1cb739719..f3f593bce 100644
--- a/drivers/sbus/audio/amd7930.c
+++ b/drivers/sbus/audio/amd7930.c
@@ -1,4 +1,4 @@
-/* $Id: amd7930.c,v 1.23 1999/11/19 09:55:58 davem Exp $
+/* $Id: amd7930.c,v 1.24 2000/01/22 05:10:27 anton Exp $
* drivers/sbus/audio/amd7930.c
*
* Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu)
@@ -1375,7 +1375,7 @@ static int amd7930_bopen(int dev, unsigned int chan,
/* Enable B channel transmit */
sbus_writeb(AMR_LIU_LMR1, info->regs + CR);
tmp = sbus_readb(info->regs + DR);
- tmp |= AM_LIU_LMR1_B1_ENBL + chan;
+ tmp |= AM_LIU_LMR1_B1_ENABL + chan;
sbus_writeb(tmp, info->regs + DR);
/* Enable B channel interrupts */
@@ -1701,7 +1701,7 @@ int __init amd7930_init(void)
continue;
if (amd7930_attach(&drivers[num_drivers],
- sdev->prom_node, sdev->my_bus, sdev) == 0)
+ sdev->prom_node, sdev->bus, sdev) == 0)
num_drivers++;
}
}
diff --git a/drivers/sbus/audio/cs4231.c b/drivers/sbus/audio/cs4231.c
index 2d46a84e3..442c25206 100644
--- a/drivers/sbus/audio/cs4231.c
+++ b/drivers/sbus/audio/cs4231.c
@@ -1170,25 +1170,28 @@ static int cs4231_open(struct inode * inode, struct file * file, struct sparcaud
static void cs4231_release(struct inode * inode, struct file * file, struct sparcaudio_driver *drv)
{
- struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
+ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
+ void (*dma_unmap_single)(struct sbus_dev *, dma_addr_t, size_t) = sbus_unmap_single;
+#ifdef EB4231_SUPPORT
+ if (cs4231_chip->status & CS_STATUS_IS_EBUS)
+ dma_unmap_single = (void (*)(struct sbus_dev *, dma_addr_t, size_t)) pci_unmap_single;
+#endif
/* zero out any info about what data we have as well */
if (file->f_mode & FMODE_READ) {
/* stop capture here or midlevel? */
cs4231_chip->perchip_info.record.open = 0;
if (cs4231_chip->input_dma_handle) {
- if(!(cs4231_chip->status & CS_STATUS_IS_EBUS))
- sbus_unmap_single(drv->dev,
- cs4231_chip->input_dma_handle,
- cs4231_chip->input_dma_size);
+ dma_unmap_single(drv->dev,
+ cs4231_chip->input_dma_handle,
+ cs4231_chip->input_dma_size);
cs4231_chip->input_dma_handle = 0;
cs4231_chip->input_dma_size = 0;
}
if (cs4231_chip->input_next_dma_handle) {
- if(!(cs4231_chip->status & CS_STATUS_IS_EBUS))
- sbus_unmap_single(drv->dev,
- cs4231_chip->input_next_dma_handle,
- cs4231_chip->input_next_dma_size);
+ dma_unmap_single(drv->dev,
+ cs4231_chip->input_next_dma_handle,
+ cs4231_chip->input_next_dma_size);
cs4231_chip->input_next_dma_handle = 0;
cs4231_chip->input_next_dma_size = 0;
}
@@ -1198,18 +1201,16 @@ static void cs4231_release(struct inode * inode, struct file * file, struct spar
cs4231_chip->perchip_info.play.active =
cs4231_chip->perchip_info.play.open = 0;
if (cs4231_chip->output_dma_handle) {
- if(!(cs4231_chip->status & CS_STATUS_IS_EBUS))
- sbus_unmap_single(drv->dev,
- cs4231_chip->output_dma_handle,
- cs4231_chip->output_dma_size);
+ dma_unmap_single(drv->dev,
+ cs4231_chip->output_dma_handle,
+ cs4231_chip->output_dma_size);
cs4231_chip->output_dma_handle = 0;
cs4231_chip->output_dma_size = 0;
}
if (cs4231_chip->output_next_dma_handle) {
- if(!(cs4231_chip->status & CS_STATUS_IS_EBUS))
- sbus_unmap_single(drv->dev,
- cs4231_chip->output_next_dma_handle,
- cs4231_chip->output_next_dma_size);
+ dma_unmap_single(drv->dev,
+ cs4231_chip->output_next_dma_handle,
+ cs4231_chip->output_next_dma_size);
cs4231_chip->output_next_dma_handle = 0;
cs4231_chip->output_next_dma_size = 0;
}
@@ -1294,6 +1295,9 @@ static void eb4231_playintr(struct sparcaudio_driver *drv)
cs4231_chip->playlen = cs4231_chip->output_size;
if (cs4231_chip->output_dma_handle) {
+ pci_unmap_single((struct pci_dev *)drv->dev,
+ cs4231_chip->output_dma_handle,
+ cs4231_chip->output_dma_size);
cs4231_chip->output_dma_handle = 0;
cs4231_chip->output_dma_size = 0;
cs4231_chip->playing_count--;
@@ -1310,7 +1314,9 @@ static void eb4231_playintr(struct sparcaudio_driver *drv)
if ((cs4231_chip->output_ptr && cs4231_chip->output_size > 0) &&
!(cs4231_chip->perchip_info.play.pause)) {
cs4231_chip->output_next_dma_handle =
- virt_to_bus(cs4231_chip->output_ptr);
+ pci_map_single((struct pci_dev *)drv->dev,
+ (char *)cs4231_chip->output_ptr,
+ cs4231_chip->output_size);
cs4231_chip->output_next_dma_size = cs4231_chip->output_size;
writel(cs4231_chip->output_next_dma_size,
@@ -1410,6 +1416,9 @@ static int eb4231_recintr(struct sparcaudio_driver *drv)
}
if (cs4231_chip->input_dma_handle) {
+ pci_unmap_single((struct pci_dev *)drv->dev,
+ cs4231_chip->input_dma_handle,
+ cs4231_chip->input_dma_size);
cs4231_chip->input_dma_handle = 0;
cs4231_chip->input_dma_size = 0;
cs4231_chip->recording_count--;
@@ -1430,7 +1439,9 @@ static int eb4231_recintr(struct sparcaudio_driver *drv)
cs4231_chip->input_size);
cs4231_chip->input_next_dma_handle =
- virt_to_bus(cs4231_chip->input_ptr);
+ pci_map_single((struct pci_dev *)drv->dev,
+ (char *)cs4231_chip->input_ptr,
+ cs4231_chip->input_size);
cs4231_chip->input_next_dma_size = cs4231_chip->input_size;
writel(cs4231_chip->input_next_dma_size,
@@ -1543,11 +1554,17 @@ static void eb4231_stop_output(struct sparcaudio_driver *drv)
cs4231_chip->output_size = 0;
if (cs4231_chip->output_dma_handle) {
+ pci_unmap_single((struct pci_dev *)drv->dev,
+ cs4231_chip->output_dma_handle,
+ cs4231_chip->output_dma_size);
cs4231_chip->output_dma_handle = 0;
cs4231_chip->output_dma_size = 0;
}
if (cs4231_chip->output_next_dma_handle) {
+ pci_unmap_single((struct pci_dev *)drv->dev,
+ cs4231_chip->output_next_dma_handle,
+ cs4231_chip->output_next_dma_size);
cs4231_chip->output_next_dma_handle = 0;
cs4231_chip->output_next_dma_size = 0;
}
@@ -1746,11 +1763,17 @@ static void eb4231_stop_input(struct sparcaudio_driver *drv)
cs4231_chip->input_size = 0;
if (cs4231_chip->input_dma_handle) {
+ pci_unmap_single((struct pci_dev *)drv->dev,
+ cs4231_chip->input_dma_handle,
+ cs4231_chip->input_dma_size);
cs4231_chip->input_dma_handle = 0;
cs4231_chip->input_dma_size = 0;
}
if (cs4231_chip->input_next_dma_handle) {
+ pci_unmap_single((struct pci_dev *)drv->dev,
+ cs4231_chip->input_next_dma_handle,
+ cs4231_chip->input_next_dma_size);
cs4231_chip->input_next_dma_handle = 0;
cs4231_chip->input_next_dma_size = 0;
}
@@ -2236,6 +2259,8 @@ static int eb4231_attach(struct sparcaudio_driver *drv,
cs4231_chip->input_size = cs4231_chip->output_size = 0;
cs4231_chip->status = 0;
+ drv->dev = (struct sbus_dev *)edev->bus->self;
+
len = prom_getproperty(edev->prom_node, "reg", (void *)regs, sizeof(regs));
if ((len % sizeof(regs[0])) != 0) {
printk("eb4231: Strange reg property size %d\n", len);
diff --git a/drivers/sbus/audio/dbri.c b/drivers/sbus/audio/dbri.c
index 66a34b35c..0b73b8e0d 100644
--- a/drivers/sbus/audio/dbri.c
+++ b/drivers/sbus/audio/dbri.c
@@ -1,4 +1,4 @@
-/* $Id: dbri.c,v 1.16 1999/11/19 09:56:05 davem Exp $
+/* $Id: dbri.c,v 1.17 2000/01/20 07:57:47 anton Exp $
* drivers/sbus/audio/dbri.c
*
* Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de)
@@ -225,8 +225,8 @@ static void dbri_detach(struct dbri *dbri)
dbri_reset(dbri);
free_irq(dbri->irq, dbri);
sbus_iounmap(dbri->regs, dbri->regs_size);
- sbus_free_consistant(dbri->sdev, sizeof(struct dbri_dma),
- dbri->dma, dbry->dma_dvma);
+ sbus_free_consistent(dbri->sdev, sizeof(struct dbri_dma),
+ dbri->dma, dbri->dma_dvma);
kfree(dbri);
}
@@ -999,7 +999,7 @@ static void recv_on_pipe(struct dbri *dbri, int pipe,
/* Make sure buffer size is multiple of four */
len &= ~3;
- buf_buffer_base = buf_buffer = sbus_map_single(dbri->sdev, buffer, len);
+ bus_buffer_base = bus_buffer = sbus_map_single(dbri->sdev, buffer, len);
while (len > 0) {
int rd, mylen;
@@ -2232,7 +2232,7 @@ static int dbri_attach(struct sparcaudio_driver *drv,
dbri = (struct dbri *) drv->private;
memset(dbri, 0, sizeof(*dbri));
- dbri->dma = sbus_alloc_consistant(sdev,
+ dbri->dma = sbus_alloc_consistent(sdev,
sizeof(struct dbri_dma),
&dbri->dma_dvma);
@@ -2251,7 +2251,7 @@ static int dbri_attach(struct sparcaudio_driver *drv,
"DBRI Registers");
if (!dbri->regs) {
printk(KERN_ERR "DBRI: could not allocate registers\n");
- sbus_free_consistant(sdev, sizeof(struct dbri_dma),
+ sbus_free_consistent(sdev, sizeof(struct dbri_dma),
dbri->dma, dbri->dma_dvma);
kfree(drv->private);
return -EIO;
@@ -2265,7 +2265,7 @@ static int dbri_attach(struct sparcaudio_driver *drv,
if (err) {
printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq);
sbus_iounmap(dbri->regs, dbri->regs_size);
- sbus_free_consistant(sdev, sizeof(struct dbri_dma),
+ sbus_free_consistent(sdev, sizeof(struct dbri_dma),
dbri->dma, dbri->dma_dvma);
kfree(drv->private);
return err;
diff --git a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile
index 9a4a59fe6..4a88efda3 100644
--- a/drivers/sbus/char/Makefile
+++ b/drivers/sbus/char/Makefile
@@ -103,6 +103,13 @@ else
endif
endif
+ifeq ($(CONFIG_SUN_JSFLASH),y)
+O_OBJS += jsflash.o
+endif
+ifeq ($(CONFIG_SUN_JSFLASH),m)
+M_OBJS += jsflash.o
+endif
+
include $(TOPDIR)/Rules.make
sunkbdmap.o: sunkeymap.c
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index ab4ff4f90..14f074023 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -191,12 +191,21 @@ static ssize_t jsf_read(struct file * file, char * buf,
}
if (p < JSF_BASE_ALL && togo != 0) {
+#if 0 /* __bzero XXX */
size_t x = JSF_BASE_ALL - p;
if (x > togo) x = togo;
clear_user(tmp, x);
tmp += x;
p += x;
togo -= x;
+#else
+ /*
+ * Implementation of clear_user() calls __bzero
+ * without regard to modversions,
+ * so we cannot build a module.
+ */
+ return 0;
+#endif
}
while (togo >= 4) {
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
index f46cffe1b..6d9decaf3 100644
--- a/drivers/sbus/char/uctrl.c
+++ b/drivers/sbus/char/uctrl.c
@@ -1,4 +1,4 @@
-/* $Id: uctrl.c,v 1.5 1999/12/15 15:48:24 davem Exp $
+/* $Id: uctrl.c,v 1.6 2000/01/22 05:22:07 anton Exp $
* uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3
*
* Copyright 1999 Derrick J Brashear (shadow@dementia.org)
@@ -380,7 +380,7 @@ void uctrl_get_external_status()
#ifdef MODULE
int init_module(void)
#else
-int __init uctrl_init(void)
+int __init ts102_uctrl_init(void)
#endif
{
struct uctrl_driver *driver = &drv;
diff --git a/drivers/sbus/char/vfc_i2c.c b/drivers/sbus/char/vfc_i2c.c
index 2538c935f..6731caa78 100644
--- a/drivers/sbus/char/vfc_i2c.c
+++ b/drivers/sbus/char/vfc_i2c.c
@@ -115,7 +115,7 @@ int vfc_i2c_reset_bus(struct vfc_dev *dev)
{
VFC_I2C_DEBUG_PRINTK((KERN_DEBUG "vfc%d: Resetting the i2c bus\n",
dev->instance));
- if(dev == NULl)
+ if(dev == NULL)
return -EINVAL;
if(dev->regs == NULL)
return -EINVAL;
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
new file mode 100644
index 000000000..5477bb1ac
--- /dev/null
+++ b/drivers/scsi/3w-xxxx.c
@@ -0,0 +1,2223 @@
+/*
+ 3w-xxxx.c -- 3ware Storage Controller device driver for Linux.
+
+ Written By: Adam Radford <linux@3ware.com>
+ Copyright (C) 1999-2000 3ware Inc.
+
+ Kernel compatablity By: Andre Hedrick <andre@suse.com>
+ Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com>
+
+ Further tiny build fixes and trivial hoovering Alan Cox
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ 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.
+
+ NO WARRANTY
+ THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+ LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+ solely responsible for determining the appropriateness of using and
+ distributing the Program and assumes all risks associated with its
+ exercise of rights under this Agreement, including but not limited to
+ the risks and costs of program errors, damage to or loss of data,
+ programs or equipment, and unavailability or interruption of operations.
+
+ DISCLAIMER OF LIABILITY
+ NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+ HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+ 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
+
+ Bugs/Comments/Suggestions should be mailed to:
+ linux@3ware.com
+
+ For more information, goto:
+ http://www.3ware.com
+*/
+
+#include <linux/module.h>
+
+MODULE_AUTHOR ("3ware Inc.");
+MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver");
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/time.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/blk.h>
+#include <linux/hdreg.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#define __3W_C /* let 3w-xxxx.h know it is use */
+
+#include "sd.h"
+#include "scsi.h"
+#include "hosts.h"
+
+#include "3w-xxxx.h"
+
+static int tw_copy_info(TW_Info *info, char *fmt, ...);
+static void tw_copy_mem_info(TW_Info *info, char *data, int len);
+static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+
+/* Globals */
+char *tw_driver_version="0.4.001";
+TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
+int tw_device_extension_count = 0;
+
+/* Functions */
+
+/* This function will complete an aen request from the isr */
+int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
+{
+ TW_Param *param;
+ unsigned short aen, aen_code;
+
+ if (tw_dev->alignment_virtual_address[request_id] == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
+ return 1;
+ }
+ param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+ aen = *(unsigned short *)(param->data);
+ aen_code = (aen & 0x0ff);
+ dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen_code);
+ /* Now queue the code */
+ tw_dev->aen_queue[tw_dev->aen_tail] = aen_code;
+ if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
+ tw_dev->aen_tail = TW_Q_START;
+ } else {
+ tw_dev->aen_tail = tw_dev->aen_tail + 1;
+ }
+ if (tw_dev->aen_head == tw_dev->aen_tail) {
+ if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
+ tw_dev->aen_head = TW_Q_START;
+ } else {
+ tw_dev->aen_head = tw_dev->aen_head + 1;
+ }
+ }
+ tw_dev->state[request_id] = TW_S_COMPLETED;
+ tw_state_request_finish(tw_dev, request_id);
+
+ return 0;
+} /* End tw_aen_complete() */
+
+/* This function will drain the aen queue after a soft reset */
+int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
+{
+ TW_Command *command_packet;
+ TW_Param *param;
+ int tries = 0;
+ int request_id = 0;
+ u32 command_que_value = 0, command_que_addr;
+ u32 status_reg_value = 0, status_reg_addr;
+ u32 param_value;
+ TW_Response_Queue response_queue;
+ u32 response_que_addr;
+ unsigned short aen;
+ unsigned short aen_code;
+ int finished = 0;
+ int first_reset = 0;
+ int queue = 0;
+ int imax, i;
+ int found = 0;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n");
+
+ command_que_addr = tw_dev->registers.command_que_addr;
+ status_reg_addr = tw_dev->registers.status_reg_addr;
+ response_que_addr = tw_dev->registers.response_que_addr;
+
+ if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT, 15)) {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d\n", tw_dev->host->host_no);
+ return 1;
+ }
+
+ /* Initialize command packet */
+ if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet virtual address.\n");
+ return 1;
+ }
+ command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+ memset(command_packet, 0, sizeof(TW_Sector));
+ command_packet->byte0.opcode = TW_OP_GET_PARAM;
+ command_packet->byte0.sgl_offset = 2;
+ command_packet->size = 4;
+ command_packet->request_id = request_id;
+ command_packet->byte3.unit = 0;
+ command_packet->byte3.host_id = 0;
+ command_packet->status = 0;
+ command_packet->flags = 0;
+ command_packet->byte6.parameter_count = 1;
+ command_que_value = tw_dev->command_packet_physical_address[request_id];
+ if (command_que_value == 0) {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet physical address.\n");
+ return 1;
+ }
+
+ /* Now setup the param */
+ if (tw_dev->alignment_virtual_address[request_id] == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment virtual address.\n");
+ return 1;
+ }
+ param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+ memset(param, 0, sizeof(TW_Sector));
+ param->table_id = 0x401; /* AEN table */
+ param->parameter_id = 2; /* Unit code */
+ param->parameter_size_bytes = 2;
+ param_value = tw_dev->alignment_physical_address[request_id];
+ if (param_value == 0) {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment physical address.\n");
+ return 1;
+ }
+ command_packet->byte8.param.sgl[0].address = param_value;
+ command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
+
+ imax = TW_POLL_MAX_RETRIES;
+
+ /* Now drain the controller's aen queue */
+ do {
+ /* Post command packet */
+ outl(command_que_value, command_que_addr);
+
+ /* Now poll for completion */
+ for (i=0;i<imax;i++) {
+ mdelay(10);
+ status_reg_value = inl(status_reg_addr);
+ if (tw_check_bits(status_reg_value)) {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected bits.\n");
+ return 1;
+ }
+ if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
+ response_queue.value = inl(response_que_addr);
+ request_id = (unsigned char)response_queue.u.response_id;
+
+ if (request_id != 0) {
+ /* Unexpected request id */
+ printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected request id.\n");
+ return 1;
+ }
+
+ if (command_packet->status != 0) {
+ if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
+ /* Bad response */
+ printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, flags = 0x%x.\n", command_packet->flags);
+ return 1;
+ } else {
+ /* We know this is a 3w-1x00, and doesn't support aen's */
+ return 0;
+ }
+ }
+
+ /* Now check the aen */
+ aen = *(unsigned short *)(param->data);
+ aen_code = (aen & 0x0ff);
+ queue = 0;
+ switch (aen_code) {
+ case TW_AEN_QUEUE_EMPTY:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_QUEUE_EMPTY.\n");
+ if (first_reset != 1) {
+ continue;
+ } else {
+ finished = 1;
+ }
+ break;
+ case TW_AEN_SOFT_RESET:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_SOFT_RESET.\n");
+ if (first_reset == 0) {
+ first_reset = 1;
+ } else {
+ queue = 1;
+ }
+ break;
+ case TW_AEN_DEGRADED_MIRROR:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_DEGRADED_MIRROR.\n");
+ queue = 1;
+ break;
+ case TW_AEN_CONTROLLER_ERROR:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_CONTROLLER_ERROR.\n");
+ queue = 1;
+ break;
+ case TW_AEN_REBUILD_FAIL:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_REBUILD_FAIL.\n");
+ queue = 1;
+ break;
+ case TW_AEN_REBUILD_DONE:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_REBUILD_DONE.\n");
+ queue = 1;
+ break;
+ case TW_AEN_QUEUE_FULL:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_QUEUE_FULL.\n");
+ queue = 1;
+ break;
+ default:
+ dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unknown AEN code 0x%x.\n", aen_code);
+ queue = 1;
+ }
+
+ /* Now put the aen on the aen_queue */
+ if (queue == 1) {
+ tw_dev->aen_queue[tw_dev->aen_tail] = aen_code;
+ if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
+ tw_dev->aen_tail = TW_Q_START;
+ } else {
+ tw_dev->aen_tail = tw_dev->aen_tail + 1;
+ }
+ if (tw_dev->aen_head == tw_dev->aen_tail) {
+ if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
+ tw_dev->aen_head = TW_Q_START;
+ } else {
+ tw_dev->aen_head = tw_dev->aen_head + 1;
+ }
+ }
+ }
+ found = 1;
+ break;
+ }
+ }
+ if (found == 0) {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Response never received.\n");
+ return 1;
+ }
+ tries++;
+ } while ((tries < TW_MAX_AEN_TRIES) && (finished == 0));
+
+ if (tries >=TW_MAX_AEN_TRIES) {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Aen queue error.\n");
+ return 1;
+ }
+
+ return 0;
+} /* End tw_aen_drain_queue() */
+
+/* This function will read the aen queue from the isr */
+int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
+{
+ TW_Command *command_packet;
+ TW_Param *param;
+ u32 command_que_value = 0, command_que_addr;
+ u32 status_reg_value = 0, status_reg_addr;
+ u32 param_value = 0;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_aen_read_queue()\n");
+ command_que_addr = tw_dev->registers.command_que_addr;
+ status_reg_addr = tw_dev->registers.status_reg_addr;
+
+ status_reg_value = inl(status_reg_addr);
+ if (tw_check_bits(status_reg_value)) {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
+ return 1;
+ }
+ if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet virtual address.\n");
+ return 1;
+ }
+ command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+ memset(command_packet, 0, sizeof(TW_Sector));
+ command_packet->byte0.opcode = TW_OP_GET_PARAM;
+ command_packet->byte0.sgl_offset = 2;
+ command_packet->size = 4;
+ command_packet->request_id = request_id;
+ command_packet->byte3.unit = 0;
+ command_packet->byte3.host_id = 0;
+ command_packet->status = 0;
+ command_packet->flags = 0;
+ command_packet->byte6.parameter_count = 1;
+ command_que_value = tw_dev->command_packet_physical_address[request_id];
+ if (command_que_value == 0) {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet physical address.\n");
+ return 1;
+ }
+ /* Now setup the param */
+ if (tw_dev->alignment_virtual_address[request_id] == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment virtual address.\n");
+ return 1;
+ }
+ param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+ memset(param, 0, sizeof(TW_Sector));
+ param->table_id = 0x401; /* AEN table */
+ param->parameter_id = 2; /* Unit code */
+ param->parameter_size_bytes = 2;
+ param_value = tw_dev->alignment_physical_address[request_id];
+ if (param_value == 0) {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment physical address.\n");
+ return 1;
+ }
+ command_packet->byte8.param.sgl[0].address = param_value;
+ command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
+
+ /* Now post the command packet */
+ if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
+ dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post succeeded.\n");
+ tw_dev->srb[request_id] = 0; /* Flag internal command */
+ tw_dev->state[request_id] = TW_S_POSTED;
+ outl(command_que_value, command_que_addr);
+ } else {
+ printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post failed, will retry.\n");
+ return 1;
+ }
+
+ return 0;
+} /* End tw_aen_read_queue() */
+
+/* This function will allocate memory and check if it is 16 d-word aligned */
+int tw_allocate_memory(TW_Device_Extension *tw_dev, int request_id, int size, int which)
+{
+ u32 *virt_addr;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_allocate_memory()\n");
+
+ if (which == 0) {
+ /* Allocate command packet memory */
+ virt_addr = kmalloc(size, GFP_ATOMIC);
+ if (virt_addr == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): kmalloc() failed.\n");
+ return 1;
+ }
+ if ((u32)virt_addr % TW_ALIGNMENT) {
+ printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): Found unaligned address.\n");
+ return 1;
+ }
+ tw_dev->command_packet_virtual_address[request_id] = virt_addr;
+ tw_dev->command_packet_physical_address[request_id] =
+ virt_to_bus(virt_addr);
+ } else {
+ /* Allocate generic buffer */
+ virt_addr = kmalloc(size, GFP_ATOMIC);
+ if (virt_addr == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): kmalloc() failed.\n");
+ return 1;
+ }
+ if ((u32)virt_addr % TW_ALIGNMENT) {
+ printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): Found unaligned address.\n");
+ return 1;
+ }
+ tw_dev->alignment_virtual_address[request_id] = virt_addr;
+ tw_dev->alignment_physical_address[request_id] = virt_to_bus(virt_addr);
+ }
+ return 0;
+} /* End tw_allocate_memory() */
+
+/* This function will check the status register for unexpected bits */
+int tw_check_bits(u32 status_reg_value)
+{
+ if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) {
+ printk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value);
+ return 1;
+ }
+ if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0) {
+ printk(KERN_WARNING "3w-xxxx: tw_check_bits(): Found unexpected bits (0x%x).\n", status_reg_value);
+ return 1;
+ }
+
+ return 0;
+} /* End tw_check_bits() */
+
+/* This function will report controller error status */
+int tw_check_errors(TW_Device_Extension *tw_dev)
+{
+ u32 status_reg_addr, status_reg_value;
+
+ status_reg_addr = tw_dev->registers.status_reg_addr;
+ status_reg_value = inl(status_reg_addr);
+
+ if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value))
+ return 1;
+
+ return 0;
+} /* End tw_check_errors() */
+
+/* This function will clear the attention interrupt */
+void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev)
+{
+ u32 control_reg_addr, control_reg_value;
+
+ control_reg_addr = tw_dev->registers.control_reg_addr;
+ control_reg_value = TW_CONTROL_CLEAR_ATTENTION_INTERRUPT;
+ outl(control_reg_value, control_reg_addr);
+} /* End tw_clear_attention_interrupt() */
+
+/* This function will clear the host interrupt */
+void tw_clear_host_interrupt(TW_Device_Extension *tw_dev)
+{
+ u32 control_reg_addr, control_reg_value;
+
+ control_reg_addr = tw_dev->registers.control_reg_addr;
+ control_reg_value = TW_CONTROL_CLEAR_HOST_INTERRUPT;
+ outl(control_reg_value, control_reg_addr);
+} /* End tw_clear_host_interrupt() */
+
+/* This function is called by tw_scsi_proc_info */
+static int tw_copy_info(TW_Info *info, char *fmt, ...)
+{
+ va_list args;
+ char buf[81];
+ int len;
+
+ va_start(args, fmt);
+ len = vsprintf(buf, fmt, args);
+ va_end(args);
+ tw_copy_mem_info(info, buf, len);
+ return len;
+} /* End tw_copy_info() */
+
+/* This function is called by tw_scsi_proc_info */
+static void tw_copy_mem_info(TW_Info *info, char *data, int len)
+{
+ if (info->position + len > info->length)
+ len = info->length - info->position;
+
+ if (info->position + len < info->offset) {
+ info->position += len;
+ return;
+ }
+ if (info->position < info->offset) {
+ data += (info->offset - info->position);
+ len -= (info->offset - info->position);
+ }
+ if (len > 0) {
+ memcpy(info->buffer + info->position, data, len);
+ info->position += len;
+ }
+} /* End tw_copy_mem_info() */
+
+/* This function will disable interrupts on the controller */
+void tw_disable_interrupts(TW_Device_Extension *tw_dev)
+{
+ u32 control_reg_value, control_reg_addr;
+
+ control_reg_addr = tw_dev->registers.control_reg_addr;
+ control_reg_value = TW_CONTROL_DISABLE_INTERRUPTS;
+ outl(control_reg_value, control_reg_addr);
+} /* End tw_disable_interrupts() */
+
+/* This function will empty the response que */
+int tw_empty_response_que(TW_Device_Extension *tw_dev)
+{
+ u32 status_reg_addr, status_reg_value;
+ u32 response_que_addr, response_que_value;
+
+ status_reg_addr = tw_dev->registers.status_reg_addr;
+ response_que_addr = tw_dev->registers.response_que_addr;
+
+ status_reg_value = inl(status_reg_addr);
+
+ if (tw_check_bits(status_reg_value)) {
+ printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 1.\n");
+ return 1;
+ }
+
+ while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
+ response_que_value = inl(response_que_addr);
+ status_reg_value = inl(status_reg_addr);
+ if (tw_check_bits(status_reg_value)) {
+ printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 2.\n");
+ return 1;
+ }
+ }
+ return 0;
+} /* End tw_empty_response_que() */
+
+/* This function will enable interrupts on the controller */
+void tw_enable_interrupts(TW_Device_Extension *tw_dev)
+{
+ u32 control_reg_value, control_reg_addr;
+
+ control_reg_addr = tw_dev->registers.control_reg_addr;
+ control_reg_value = (TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |
+ TW_CONTROL_UNMASK_RESPONSE_INTERRUPT |
+ TW_CONTROL_ENABLE_INTERRUPTS);
+ outl(control_reg_value, control_reg_addr);
+} /* End tw_enable_interrupts() */
+
+/* This function will find and initialize all cards */
+int tw_findcards(Scsi_Host_Template *tw_host)
+{
+ int numcards = 0, tries = 0, error = 0;
+ struct Scsi_Host *host;
+ TW_Device_Extension *tw_dev;
+ TW_Device_Extension *tw_dev2;
+ struct pci_dev *tw_pci_dev = NULL;
+ u32 status_reg_value;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n");
+ while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, TW_DEVICE_ID, tw_pci_dev))) {
+ /* Prepare temporary device extension */
+ tw_dev=(TW_Device_Extension *)kmalloc(sizeof(TW_Device_Extension), GFP_ATOMIC);
+ if (tw_dev == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_findcards(): kmalloc() failed for card %d.\n", numcards);
+ continue;
+ }
+ memset(tw_dev, 0, sizeof(TW_Device_Extension));
+
+ error = tw_initialize_device_extension(tw_dev);
+ if (error) {
+ printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize device extension for card %d.\n", numcards);
+ tw_free_device_extension(tw_dev);
+ kfree(tw_dev);
+ continue;
+ }
+
+ /* Calculate the cards register addresses */
+ tw_dev->registers.base_addr = tw_pci_dev->resource[0].start;
+ tw_dev->registers.control_reg_addr = (tw_pci_dev->resource[0].start & ~15);
+ tw_dev->registers.status_reg_addr = ((tw_pci_dev->resource[0].start & ~15) + 0x4);
+ tw_dev->registers.command_que_addr = ((tw_pci_dev->resource[0].start & ~15) + 0x8);
+ tw_dev->registers.response_que_addr = ((tw_pci_dev->resource[0].start & ~15) + 0xC);
+ /* Save pci_dev struct to device extension */
+ tw_dev->tw_pci_dev = tw_pci_dev;
+
+ /* Poll status register for 60 secs for 'Controller Ready' flag */
+ if (tw_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY, 60)) {
+ printk(KERN_WARNING "3w-xxxx: tw_findcards(): Microcontroller not ready for card %d.\n", numcards);
+ tw_free_device_extension(tw_dev);
+ kfree(tw_dev);
+ continue;
+ }
+
+ /* Disable interrupts on the card */
+ tw_disable_interrupts(tw_dev);
+
+ while (tries < TW_MAX_RESET_TRIES) {
+ /* Do soft reset */
+ tw_soft_reset(tw_dev);
+
+ error = tw_aen_drain_queue(tw_dev);
+ if (error) {
+ printk(KERN_WARNING "3w-xxxx: tw_findcards(): No attention interrupt for card %d.\n", numcards);
+ tries++;
+ continue;
+ }
+
+ /* Check for controller errors */
+ if (tw_check_errors(tw_dev)) {
+ printk(KERN_WARNING "3w-xxxx: tw_findcards(): Controller errors found, soft resetting card %d.\n", numcards);
+ tries++;
+ continue;
+ }
+
+ /* Empty the response queue */
+ error = tw_empty_response_que(tw_dev);
+ if (error) {
+ printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't empty response queue for card %d.\n", numcards);
+ tries++;
+ continue;
+ }
+
+ /* Now the controller is in a good state */
+ break;
+ }
+
+ if (tries >= TW_MAX_RESET_TRIES) {
+ printk(KERN_WARNING "3w-xxxx: tw_findcards(): Controller error or no attention interrupt: giving up for card %d.\n", numcards);
+ tw_free_device_extension(tw_dev);
+ kfree(tw_dev);
+ continue;
+ }
+
+ /* Make sure that io region isn't already taken */
+ if (check_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE)) {
+ printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't get io range 0x%lx-0x%lx for card %d.\n",
+ (tw_dev->tw_pci_dev->resource[0].start),
+ (tw_dev->tw_pci_dev->resource[0].start) +
+ TW_IO_ADDRESS_RANGE, numcards);
+ tw_free_device_extension(tw_dev);
+ kfree(tw_dev);
+ continue;
+ }
+
+ /* Reserve the io address space */
+ request_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE, TW_DEVICE_NAME);
+ error = tw_initialize_units(tw_dev);
+ if (error) {
+ printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize units for card %d.\n", numcards);
+ release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
+ tw_free_device_extension(tw_dev);
+ kfree(tw_dev);
+ continue;
+ }
+
+ error = tw_initconnection(tw_dev);
+ if (error) {
+ printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initconnection for card %d.\n", numcards);
+ release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
+ tw_free_device_extension(tw_dev);
+ kfree(tw_dev);
+ continue;
+ }
+
+ /* Calculate max cmds per lun */
+ if (tw_dev->num_units > 0)
+ tw_host->cmd_per_lun = (TW_Q_LENGTH-2)/tw_dev->num_units;
+
+ /* Register the card with the kernel SCSI layer */
+ host = scsi_register(tw_host, sizeof(TW_Device_Extension));
+
+ /* FIXME - check for NULL */
+
+ status_reg_value = inl(tw_dev->registers.status_reg_addr);
+
+ dprintk(KERN_NOTICE "scsi%d : Found a 3ware Storage Controller at 0x%x, IRQ: %d P-chip: %d.%d\n", host->host_no,
+ (u32)(tw_pci_dev->resource[0].start), tw_pci_dev->irq,
+ (status_reg_value & TW_STATUS_MAJOR_VERSION_MASK) >> 28,
+ (status_reg_value & TW_STATUS_MINOR_VERSION_MASK) >> 24);
+
+ if (host->hostdata) {
+ tw_dev2 = (TW_Device_Extension *)host->hostdata;
+ memcpy(tw_dev2, tw_dev, sizeof(TW_Device_Extension));
+ tw_device_extension_list[tw_device_extension_count] = tw_dev2;
+ numcards++;
+ tw_device_extension_count = numcards;
+ tw_dev2->host = host;
+ } else {
+ printk(KERN_WARNING "3w-xxxx: tw_findcards(): Bad scsi host data for card %d.\n", numcards-1);
+ scsi_unregister(host);
+ release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
+ tw_free_device_extension(tw_dev);
+ kfree(tw_dev);
+ continue;
+ }
+
+ /* Re-enable interrupts on the card */
+ tw_enable_interrupts(tw_dev2);
+
+ /* Now setup the interrupt handler */
+ error = tw_setup_irq(tw_dev2);
+ if (error) {
+ printk(KERN_WARNING "3w-xxxx: tw_findcards(): Error requesting irq for card %d.\n", numcards-1);
+ scsi_unregister(host);
+ release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
+
+ tw_free_device_extension(tw_dev);
+ kfree(tw_dev);
+ numcards--;
+ continue;
+ }
+
+ /* Free the temporary device extension */
+ if (tw_dev)
+ kfree(tw_dev);
+ }
+
+ if (numcards == 0)
+ printk(KERN_WARNING "3w-xxxx: tw_findcards(): No cards found.\n");
+
+ return numcards;
+} /* End tw_findcards() */
+
+/* This function will free up device extension resources */
+void tw_free_device_extension(TW_Device_Extension *tw_dev)
+{
+ int i, imax;
+ imax = TW_Q_LENGTH;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n");
+ /* Free command packet and generic buffer memory */
+ for (i=0;i<imax;i++) {
+ if (tw_dev->command_packet_virtual_address[i])
+ kfree(tw_dev->command_packet_virtual_address[i]);
+
+ if (tw_dev->alignment_virtual_address[i])
+ kfree(tw_dev->alignment_virtual_address[i]);
+ }
+} /* End tw_free_device_extension() */
+
+/* This function will send an initconnection command to controller */
+int tw_initconnection(TW_Device_Extension *tw_dev)
+{
+ u32 command_que_addr, command_que_value;
+ u32 status_reg_addr, status_reg_value;
+ u32 response_que_addr;
+ TW_Command *command_packet;
+ TW_Response_Queue response_queue;
+ int request_id = 0;
+ int i = 0;
+ int imax = 0;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n");
+ command_que_addr = tw_dev->registers.command_que_addr;
+ status_reg_addr = tw_dev->registers.status_reg_addr;
+ response_que_addr = tw_dev->registers.response_que_addr;
+
+ /* Initialize InitConnection command packet */
+ if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet virtual address.\n");
+ return 1;
+ }
+
+ command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+ memset(command_packet, 0, sizeof(TW_Sector));
+ command_packet->byte0.opcode = TW_OP_INIT_CONNECTION;
+ command_packet->byte0.sgl_offset = 0x0;
+ command_packet->size = TW_INIT_COMMAND_PACKET_SIZE;
+ command_packet->request_id = request_id;
+ command_packet->byte3.unit = 0x0;
+ command_packet->byte3.host_id = 0x0;
+ command_packet->status = 0x0;
+ command_packet->flags = 0x0;
+ command_packet->byte6.message_credits = TW_INIT_MESSAGE_CREDITS;
+ command_packet->byte8.init_connection.response_queue_pointer = 0x0;
+ command_que_value = tw_dev->command_packet_physical_address[request_id];
+
+ if (command_que_value == 0) {
+ printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n");
+ return 1;
+ }
+
+ /* Send command packet to the board */
+ outl(command_que_value, command_que_addr);
+
+ /* Poll for completion */
+ imax = TW_POLL_MAX_RETRIES;
+ for (i=0;i<imax;i++) {
+ mdelay(10);
+ status_reg_value = inl(status_reg_addr);
+ if (tw_check_bits(status_reg_value)) {
+ printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected bits.\n");
+ return 1;
+ }
+ if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
+ response_queue.value = inl(response_que_addr);
+ request_id = (unsigned char)response_queue.u.response_id;
+ if (request_id != 0) {
+ /* unexpected request id */
+ printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
+ return 1;
+ }
+ if (command_packet->status != 0) {
+ /* bad response */
+ printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, flags = 0x%x.\n", command_packet->flags);
+ return 1;
+ }
+ break; /* Response was okay, so we exit */
+ }
+ }
+ return 0;
+} /* End tw_initconnection() */
+
+/* This function will initialize the fields of a device extension */
+int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
+{
+ int i, imax;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_device_extension()\n");
+ imax = TW_Q_LENGTH;
+
+ for (i=0; i<imax; i++) {
+ /* Initialize command packet buffers */
+ tw_allocate_memory(tw_dev, i, sizeof(TW_Sector), 0);
+ if (tw_dev->command_packet_virtual_address[i] == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_initialize_device_extension(): Bad command packet virtual address.\n");
+ return 1;
+ }
+ memset(tw_dev->command_packet_virtual_address[i], 0, sizeof(TW_Sector));
+
+ /* Initialize generic buffer */
+ tw_allocate_memory(tw_dev, i, sizeof(TW_Sector), 1);
+ if (tw_dev->alignment_virtual_address[i] == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_initialize_device_extension(): Bad alignment virtual address.\n");
+ return 1;
+ }
+ memset(tw_dev->alignment_virtual_address[i], 0, sizeof(TW_Sector));
+
+ tw_dev->free_queue[i] = i;
+ tw_dev->state[i] = TW_S_INITIAL;
+ tw_dev->ioctl_size[i] = 0;
+ tw_dev->aen_queue[i] = 0;
+ }
+
+ for (i=0;i<TW_MAX_UNITS;i++)
+ tw_dev->is_unit_present[i] = 0;
+
+ tw_dev->num_units = 0;
+ tw_dev->num_aborts = 0;
+ tw_dev->num_resets = 0;
+ tw_dev->free_head = TW_Q_START;
+ tw_dev->free_tail = TW_Q_LENGTH - 1;
+ tw_dev->posted_request_count = 0;
+ tw_dev->max_posted_request_count = 0;
+ tw_dev->max_sgl_entries = 0;
+ tw_dev->sgl_entries = 0;
+ tw_dev->host = NULL;
+ tw_dev->pending_head = TW_Q_START;
+ tw_dev->pending_tail = TW_Q_START;
+ tw_dev->aen_head = 0;
+ tw_dev->aen_tail = 0;
+ tw_dev->sector_count = 0;
+ tw_dev->max_sector_count = 0;
+ spin_lock_init(&tw_dev->tw_lock);
+ tw_dev->flags = 0;
+ return 0;
+} /* End tw_initialize_device_extension() */
+
+/* This function will get unit info from the controller */
+int tw_initialize_units(TW_Device_Extension *tw_dev)
+{
+ int found = 0;
+ unsigned char request_id = 0;
+ TW_Command *command_packet;
+ TW_Param *param;
+ int i, imax, num_units = 0;
+ u32 status_reg_addr, status_reg_value;
+ u32 command_que_addr, command_que_value;
+ u32 response_que_addr;
+ TW_Response_Queue response_queue;
+ u32 param_value;
+ unsigned char *is_unit_present;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units()\n");
+
+ status_reg_addr = tw_dev->registers.status_reg_addr;
+ command_que_addr = tw_dev->registers.command_que_addr;
+ response_que_addr = tw_dev->registers.response_que_addr;
+
+ /* Setup the command packet */
+ command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+ if (command_packet == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet virtual address.\n");
+ return 1;
+ }
+ memset(command_packet, 0, sizeof(TW_Sector));
+ command_packet->byte0.opcode = TW_OP_GET_PARAM;
+ command_packet->byte0.sgl_offset = 2;
+ command_packet->size = 4;
+ command_packet->request_id = request_id;
+ command_packet->byte3.unit = 0;
+ command_packet->byte3.host_id = 0;
+ command_packet->status = 0;
+ command_packet->flags = 0;
+ command_packet->byte6.block_count = 1;
+
+ /* Now setup the param */
+ if (tw_dev->alignment_virtual_address[request_id] == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment virtual address.\n");
+ return 1;
+ }
+ param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+ memset(param, 0, sizeof(TW_Sector));
+ param->table_id = 3; /* unit summary table */
+ param->parameter_id = 3; /* unitstatus parameter */
+ param->parameter_size_bytes = TW_MAX_UNITS;
+ param_value = tw_dev->alignment_physical_address[request_id];
+ if (param_value == 0) {
+ printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment physical address.\n");
+ return 1;
+ }
+
+ command_packet->byte8.param.sgl[0].address = param_value;
+ command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
+
+ /* Post the command packet to the board */
+ command_que_value = tw_dev->command_packet_physical_address[request_id];
+ if (command_que_value == 0) {
+ printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet physical address.\n");
+ return 1;
+ }
+ outl(command_que_value, command_que_addr);
+
+ /* Poll for completion */
+ imax = TW_POLL_MAX_RETRIES;
+ for(i=0; i<imax; i++) {
+ mdelay(10);
+ status_reg_value = inl(status_reg_addr);
+ if (tw_check_bits(status_reg_value)) {
+ printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n");
+ return 1;
+ }
+ if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
+ response_queue.value = inl(response_que_addr);
+ request_id = (unsigned char)response_queue.u.response_id;
+ if (request_id != 0) {
+ /* unexpected request id */
+ printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
+ return 1;
+ }
+ if (command_packet->status != 0) {
+ /* bad response */
+ printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, flags = 0x%x.\n", command_packet->flags);
+ return 1;
+ }
+ found = 1;
+ break;
+ }
+ }
+ if (found == 0) {
+ /* response never received */
+ printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n");
+ return 1;
+ }
+
+ param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+ is_unit_present = (unsigned char *)&(param->data[0]);
+
+ /* Show all units present */
+ imax = TW_MAX_UNITS;
+ for(i=0; i<imax; i++) {
+ if (is_unit_present[i] == 0) {
+ tw_dev->is_unit_present[i] = FALSE;
+ } else {
+ dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): Unit %d found.\n", i);
+ tw_dev->is_unit_present[i] = TRUE;
+ num_units++;
+ }
+ }
+ tw_dev->num_units = num_units;
+
+ if (num_units == 0) {
+ printk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): No units found.\n");
+ return 1;
+ }
+
+ return 0;
+} /* End tw_initialize_units() */
+
+/* This function is the interrupt service routine */
+static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ int request_id;
+ u32 status_reg_addr, status_reg_value;
+ u32 response_que_addr;
+ TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
+ TW_Response_Queue response_que;
+ int error = 0;
+ int do_response_interrupt=0;
+ int do_attention_interrupt=0;
+ int do_host_interrupt=0;
+ int do_command_interrupt=0;
+ int flags = 0;
+ int flags2 = 0;
+ TW_Command *command_packet;
+ if (test_and_set_bit(TW_IN_INTR, &tw_dev->flags))
+ return;
+ spin_lock_irqsave(&io_request_lock, flags);
+
+ if (tw_dev->tw_pci_dev->irq == irq) {
+ spin_lock_irqsave(&tw_dev->tw_lock, flags2);
+ dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt()\n");
+
+ /* Read the registers */
+ status_reg_addr = tw_dev->registers.status_reg_addr;
+ response_que_addr = tw_dev->registers.response_que_addr;
+ status_reg_value = inl(status_reg_addr);
+
+ /* Check which interrupt */
+ if (status_reg_value & TW_STATUS_HOST_INTERRUPT)
+ do_host_interrupt=1;
+ if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT)
+ do_attention_interrupt=1;
+ if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT)
+ do_command_interrupt=1;
+ if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT)
+ do_response_interrupt=1;
+
+ /* Handle host interrupt */
+ if (do_host_interrupt) {
+ dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n");
+ tw_clear_host_interrupt(tw_dev);
+ }
+
+ /* Handle attention interrupt */
+ if (do_attention_interrupt) {
+ dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n");
+ tw_state_request_start(tw_dev, &request_id);
+ error = tw_aen_read_queue(tw_dev, request_id);
+ if (error) {
+ printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Error reading aen queue.\n");
+ tw_dev->state[request_id] = TW_S_COMPLETED;
+ tw_state_request_finish(tw_dev, request_id);
+ } else {
+ dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Clearing attention interrupt.\n");
+ tw_clear_attention_interrupt(tw_dev);
+ }
+ }
+
+ /* Handle command interrupt */
+ if (do_command_interrupt) {
+ /* Drain as many pending commands as we can */
+ while (tw_dev->pending_request_count > 0) {
+ request_id = tw_dev->pending_queue[tw_dev->pending_head];
+ if (tw_dev->state[request_id] != TW_S_PENDING) {
+ printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found request id that wasn't pending.\n");
+ break;
+ }
+ if (tw_post_command_packet(tw_dev, request_id)==0) {
+ if (tw_dev->pending_head == TW_Q_LENGTH-1) {
+ tw_dev->pending_head = TW_Q_START;
+ } else {
+ tw_dev->pending_head = tw_dev->pending_head + 1;
+ }
+ tw_dev->pending_request_count--;
+ } else {
+ break;
+ }
+ }
+ /* If there are no more pending requests, we mask command interrupt */
+ if (tw_dev->pending_request_count == 0)
+ tw_mask_command_interrupt(tw_dev);
+ }
+
+ /* Handle response interrupt */
+ if (do_response_interrupt) {
+ /* Drain the response queue from the board */
+ while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
+ response_que.value = inl(response_que_addr);
+ request_id = response_que.u.response_id;
+ command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+ if (command_packet->status != 0) {
+ printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, flags = 0x%x.\n", command_packet->flags);
+ }
+ if (tw_dev->state[request_id] != TW_S_POSTED) {
+ printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", request_id, command_packet->byte0.opcode);
+ }
+ error = 0;
+ dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
+ /* Check for internal command */
+ if (tw_dev->srb[request_id] == 0) {
+ dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
+ error = tw_aen_complete(tw_dev, request_id);
+ if (error) {
+ printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Error completing aen.\n");
+ }
+ status_reg_value = inl(status_reg_addr);
+ if (tw_check_bits(status_reg_value)) {
+ printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
+ }
+ } else {
+ switch (tw_dev->srb[request_id]->cmnd[0]) {
+ case READ_10:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10\n");
+ case READ_6:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_6\n");
+ break;
+ case WRITE_10:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10\n");
+ case WRITE_6:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_6\n");
+ break;
+ case INQUIRY:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");
+ error = tw_scsiop_inquiry_complete(tw_dev, request_id);
+ break;
+ case READ_CAPACITY:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");
+ error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
+ break;
+ case TW_IOCTL:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TW_IOCTL\n");
+ error = tw_ioctl_complete(tw_dev, request_id);
+ break;
+ default:
+ printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unknown scsi opcode: 0x%x.\n", tw_dev->srb[request_id]->cmnd[0]);
+ tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
+ tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+ }
+ if (error) {
+ /* Tell scsi layer there was an error */
+ printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Scsi Error.\n");
+ tw_dev->srb[request_id]->result = (DID_ERROR << 16);
+ } else {
+ /* Tell scsi layer command was a success */
+ tw_dev->srb[request_id]->result = (DID_OK << 16);
+ }
+ tw_dev->state[request_id] = TW_S_COMPLETED;
+ tw_state_request_finish(tw_dev, request_id);
+ tw_dev->posted_request_count--;
+ tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+ status_reg_value = inl(status_reg_addr);
+ if (tw_check_bits(status_reg_value)) {
+ printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
+ }
+ }
+ }
+ }
+ spin_unlock_irqrestore(&tw_dev->tw_lock, flags2);
+ }
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ clear_bit(TW_IN_INTR, &tw_dev->flags);
+} /* End tw_interrupt() */
+
+/* This function handles ioctls from userspace to the driver */
+int tw_ioctl(TW_Device_Extension *tw_dev, int request_id)
+{
+ unsigned char opcode;
+ int bufflen;
+ TW_Param *param;
+ TW_Command *command_packet;
+ u32 param_value;
+ TW_Ioctl *ioctl = NULL;
+ int tw_aen_code;
+
+ ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer;
+ if (ioctl == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Request buffer NULL.\n");
+ tw_dev->state[request_id] = TW_S_COMPLETED;
+ tw_state_request_finish(tw_dev, request_id);
+ tw_dev->srb[request_id]->result = (DID_OK << 16);
+ tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+ return 0;
+ }
+ bufflen = tw_dev->srb[request_id]->request_bufflen;
+
+ /* Initialize command packet */
+ command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+ if (command_packet == NULL) {
+ printk(KERN_WARNING "3w-xxxx: twioctl(): Bad command packet virtual address.\n");
+ tw_dev->state[request_id] = TW_S_COMPLETED;
+ tw_state_request_finish(tw_dev, request_id);
+ tw_dev->srb[request_id]->result = (DID_OK << 16);
+ tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+ return 0;
+ }
+ memset(command_packet, 0, sizeof(TW_Sector));
+
+ /* Initialize param */
+ if (tw_dev->alignment_virtual_address[request_id] == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment virtual address.\n");
+ tw_dev->state[request_id] = TW_S_COMPLETED;
+ tw_state_request_finish(tw_dev, request_id);
+ tw_dev->srb[request_id]->result = (DID_OK << 16);
+ tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+ return 0;
+ }
+ param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+ memset(param, 0, sizeof(TW_Sector));
+
+ dprintk(KERN_NOTICE "opcode = %d table_id = %d parameter_id = %d parameter_size_bytes = %d\n", ioctl->opcode, ioctl->table_id, ioctl->parameter_id,, ioctl->parameter_size_bytes);
+ opcode = ioctl->opcode;
+
+ switch (opcode) {
+ case TW_OP_NOP:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_NOP.\n");
+ command_packet->byte0.opcode = TW_OP_NOP;
+ break;
+ case TW_OP_GET_PARAM:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_GET_PARAM.\n");
+ command_packet->byte0.opcode = TW_OP_GET_PARAM;
+ param->table_id = ioctl->table_id;
+ param->parameter_id = ioctl->parameter_id;
+ param->parameter_size_bytes = ioctl->parameter_size_bytes;
+ tw_dev->ioctl_size[request_id] = ioctl->parameter_size_bytes;
+ dprintk(KERN_NOTICE "table_id = %d parameter_id = %d parameter_size_bytes %d\n", param->table_id, param->parameter_id, param->parameter_size_bytes);
+ break;
+ case TW_OP_SET_PARAM:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_SET_PARAM: table_id = %d, parameter_id = %d, parameter_size_bytes = %d.\n",
+ ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);
+ command_packet->byte0.opcode = TW_OP_SET_PARAM;
+ param->table_id = ioctl->table_id;
+ param->parameter_id = ioctl->parameter_id;
+ param->parameter_size_bytes = ioctl->parameter_size_bytes;
+ memcpy(param->data, ioctl->data, ioctl->parameter_size_bytes);
+ break;
+ case TW_OP_AEN_LISTEN:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_AEN_LISTEN.\n");
+ if (tw_dev->aen_head == tw_dev->aen_tail) {
+ /* aen queue empty */
+ dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Aen queue empty.\n");
+ tw_aen_code = TW_AEN_QUEUE_EMPTY;
+ memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);
+ } else {
+ /* Copy aen queue entry to request buffer */
+ dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Returning aen 0x%x\n", tw_dev->aen_queue[tw_dev->aen_head]);
+ tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
+ memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);
+ if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
+ tw_dev->aen_head = TW_Q_START;
+ } else {
+ tw_dev->aen_head = tw_dev->aen_head + 1;
+ }
+ }
+ tw_dev->state[request_id] = TW_S_COMPLETED;
+ tw_state_request_finish(tw_dev, request_id);
+ tw_dev->srb[request_id]->result = (DID_OK << 16);
+ tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+ return 0;
+ default:
+ printk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
+ tw_dev->state[request_id] = TW_S_COMPLETED;
+ tw_state_request_finish(tw_dev, request_id);
+ tw_dev->srb[request_id]->result = (DID_OK << 16);
+ tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+ return 0;
+ }
+
+ param_value = tw_dev->alignment_physical_address[request_id];
+ if (param_value == 0) {
+ printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
+ tw_dev->state[request_id] = TW_S_COMPLETED;
+ tw_state_request_finish(tw_dev, request_id);
+ tw_dev->srb[request_id]->result = (DID_OK << 16);
+ tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+ }
+
+ command_packet->byte8.param.sgl[0].address = param_value;
+ command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
+
+ command_packet->byte0.sgl_offset = 2;
+ command_packet->size = 4;
+ command_packet->request_id = request_id;
+ command_packet->byte3.unit = 0;
+ command_packet->byte3.host_id = 0;
+ command_packet->status = 0;
+ command_packet->flags = 0;
+ command_packet->byte6.parameter_count = 1;
+
+ /* Now try to post the command to the board */
+ tw_post_command_packet(tw_dev, request_id);
+
+ return 0;
+} /* End tw_ioctl() */
+
+/* This function is called by the isr to complete ioctl requests */
+int tw_ioctl_complete(TW_Device_Extension *tw_dev, int request_id)
+{
+ unsigned char *param_data;
+ unsigned char *buff;
+ TW_Param *param;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete()\n");
+ buff = tw_dev->srb[request_id]->request_buffer;
+ if (buff == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): Request buffer NULL.\n");
+ return 1;
+ }
+ dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete(): Request_bufflen = %d\n", tw_dev->srb[request_id]->request_bufflen);
+ memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
+ param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+ if (param == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
+ return 1;
+ }
+ param_data = &(param->data[0]);
+
+ memcpy(buff, param_data, tw_dev->ioctl_size[request_id]);
+
+ return 0;
+} /* End tw_ioctl_complete() */
+
+/* This function will mask the command interrupt */
+void tw_mask_command_interrupt(TW_Device_Extension *tw_dev)
+{
+ u32 control_reg_addr, control_reg_value;
+
+ control_reg_addr = tw_dev->registers.control_reg_addr;
+ control_reg_value = TW_CONTROL_MASK_COMMAND_INTERRUPT;
+ outl(control_reg_value, control_reg_addr);
+} /* End tw_mask_command_interrupt() */
+
+/* This function will poll the status register for a flag */
+int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
+{
+ u32 status_reg_addr, status_reg_value;
+ struct timeval before, timeout;
+
+ status_reg_addr = tw_dev->registers.status_reg_addr;
+ do_gettimeofday(&before);
+ status_reg_value = inl(status_reg_addr);
+
+ while ((status_reg_value & flag) != flag) {
+ status_reg_value = inl(status_reg_addr);
+ do_gettimeofday(&timeout);
+ if (before.tv_sec + seconds < timeout.tv_sec) {
+ printk(KERN_WARNING "3w-xxxx: tw_poll_status(): Flag 0x%x not found.\n", flag);
+ return 1;
+ }
+ mdelay(1);
+ }
+ return 0;
+} /* End tw_poll_status() */
+
+/* This function will attempt to post a command packet to the board */
+int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
+{
+ u32 status_reg_addr, status_reg_value;
+ u32 command_que_addr, command_que_value;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_post_command_packet()\n");
+ command_que_addr = tw_dev->registers.command_que_addr;
+ command_que_value = tw_dev->command_packet_physical_address[request_id];
+ status_reg_addr = tw_dev->registers.status_reg_addr;
+ status_reg_value = inl(status_reg_addr);
+
+ if (tw_check_bits(status_reg_value))
+ printk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
+
+ if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
+ /* We successfully posted the command packet */
+ outl(command_que_value, command_que_addr);
+ tw_dev->state[request_id] = TW_S_POSTED;
+ tw_dev->posted_request_count++;
+ if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
+ tw_dev->max_posted_request_count = tw_dev->posted_request_count;
+ }
+ } else {
+ /* Couldn't post the command packet, so we do it in the isr */
+ if (tw_dev->state[request_id] != TW_S_PENDING) {
+ tw_dev->state[request_id] = TW_S_PENDING;
+ tw_dev->pending_request_count++;
+ if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
+ tw_dev->max_pending_request_count = tw_dev->pending_request_count;
+ }
+ tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
+ if (tw_dev->pending_tail == TW_Q_LENGTH-1) {
+ tw_dev->pending_tail = TW_Q_START;
+ } else {
+ tw_dev->pending_tail = tw_dev->pending_tail + 1;
+ }
+ }
+ tw_unmask_command_interrupt(tw_dev);
+ return 1;
+ }
+ return 0;
+} /* End tw_post_command_packet() */
+
+/* This function will reset a device extension */
+int tw_reset_device_extension(TW_Device_Extension *tw_dev)
+{
+ int imax = 0;
+ int i = 0;
+ Scsi_Cmnd *srb;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_reset_device_extension()\n");
+ imax = TW_Q_LENGTH;
+
+ if (tw_reset_sequence(tw_dev)) {
+ printk(KERN_WARNING "3w-xxxx: tw_reset_device_extension(): Reset sequence failed for card %d.\n", tw_dev->host->host_no);
+ return 1;
+ }
+
+ /* Abort all requests that are in progress */
+ for (i=0;i<imax;i++) {
+ if ((tw_dev->state[i] != TW_S_FINISHED) &&
+ (tw_dev->state[i] != TW_S_INITIAL) &&
+ (tw_dev->state[i] != TW_S_COMPLETED)) {
+ srb = tw_dev->srb[i];
+ srb->result = (DID_RESET << 16);
+ tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
+ }
+ }
+
+ /* Reset queues and counts */
+ for (i=0;i<imax;i++) {
+ tw_dev->free_queue[i] = i;
+ tw_dev->state[i] = TW_S_INITIAL;
+ }
+ tw_dev->free_head = TW_Q_START;
+ tw_dev->free_tail = TW_Q_LENGTH - 1;
+ tw_dev->posted_request_count = 0;
+ tw_dev->pending_request_count = 0;
+ tw_dev->pending_head = TW_Q_START;
+ tw_dev->pending_tail = TW_Q_START;
+
+ return 0;
+} /* End tw_reset_device_extension() */
+
+/* This function will reset a controller */
+int tw_reset_sequence(TW_Device_Extension *tw_dev)
+{
+ int error = 0;
+ int tries = 0;
+
+ /* Disable interrupts */
+ tw_disable_interrupts(tw_dev);
+
+ /* Reset the board */
+ while (tries < TW_MAX_RESET_TRIES) {
+ tw_soft_reset(tw_dev);
+
+ error = tw_aen_drain_queue(tw_dev);
+ if (error) {
+ printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): No attention interrupt for card %d.\n", tw_dev->host->host_no);
+ tries++;
+ continue;
+ }
+
+ /* Check for controller errors */
+ if (tw_check_errors(tw_dev)) {
+ printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Controller errors found, soft resetting card %d.\n", tw_dev->host->host_no);
+ tries++;
+ continue;
+ }
+
+ /* Empty the response queue again */
+ error = tw_empty_response_que(tw_dev);
+ if (error) {
+ printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Couldn't empty response queue for card %d.\n", tw_dev->host->host_no);
+ tries++;
+ continue;
+ }
+
+ /* Now the controller is in a good state */
+ break;
+ }
+
+ if (tries >= TW_MAX_RESET_TRIES) {
+ printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Controller error or no attention interrupt: giving up for card %d.\n", tw_dev->host->host_no);
+ return 1;
+ }
+
+ error = tw_initconnection(tw_dev);
+ if (error) {
+ printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no);
+ return 1;
+ }
+
+ /* Re-enable interrupts */
+ tw_enable_interrupts(tw_dev);
+
+ return 0;
+} /* End tw_reset_sequence() */
+
+/* This funciton returns unit geometry in cylinders/heads/sectors */
+int tw_scsi_biosparam(Disk *disk, kdev_t dev, int geom[])
+{
+ int heads, sectors, cylinders;
+ TW_Device_Extension *tw_dev;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n");
+ tw_dev = (TW_Device_Extension *)disk->device->host->hostdata;
+
+ heads = 64;
+ sectors = 32;
+ cylinders = disk->capacity / (heads * sectors);
+
+ if (disk->capacity >= 0x200000) {
+ heads = 255;
+ sectors = 63;
+ cylinders = disk->capacity / (heads * sectors);
+ }
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam(): heads = %d, sectors = %d, cylinders = %d\n", heads, sectors, cylinders);
+ geom[0] = heads;
+ geom[1] = sectors;
+ geom[2] = cylinders;
+
+ return 0;
+} /* End tw_scsi_biosparam() */
+
+/* This function will find and initialize any cards */
+int tw_scsi_detect(Scsi_Host_Template *tw_host)
+{
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_detect()\n");
+
+ /* Check if the kernel has PCI interface compiled in */
+ if (!pci_present()) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsi_detect(): No pci interface present.\n");
+ return 0;
+ }
+
+ return(tw_findcards(tw_host));
+} /* End tw_scsi_detect() */
+
+/* This is the new scsi eh abort function */
+int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt)
+{
+ TW_Device_Extension *tw_dev=NULL;
+ int i = 0;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_abort()\n");
+
+ if (!SCpnt) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid Scsi_Cmnd.\n");
+ return (FAILED);
+ }
+
+ tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
+ if (tw_dev == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid device extension.\n");
+ return (FAILED);
+ }
+
+ spin_lock(&tw_dev->tw_lock);
+ tw_dev->num_aborts++;
+
+ /* If the command hasn't been posted yet, we can do the abort */
+ for (i=0;i<TW_Q_LENGTH;i++) {
+ if (tw_dev->srb[i] == SCpnt) {
+ if (tw_dev->state[i] == TW_S_STARTED) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Abort succeeded for started Scsi_Cmnd 0x%x\n", (u32)tw_dev->srb[i]);
+ tw_dev->state[i] = TW_S_COMPLETED;
+ tw_state_request_finish(tw_dev, i);
+ spin_unlock(&tw_dev->tw_lock);
+ return (SUCCESS);
+ }
+ if (tw_dev->state[i] == TW_S_PENDING) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Abort succeeded for pending Scsi_Cmnd 0x%x\n", (u32)tw_dev->srb[i]);
+ if (tw_dev->pending_head == TW_Q_LENGTH-1) {
+ tw_dev->pending_head = TW_Q_START;
+ } else {
+ tw_dev->pending_head = tw_dev->pending_head + 1;
+ }
+ tw_dev->pending_request_count--;
+ tw_dev->state[i] = TW_S_COMPLETED;
+ tw_state_request_finish(tw_dev, i);
+ spin_unlock(&tw_dev->tw_lock);
+ return (SUCCESS);
+ }
+ }
+ }
+
+ /* If the command has already been posted, we have to reset the card */
+ printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Abort failed for unknown Scsi_Cmnd 0x%x, resetting card %d.\n", (u32)SCpnt, tw_dev->host->host_no);
+
+ if (tw_reset_device_extension(tw_dev)) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Reset failed for card %d.\n", tw_dev->host->host_no);
+ spin_unlock(&tw_dev->tw_lock);
+ return (FAILED);
+ }
+ spin_unlock(&tw_dev->tw_lock);
+
+ return (SUCCESS);
+} /* End tw_scsi_eh_abort() */
+
+/* This is the new scsi eh reset function */
+int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt)
+{
+ TW_Device_Extension *tw_dev=NULL;
+ int flags = 0;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_reset()\n");
+
+ if (!SCpnt) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid Scsi_Cmnd.\n");
+ return (FAILED);
+ }
+
+ tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
+ if (tw_dev == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid device extension.\n");
+ return (FAILED);
+ }
+
+ spin_lock_irqsave(&tw_dev->tw_lock, flags);
+ tw_dev->num_resets++;
+
+ /* Now reset the card and some of the device extension data */
+ if (tw_reset_device_extension(tw_dev)) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Reset failed for card %d.\n", tw_dev->host->host_no);
+ spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
+ return (FAILED);
+ }
+ printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Reset succeeded for card %d.\n", tw_dev->host->host_no);
+ spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
+
+ return (SUCCESS);
+} /* End tw_scsi_eh_reset() */
+
+/* This function handles input and output from /proc/scsi/3w-xxxx/x */
+int tw_scsi_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout)
+{
+ TW_Device_Extension *tw_dev = NULL;
+ TW_Info info;
+ int i;
+ int j;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_proc_info()\n");
+
+ /* Find the correct device extension */
+ for (i=0;i<tw_device_extension_count;i++)
+ if (tw_device_extension_list[i]->host->host_no == hostno)
+ tw_dev = tw_device_extension_list[i];
+ if (tw_dev == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsi_proc_info(): Couldn't locate device extension.\n");
+ return (-EINVAL);
+ }
+
+ info.buffer = buffer;
+ info.length = length;
+ info.offset = offset;
+ info.position = 0;
+
+ if (inout) {
+ /* Write */
+ if (strncmp(buffer, "debug", 5) == 0) {
+ printk(KERN_INFO "3w-xxxx: Posted commands:\n");
+ for (j=0;j<TW_Q_LENGTH;j++) {
+ if (tw_dev->state[j] == TW_S_POSTED) {
+ TW_Command *command = (TW_Command *)tw_dev->command_packet_virtual_address[j];
+ printk(KERN_INFO "3w-xxxx: Request_id: %d\n", j);
+ printk(KERN_INFO "Opcode: 0x%x\n", command->byte0.opcode);
+ printk(KERN_INFO "Block_count: 0x%x\n", command->byte6.block_count);
+ printk(KERN_INFO "LBA: 0x%x\n", (u32)command->byte8.io.lba);
+ printk(KERN_INFO "Physical command packet addr: 0x%x\n", tw_dev->command_packet_physical_address[j]);
+ printk(KERN_INFO "Scsi_Cmnd: 0x%x\n", (u32)tw_dev->srb[j]);
+ }
+ }
+ printk(KERN_INFO "3w-xxxx: Free_head: %3d\n", tw_dev->free_head);
+ printk(KERN_INFO "3w-xxxx: Free_tail: %3d\n", tw_dev->free_tail);
+ }
+ return length;
+ } else {
+ /* Read */
+ if (start) {
+ *start = buffer;
+ }
+ tw_copy_info(&info, "scsi%d: 3ware Storage Controller\n", hostno);
+ tw_copy_info(&info, "Driver version: %s\n", tw_driver_version);
+ tw_copy_info(&info, "Current commands posted: %3d\n", tw_dev->posted_request_count);
+ tw_copy_info(&info, "Max commands posted: %3d\n", tw_dev->max_posted_request_count);
+ tw_copy_info(&info, "Current pending commands: %3d\n", tw_dev->pending_request_count);
+ tw_copy_info(&info, "Max pending commands: %3d\n", tw_dev->max_pending_request_count);
+ tw_copy_info(&info, "Last sgl length: %3d\n", tw_dev->sgl_entries);
+ tw_copy_info(&info, "Max sgl length: %3d\n", tw_dev->max_sgl_entries);
+ tw_copy_info(&info, "Last sector count: %3d\n", tw_dev->sector_count);
+ tw_copy_info(&info, "Max sector count: %3d\n", tw_dev->max_sector_count);
+ tw_copy_info(&info, "Resets: %3d\n", tw_dev->num_resets);
+ tw_copy_info(&info, "Aborts: %3d\n", tw_dev->num_aborts);
+ }
+ if (info.position > info.offset) {
+ return (info.position - info.offset);
+ } else {
+ return 0;
+ }
+} /* End tw_scsi_proc_info() */
+
+/* This is the main scsi queue function to handle scsi opcodes */
+int tw_scsi_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+{
+ unsigned char *command = SCpnt->cmnd;
+ int request_id = 0;
+ int error = 0;
+ int flags = 0;
+ TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
+
+ spin_lock_irqsave(&tw_dev->tw_lock, flags);
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue()\n");
+
+ /* Skip scsi command if it isn't for us */
+ if ((tw_dev->is_unit_present[SCpnt->target] == FALSE) || (SCpnt->lun != 0)) {
+ SCpnt->result = (DID_BAD_TARGET << 16);
+ done(SCpnt);
+ spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
+ return 0;
+ }
+ if (done == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid done function.\n");
+ SCpnt->result = (DID_ERROR << 16);
+ done(SCpnt);
+ spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
+ return 0;
+ }
+ if (tw_dev == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid device extension.\n");
+ SCpnt->result = (DID_ERROR << 16);
+ done(SCpnt);
+ spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
+ return 0;
+ }
+
+ /* Save done function into Scsi_Cmnd struct */
+ SCpnt->scsi_done = done;
+
+ /* Queue the command and get a request id */
+ tw_state_request_start(tw_dev, &request_id);
+
+ /* Save the scsi command for use by the ISR */
+ tw_dev->srb[request_id] = SCpnt;
+
+ switch (*command) {
+ case READ_10:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_10.\n");
+ case READ_6:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_6.\n");
+ case WRITE_10:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught WRITE_10.\n");
+ case WRITE_6:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught WRITE_6.\n");
+ error = tw_scsiop_read_write(tw_dev, request_id);
+ break;
+ case TEST_UNIT_READY:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
+ error = tw_scsiop_test_unit_ready(tw_dev, request_id);
+ break;
+ case INQUIRY:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
+ error = tw_scsiop_inquiry(tw_dev, request_id);
+ break;
+ case READ_CAPACITY:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
+ error = tw_scsiop_read_capacity(tw_dev, request_id);
+ break;
+ case TW_IOCTL:
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TW_SCSI_IOCTL.\n");
+ error = tw_ioctl(tw_dev, request_id);
+ break;
+ default:
+ printk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): Unknown scsi opcode: 0x%x\n", *command);
+ tw_dev->state[request_id] = TW_S_COMPLETED;
+ tw_state_request_finish(tw_dev, request_id);
+ SCpnt->result = (DID_BAD_TARGET << 16);
+ done(SCpnt);
+ }
+ if (error) {
+ tw_dev->state[request_id] = TW_S_COMPLETED;
+ tw_state_request_finish(tw_dev, request_id);
+ SCpnt->result = (DID_ERROR << 16);
+ done(SCpnt);
+ }
+ spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
+
+ return 0;
+} /* End tw_scsi_queue() */
+
+/* This function will release the resources on an rmmod call */
+int tw_scsi_release(struct Scsi_Host *tw_host)
+{
+ TW_Device_Extension *tw_dev;
+ tw_dev = (TW_Device_Extension *)tw_host->hostdata;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_release()\n");
+
+ /* Free up the IO region */
+ release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
+
+ /* Free up the IRQ */
+ free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
+
+ /* Free up device extension resources */
+ tw_free_device_extension(tw_dev);
+
+ /* Tell kernel scsi-layer we are gone */
+ scsi_unregister(tw_host);
+
+ return 0;
+} /* End tw_scsi_release() */
+
+/* This function handles scsi inquiry commands */
+int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
+{
+ TW_Param *param;
+ TW_Command *command_packet;
+ u32 command_que_value, command_que_addr;
+ u32 param_value;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry()\n");
+
+ /* Initialize command packet */
+ command_que_addr = tw_dev->registers.command_que_addr;
+ command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+ if (command_packet == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet virtual address.\n");
+ return 1;
+ }
+ memset(command_packet, 0, sizeof(TW_Sector));
+ command_packet->byte0.opcode = TW_OP_GET_PARAM;
+ command_packet->byte0.sgl_offset = 2;
+ command_packet->size = 4;
+ command_packet->request_id = request_id;
+ command_packet->byte3.unit = 0;
+ command_packet->byte3.host_id = 0;
+ command_packet->status = 0;
+ command_packet->flags = 0;
+ command_packet->byte6.parameter_count = 1;
+
+ /* Now setup the param */
+ if (tw_dev->alignment_virtual_address[request_id] == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment virtual address.\n");
+ return 1;
+ }
+ param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+ memset(param, 0, sizeof(TW_Sector));
+ param->table_id = 3; /* unit summary table */
+ param->parameter_id = 3; /* unitsstatus parameter */
+ param->parameter_size_bytes = TW_MAX_UNITS;
+ param_value = tw_dev->alignment_physical_address[request_id];
+ if (param_value == 0) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment physical address.\n");
+ return 1;
+ }
+
+ command_packet->byte8.param.sgl[0].address = param_value;
+ command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
+ command_que_value = tw_dev->command_packet_physical_address[request_id];
+ if (command_que_value == 0) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet physical address.\n");
+ return 1;
+ }
+
+ /* Now try to post the command packet */
+ tw_post_command_packet(tw_dev, request_id);
+
+ return 0;
+} /* End tw_scsiop_inquiry() */
+
+/* This function is called by the isr to complete an inquiry command */
+int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
+{
+ unsigned char *is_unit_present;
+ unsigned char *request_buffer;
+ int i;
+ TW_Param *param;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
+
+ /* Fill request buffer */
+ if (tw_dev->srb[request_id]->request_buffer == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Request buffer NULL.\n");
+ return 1;
+ }
+ request_buffer = tw_dev->srb[request_id]->request_buffer;
+ memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
+ request_buffer[0] = TYPE_DISK; /* Peripheral device type */
+ request_buffer[1] = 0; /* Device type modifier */
+ request_buffer[2] = 0; /* No ansi/iso compliance */
+ request_buffer[4] = 31; /* Additional length */
+ memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */
+ memcpy(&request_buffer[16], "3w-xxxx ", 16); /* Product ID */
+ memcpy(&request_buffer[32], tw_driver_version, 3);
+
+ param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+ if (param == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Bad alignment virtual address.\n");
+ return 1;
+ }
+ is_unit_present = &(param->data[0]);
+
+ for (i=0 ; i<TW_MAX_UNITS; i++) {
+ if (is_unit_present[i] == 0) {
+ tw_dev->is_unit_present[i] = FALSE;
+ } else {
+ tw_dev->is_unit_present[i] = TRUE;
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete: Unit %d found.\n", i);
+ }
+ }
+
+ return 0;
+} /* End tw_scsiop_inquiry_complete() */
+
+/* This function handles scsi read_capacity commands */
+int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
+{
+ TW_Param *param;
+ TW_Command *command_packet;
+ u32 command_que_addr, command_que_value;
+ u32 param_value;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n");
+
+ /* Initialize command packet */
+ command_que_addr = tw_dev->registers.command_que_addr;
+ command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+
+ if (command_packet == NULL) {
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet virtual address.\n");
+ return 1;
+ }
+ memset(command_packet, 0, sizeof(TW_Sector));
+ command_packet->byte0.opcode = TW_OP_GET_PARAM;
+ command_packet->byte0.sgl_offset = 2;
+ command_packet->size = 4;
+ command_packet->request_id = request_id;
+ command_packet->byte3.unit = tw_dev->srb[request_id]->target;
+ command_packet->byte3.host_id = 0;
+ command_packet->status = 0;
+ command_packet->flags = 0;
+ command_packet->byte6.block_count = 1;
+
+ /* Now setup the param */
+ if (tw_dev->alignment_virtual_address[request_id] == NULL) {
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment virtual address.\n");
+ return 1;
+ }
+ param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+ memset(param, 0, sizeof(TW_Sector));
+ param->table_id = TW_UNIT_INFORMATION_TABLE_BASE +
+ tw_dev->srb[request_id]->target;
+ param->parameter_id = 4; /* unitcapacity parameter */
+ param->parameter_size_bytes = 4;
+ param_value = tw_dev->alignment_physical_address[request_id];
+ if (param_value == 0) {
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n");
+ return 1;
+ }
+
+ command_packet->byte8.param.sgl[0].address = param_value;
+ command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
+ command_que_value = tw_dev->command_packet_physical_address[request_id];
+ if (command_que_value == 0) {
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet physical address.\n");
+ return 1;
+ }
+
+ /* Now try to post the command to the board */
+ tw_post_command_packet(tw_dev, request_id);
+
+ return 0;
+} /* End tw_scsiop_read_capacity() */
+
+/* This function is called by the isr to complete a readcapacity command */
+int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id)
+{
+ unsigned char *param_data;
+ u32 capacity;
+ char *buff;
+ TW_Param *param;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
+
+ buff = tw_dev->srb[request_id]->request_buffer;
+ if (buff == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Request buffer NULL.\n");
+ return 1;
+ }
+ memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
+ param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+ if (param == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
+ return 1;
+ }
+ param_data = &(param->data[0]);
+
+ capacity = (param_data[3] << 24) | (param_data[2] << 16) |
+ (param_data[1] << 8) | param_data[0];
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete(): Capacity = 0x%x.\n", capacity);
+
+ /* Number of LBA's */
+ buff[0] = (capacity >> 24);
+ buff[1] = (capacity >> 16) & 0xff;
+ buff[2] = (capacity >> 8) & 0xff;
+ buff[3] = capacity & 0xff;
+
+ /* Block size in bytes (512) */
+ buff[4] = (TW_BLOCK_SIZE >> 24);
+ buff[5] = (TW_BLOCK_SIZE >> 16) & 0xff;
+ buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
+ buff[7] = TW_BLOCK_SIZE & 0xff;
+
+ return 0;
+} /* End tw_scsiop_read_capacity_complete() */
+
+/* This function handles scsi read or write commands */
+int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
+{
+ TW_Command *command_packet;
+ u32 command_que_addr, command_que_value = 0;
+ u32 lba = 0x0, num_sectors = 0x0;
+ int i;
+ Scsi_Cmnd *srb;
+ struct scatterlist *sglist;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
+
+ if (tw_dev->srb[request_id]->request_buffer == NULL) {
+ printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n");
+ return 1;
+ }
+ sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
+ srb = tw_dev->srb[request_id];
+
+ /* Initialize command packet */
+ command_que_addr = tw_dev->registers.command_que_addr;
+ command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+ if (command_packet == NULL) {
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): Bad command packet virtual address.\n");
+ return 1;
+ }
+
+ if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == READ_10) {
+ command_packet->byte0.opcode = TW_OP_READ;
+ } else {
+ command_packet->byte0.opcode = TW_OP_WRITE;
+ }
+
+ command_packet->byte0.sgl_offset = 3;
+ command_packet->size = 5;
+ command_packet->request_id = request_id;
+ command_packet->byte3.unit = srb->target;
+ command_packet->byte3.host_id = 0;
+ command_packet->status = 0;
+ command_packet->flags = 0;
+
+ if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) {
+ lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3];
+ num_sectors = (u32)srb->cmnd[4];
+ } else {
+ lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) |
+ ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
+ num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
+ }
+
+ /* Update sector statistic */
+ tw_dev->sector_count = num_sectors;
+ if (tw_dev->sector_count > tw_dev->max_sector_count)
+ tw_dev->max_sector_count = tw_dev->sector_count;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors);
+ command_packet->byte8.io.lba = lba;
+ command_packet->byte6.block_count = num_sectors;
+
+ /* Do this if there are no sg list entries */
+ if (tw_dev->srb[request_id]->use_sg == 0) {
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n");
+ command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->srb[request_id]->request_buffer);
+ command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
+ }
+
+ /* Do this if we have multiple sg list entries */
+ if (tw_dev->srb[request_id]->use_sg > 0) {
+ for (i=0;i<tw_dev->srb[request_id]->use_sg; i++) {
+ command_packet->byte8.io.sgl[i].address = virt_to_bus(sglist[i].address);
+ command_packet->byte8.io.sgl[i].length = sglist[i].length;
+ command_packet->size+=2;
+ }
+ if (tw_dev->srb[request_id]->use_sg > 1)
+ command_packet->size-=2;
+ }
+
+ /* Update SG statistics */
+ tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
+ if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
+ tw_dev->max_sgl_entries = tw_dev->sgl_entries;
+
+ command_que_value = tw_dev->command_packet_physical_address[request_id];
+ if (command_que_value == 0) {
+ dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n");
+ return 1;
+ }
+
+ /* Now try to post the command to the board */
+ tw_post_command_packet(tw_dev, request_id);
+
+ return 0;
+} /* End tw_scsiop_read_write() */
+
+/* This function will handle test unit ready scsi command */
+int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
+{
+ dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n");
+
+ /* Tell the scsi layer were done */
+ tw_dev->state[request_id] = TW_S_COMPLETED;
+ tw_state_request_finish(tw_dev, request_id);
+ tw_dev->srb[request_id]->result = (DID_OK << 16);
+ tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+
+ return 0;
+} /* End tw_scsiop_test_unit_ready() */
+
+/* This function will setup the interrupt handler */
+int tw_setup_irq(TW_Device_Extension *tw_dev)
+{
+ char *device = TW_DEVICE_NAME;
+ int error;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_setup_irq()\n");
+ error = request_irq(tw_dev->tw_pci_dev->irq, tw_interrupt, SA_SHIRQ, device, tw_dev);
+
+ if (error < 0) {
+ printk(KERN_WARNING "3w-xxxx: tw_setup_irq(): Error requesting IRQ: %d for card %d.\n", tw_dev->tw_pci_dev->irq, tw_dev->host->host_no);
+ return 1;
+ }
+ return 0;
+} /* End tw_setup_irq() */
+
+/* This function will soft reset the controller */
+void tw_soft_reset(TW_Device_Extension *tw_dev)
+{
+ u32 control_reg_addr, control_reg_value;
+
+ control_reg_addr = tw_dev->registers.control_reg_addr;
+ control_reg_value = ( TW_CONTROL_ISSUE_SOFT_RESET |
+ TW_CONTROL_CLEAR_HOST_INTERRUPT |
+ TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |
+ TW_CONTROL_MASK_COMMAND_INTERRUPT |
+ TW_CONTROL_MASK_RESPONSE_INTERRUPT |
+ TW_CONTROL_CLEAR_ERROR_STATUS |
+ TW_CONTROL_DISABLE_INTERRUPTS);
+ outl(control_reg_value, control_reg_addr);
+} /* End tw_soft_reset() */
+
+/* This function will free a request_id */
+int tw_state_request_finish(TW_Device_Extension *tw_dev, int request_id)
+{
+ dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish()\n");
+
+ do {
+ if (tw_dev->free_tail == TW_Q_LENGTH-1) {
+ tw_dev->free_tail = TW_Q_START;
+ } else {
+ tw_dev->free_tail = tw_dev->free_tail + 1;
+ }
+ } while ((tw_dev->state[tw_dev->free_queue[tw_dev->free_tail]] != TW_S_COMPLETED));
+
+ tw_dev->free_queue[tw_dev->free_tail] = request_id;
+
+ tw_dev->state[request_id] = TW_S_FINISHED;
+ dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish(): Freeing request_id %d\n", request_id);
+
+ return 0;
+} /* End tw_state_request_finish() */
+
+/* This function will assign an available request_id */
+int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id)
+{
+ int id = 0;
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start()\n");
+
+ /* Obtain next free request_id */
+ do {
+ if (tw_dev->free_head == TW_Q_LENGTH - 1) {
+ tw_dev->free_head = TW_Q_START;
+ } else {
+ tw_dev->free_head = tw_dev->free_head + 1;
+ }
+ } while ((tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_STARTED) ||
+ (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_POSTED) ||
+ (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_PENDING) ||
+ (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_COMPLETED));
+
+ id = tw_dev->free_queue[tw_dev->free_head];
+
+ if (tw_dev->free_head == TW_Q_LENGTH - 1) {
+ tw_dev->free_head = TW_Q_START;
+ } else {
+ tw_dev->free_head = tw_dev->free_head + 1;
+ }
+
+ dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start(): id = %d.\n", id);
+ *request_id = id;
+ tw_dev->state[id] = TW_S_STARTED;
+
+ return 0;
+} /* End tw_state_request_start() */
+
+/* This function will unmask the command interrupt on the controller */
+void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev)
+{
+ u32 control_reg_addr, control_reg_value;
+
+ control_reg_addr = tw_dev->registers.control_reg_addr;
+ control_reg_value = TW_CONTROL_UNMASK_COMMAND_INTERRUPT;
+ outl(control_reg_value, control_reg_addr);
+} /* End tw_unmask_command_interrupt() */
+
+/* Now get things going */
+
+#ifdef MODULE
+Scsi_Host_Template driver_template = TWXXXX;
+#include "scsi_module.c"
+#endif
diff --git a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
new file mode 100644
index 000000000..f07ad658d
--- /dev/null
+++ b/drivers/scsi/3w-xxxx.h
@@ -0,0 +1,369 @@
+/*
+ 3w-xxxx.h -- 3ware Storage Controller device driver for Linux.
+
+ Written By: Adam Radford <linux@3ware.com>
+ Copyright (C) 1999 3ware Inc.
+
+ Kernel compatablity By: Andre Hedrick <andre@suse.com>
+ Non-Copyright (C) 2000 Andre Hedrick <andre@suse.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; version 2 of the License.
+
+ 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.
+
+ NO WARRANTY
+ THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+ LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+ solely responsible for determining the appropriateness of using and
+ distributing the Program and assumes all risks associated with its
+ exercise of rights under this Agreement, including but not limited to
+ the risks and costs of program errors, damage to or loss of data,
+ programs or equipment, and unavailability or interruption of operations.
+
+ DISCLAIMER OF LIABILITY
+ NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+ HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+ 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
+
+ Bugs/Comments/Suggestions should be mailed to:
+ linux@3ware.com
+
+ For more information, goto:
+ http://www.3ware.com
+*/
+
+#ifndef _3W_XXXX_H
+#define _3W_XXXX_H
+
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+
+/* Control register bit definitions */
+#define TW_CONTROL_CLEAR_HOST_INTERRUPT 0x00080000
+#define TW_CONTROL_CLEAR_ATTENTION_INTERRUPT 0x00040000
+#define TW_CONTROL_MASK_COMMAND_INTERRUPT 0x00020000
+#define TW_CONTROL_MASK_RESPONSE_INTERRUPT 0x00010000
+#define TW_CONTROL_UNMASK_COMMAND_INTERRUPT 0x00008000
+#define TW_CONTROL_UNMASK_RESPONSE_INTERRUPT 0x00004000
+#define TW_CONTROL_CLEAR_ERROR_STATUS 0x00000200
+#define TW_CONTROL_ISSUE_SOFT_RESET 0x00000100
+#define TW_CONTROL_ENABLE_INTERRUPTS 0x00000080
+#define TW_CONTROL_DISABLE_INTERRUPTS 0x00000040
+#define TW_CONTROL_ISSUE_HOST_INTERRUPT 0x00000020
+
+/* Status register bit definitions */
+#define TW_STATUS_MAJOR_VERSION_MASK 0xF0000000
+#define TW_STATUS_MINOR_VERSION_MASK 0x0F000000
+#define TW_STATUS_PCI_PARITY_ERROR 0x00800000
+#define TW_STATUS_QUEUE_ERROR 0x00400000
+#define TW_STATUS_MICROCONTROLLER_ERROR 0x00200000
+#define TW_STATUS_PCI_ABORT 0x00100000
+#define TW_STATUS_HOST_INTERRUPT 0x00080000
+#define TW_STATUS_ATTENTION_INTERRUPT 0x00040000
+#define TW_STATUS_COMMAND_INTERRUPT 0x00020000
+#define TW_STATUS_RESPONSE_INTERRUPT 0x00010000
+#define TW_STATUS_COMMAND_QUEUE_FULL 0x00008000
+#define TW_STATUS_RESPONSE_QUEUE_EMPTY 0x00004000
+#define TW_STATUS_MICROCONTROLLER_READY 0x00002000
+#define TW_STATUS_COMMAND_QUEUE_EMPTY 0x00001000
+#define TW_STATUS_ALL_INTERRUPTS 0x000F0000
+#define TW_STATUS_CLEARABLE_BITS 0x00D00000
+#define TW_STATUS_EXPECTED_BITS 0x00002000
+#define TW_STATUS_UNEXPECTED_BITS 0x00F80000
+
+/* RESPONSE QUEUE BIT DEFINITIONS */
+#define TW_RESPONSE_ID_MASK 0x00000FF0
+
+/* PCI related defines */
+#define TW_IO_ADDRESS_RANGE 0xD
+#define TW_DEVICE_NAME "3ware Storage Controller"
+#define TW_VENDOR_ID (0x13C1) /* 3ware */
+#define TW_DEVICE_ID (0x1000) /* Storage Controller */
+
+/* Command packet opcodes */
+#define TW_OP_NOP 0x0
+#define TW_OP_INIT_CONNECTION 0x1
+#define TW_OP_READ 0x2
+#define TW_OP_WRITE 0x3
+#define TW_OP_VERIFY 0x4
+#define TW_OP_GET_PARAM 0x12
+#define TW_OP_SET_PARAM 0x13
+#define TW_OP_SECTOR_INFO 0x1a
+#define TW_OP_AEN_LISTEN 0x1c
+
+/* Asynchronous Event Notification (AEN) Codes */
+#define TW_AEN_QUEUE_EMPTY 0x0000
+#define TW_AEN_SOFT_RESET 0x0001
+#define TW_AEN_DEGRADED_MIRROR 0x0002
+#define TW_AEN_CONTROLLER_ERROR 0x0003
+#define TW_AEN_REBUILD_FAIL 0x0004
+#define TW_AEN_REBUILD_DONE 0x0005
+#define TW_AEN_QUEUE_FULL 0x00ff
+#define TW_AEN_TABLE_UNDEFINED 0x15
+
+/* Misc defines */
+#define TW_ALIGNMENT 0x200 /* 16 D-WORDS */
+#define TW_MAX_UNITS 16
+#define TW_COMMAND_ALIGNMENT_MASK 0x1ff
+#define TW_INIT_MESSAGE_CREDITS 0x100
+#define TW_INIT_COMMAND_PACKET_SIZE 0x3
+#define TW_POLL_MAX_RETRIES 10000
+#define TW_MAX_SGL_LENGTH 62
+#define TW_Q_LENGTH 256
+#define TW_Q_START 0
+#define TW_MAX_SLOT 32
+#define TW_MAX_PCI_BUSES 255
+#define TW_MAX_RESET_TRIES 3
+#define TW_UNIT_INFORMATION_TABLE_BASE 0x300
+#define TW_MAX_CMDS_PER_LUN (TW_Q_LENGTH-2)/TW_MAX_UNITS
+#define TW_BLOCK_SIZE 0x200 /* 512-byte blocks */
+#define TW_IOCTL 0x80
+#define TW_MAX_AEN_TRIES 100
+
+#define TW_IN_INTR 1
+
+/* Macros */
+#define TW_STATUS_ERRORS(x) \
+ (((x & TW_STATUS_PCI_ABORT) || \
+ (x & TW_STATUS_PCI_PARITY_ERROR) || \
+ (x & TW_STATUS_QUEUE_ERROR) || \
+ (x & TW_STATUS_MICROCONTROLLER_ERROR)) && \
+ (x & TW_STATUS_MICROCONTROLLER_READY))
+
+#ifdef TW_DEBUG
+#define dprintk(msg...) printk(msg)
+#else
+#define dprintk(msg...) do { } while(0);
+#endif
+
+/* Scatter Gather List Entry */
+typedef struct TAG_TW_SG_Entry {
+ unsigned long address;
+ unsigned long length;
+} TW_SG_Entry;
+
+typedef unsigned char TW_Sector[512];
+
+/* Command Packet */
+typedef struct TW_Command {
+ /* First DWORD */
+ struct {
+ unsigned char opcode:5;
+ unsigned char sgl_offset:3;
+ } byte0;
+ unsigned char size;
+ unsigned char request_id;
+ struct {
+ unsigned char unit:4;
+ unsigned char host_id:4;
+ } byte3;
+ /* Second DWORD */
+ unsigned char status;
+ unsigned char flags;
+ union {
+ unsigned short block_count;
+ unsigned short parameter_count;
+ unsigned short message_credits;
+ } byte6;
+ union {
+ struct {
+ unsigned long lba;
+ TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
+ unsigned long padding; /* pad to 512 bytes */
+ } io;
+ struct {
+ TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
+ unsigned long padding[2];
+ } param;
+ struct {
+ unsigned long response_queue_pointer;
+ unsigned long padding[125];
+ } init_connection;
+ struct {
+ char version[504];
+ } ioctl_miniport_version;
+ } byte8;
+} TW_Command;
+
+typedef struct TAG_TW_Ioctl {
+ int buffer;
+ unsigned char opcode;
+ unsigned short table_id;
+ unsigned char parameter_id;
+ unsigned char parameter_size_bytes;
+ unsigned char data[1];
+} TW_Ioctl;
+
+/* GetParam descriptor */
+typedef struct {
+ unsigned short table_id;
+ unsigned char parameter_id;
+ unsigned char parameter_size_bytes;
+ unsigned char data[1];
+} TW_Param, *PTW_Param;
+
+/* Response queue */
+typedef union TAG_TW_Response_Queue {
+ struct {
+ u32 undefined_1: 4;
+ u32 response_id: 8;
+ u32 undefined_2: 20;
+ } u;
+ u32 value;
+} TW_Response_Queue;
+
+typedef struct TAG_TW_Registers {
+ u32 base_addr;
+ u32 control_reg_addr;
+ u32 status_reg_addr;
+ u32 command_que_addr;
+ u32 response_que_addr;
+} TW_Registers;
+
+typedef struct TAG_TW_Info {
+ char *buffer;
+ int length;
+ int offset;
+ int position;
+} TW_Info;
+
+typedef enum TAG_TW_Cmd_State {
+ TW_S_INITIAL, /* Initial state */
+ TW_S_STARTED, /* Id in use */
+ TW_S_POSTED, /* Posted to the controller */
+ TW_S_PENDING, /* Waiting to be posted in isr */
+ TW_S_COMPLETED, /* Completed by isr */
+ TW_S_FINISHED, /* I/O completely done */
+} TW_Cmd_State;
+
+typedef struct TAG_TW_Device_Extension {
+ TW_Registers registers;
+ u32 *alignment_virtual_address[TW_Q_LENGTH];
+ u32 alignment_physical_address[TW_Q_LENGTH];
+ int is_unit_present[TW_MAX_UNITS];
+ int num_units;
+ u32 *command_packet_virtual_address[TW_Q_LENGTH];
+ u32 command_packet_physical_address[TW_Q_LENGTH];
+ struct pci_dev *tw_pci_dev;
+ Scsi_Cmnd *srb[TW_Q_LENGTH];
+ unsigned char free_queue[TW_Q_LENGTH];
+ unsigned char free_head;
+ unsigned char free_tail;
+ unsigned char pending_queue[TW_Q_LENGTH];
+ unsigned char pending_head;
+ unsigned char pending_tail;
+ TW_Cmd_State state[TW_Q_LENGTH];
+ u32 posted_request_count;
+ u32 max_posted_request_count;
+ u32 request_count_marked_pending;
+ u32 pending_request_count;
+ u32 max_pending_request_count;
+ u32 max_sgl_entries;
+ u32 sgl_entries;
+ u32 num_aborts;
+ u32 num_resets;
+ u32 sector_count;
+ u32 max_sector_count;
+ struct Scsi_Host *host;
+ spinlock_t tw_lock;
+ unsigned char ioctl_size[TW_Q_LENGTH];
+ unsigned short aen_queue[TW_Q_LENGTH];
+ unsigned char aen_head;
+ unsigned char aen_tail;
+ u32 flags;
+} TW_Device_Extension;
+
+/* Function prototypes */
+int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id);
+int tw_aen_drain_queue(TW_Device_Extension *tw_dev);
+int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id);
+int tw_allocate_memory(TW_Device_Extension *tw_dev, int request_id, int size, int which);
+int tw_check_bits(u32 status_reg_value);
+int tw_check_errors(TW_Device_Extension *tw_dev);
+void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev);
+void tw_clear_host_interrupt(TW_Device_Extension *tw_dev);
+void tw_disable_interrupts(TW_Device_Extension *tw_dev);
+int tw_empty_response_que(TW_Device_Extension *tw_dev);
+void tw_enable_interrupts(TW_Device_Extension *tw_dev);
+int tw_findcards(Scsi_Host_Template *tw_host);
+void tw_free_device_extension(TW_Device_Extension *tw_dev);
+int tw_initconnection(TW_Device_Extension *tw_dev);
+int tw_initialize_device_extension(TW_Device_Extension *tw_dev);
+int tw_initialize_units(TW_Device_Extension *tw_dev);
+int tw_ioctl(TW_Device_Extension *tw_dev, int request_id);
+int tw_ioctl_complete(TW_Device_Extension *tw_dev, int request_id);
+void tw_mask_command_interrupt(TW_Device_Extension *tw_dev);
+int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds);
+int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id);
+int tw_reset_device_extension(TW_Device_Extension *tw_dev);
+int tw_reset_sequence(TW_Device_Extension *tw_dev);
+int tw_scsi_biosparam(Disk *disk, kdev_t dev, int geom[]);
+int tw_scsi_detect(Scsi_Host_Template *tw_host);
+int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt);
+int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt);
+int tw_scsi_proc_info(char *buffer, char **start, off_t offset, int length, int inode, int inout);
+int tw_scsi_queue(Scsi_Cmnd *cmd, void (*done) (Scsi_Cmnd *));
+int tw_scsi_release(struct Scsi_Host *tw_host);
+int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id);
+int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id);
+int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id);
+int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id);
+int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id);
+int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id);
+int tw_setup_irq(TW_Device_Extension *tw_dev);
+void tw_soft_reset(TW_Device_Extension *tw_dev);
+int tw_state_request_finish(TW_Device_Extension *tw_dev,int request_id);
+int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id);
+void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev);
+
+#if defined(HOSTS_C) || defined(MODULE)
+/* Scsi_Host_Template Initializer */
+#define TWXXXX { \
+ next : NULL, \
+ module : NULL, \
+ proc_name : "3w-xxxx", \
+ proc_info : tw_scsi_proc_info, \
+ name : "3ware Storage Controller", \
+ detect : tw_scsi_detect, \
+ release : tw_scsi_release, \
+ info : NULL, \
+ ioctl : NULL, \
+ command : NULL, \
+ queuecommand : tw_scsi_queue, \
+ eh_strategy_handler : NULL, \
+ eh_abort_handler : tw_scsi_eh_abort, \
+ eh_device_reset_handler : NULL, \
+ eh_bus_reset_handler : NULL, \
+ eh_host_reset_handler : tw_scsi_eh_reset, \
+ abort : NULL, \
+ reset : NULL, \
+ slave_attach : NULL, \
+ bios_param : tw_scsi_biosparam, \
+ can_queue : TW_Q_LENGTH, \
+ this_id: -1, \
+ sg_tablesize : TW_MAX_SGL_LENGTH, \
+ cmd_per_lun: TW_MAX_CMDS_PER_LUN, \
+ present : 0, \
+ unchecked_isa_dma : 0, \
+ use_clustering : ENABLE_CLUSTERING, \
+ use_new_eh_code : 1, \
+ emulated : 1 \
+}
+#endif /* HOSTS_C */
+#endif /* _3W_XXXX_H */
diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c
index 2fbbe449b..a5e0ca0a2 100644
--- a/drivers/scsi/53c7xx.c
+++ b/drivers/scsi/53c7xx.c
@@ -245,7 +245,6 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/errno.h>
-#include <linux/proc_fs.h>
#include <linux/string.h>
#include <linux/malloc.h>
#include <linux/vmalloc.h>
diff --git a/drivers/scsi/Config.in b/drivers/scsi/Config.in
index d83913442..a1a82d96f 100644
--- a/drivers/scsi/Config.in
+++ b/drivers/scsi/Config.in
@@ -30,9 +30,9 @@ dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI
if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then
bool ' Enable Tagged Command Queueing (TCQ) by default' CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
- int 'Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8
+ int ' Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8
bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS
- int 'Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5
+ int ' Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5
fi
dep_tristate 'IBM ServeRAID support' CONFIG_SCSI_IPS $CONFIG_SCSI
dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
@@ -49,7 +49,7 @@ dep_tristate 'EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) supp
if [ "$CONFIG_SCSI_EATA" != "n" ]; then
bool ' enable tagged command queueing' CONFIG_SCSI_EATA_TAGGED_QUEUE
bool ' enable elevator sorting' CONFIG_SCSI_EATA_LINKED_COMMANDS
- int 'maximum number of queued commands' CONFIG_SCSI_EATA_MAX_TAGS 16
+ int ' maximum number of queued commands' CONFIG_SCSI_EATA_MAX_TAGS 16
fi
dep_tristate 'EATA-DMA [Obsolete] (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support' CONFIG_SCSI_EATA_DMA $CONFIG_SCSI
dep_tristate 'EATA-PIO (old DPT PM2001, PM2012A) support' CONFIG_SCSI_EATA_PIO $CONFIG_SCSI
@@ -92,9 +92,9 @@ if [ "$CONFIG_PCI" = "y" -a "$CONFIG_SCSI_NCR53C7xx" != "y" ]; then
dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX $CONFIG_SCSI
dep_tristate 'SYM53C8XX SCSI support' CONFIG_SCSI_SYM53C8XX $CONFIG_SCSI
if [ "$CONFIG_SCSI_NCR53C8XX" != "n" -o "$CONFIG_SCSI_SYM53C8XX" != "n" ]; then
- int 'default tagged command queue depth' CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS 8
- int 'maximum number of queued commands' CONFIG_SCSI_NCR53C8XX_MAX_TAGS 32
- int 'synchronous transfers frequency in MHz' CONFIG_SCSI_NCR53C8XX_SYNC 20
+ int ' default tagged command queue depth' CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS 8
+ int ' maximum number of queued commands' CONFIG_SCSI_NCR53C8XX_MAX_TAGS 32
+ int ' synchronous transfers frequency in MHz' CONFIG_SCSI_NCR53C8XX_SYNC 20
bool ' enable profiling' CONFIG_SCSI_NCR53C8XX_PROFILE
bool ' use normal IO' CONFIG_SCSI_NCR53C8XX_IOMAPPED
if [ "$CONFIG_SCSI_SYM53C8XX" != "n" ]; then
@@ -138,7 +138,7 @@ dep_tristate 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 $CONFIG_SCS
dep_tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F $CONFIG_SCSI
if [ "$CONFIG_SCSI_U14_34F" != "n" ]; then
bool ' enable elevator sorting' CONFIG_SCSI_U14_34F_LINKED_COMMANDS
- int 'maximum number of queued commands' CONFIG_SCSI_U14_34F_MAX_TAGS 8
+ int ' maximum number of queued commands' CONFIG_SCSI_U14_34F_MAX_TAGS 8
fi
dep_tristate 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR $CONFIG_SCSI
#
@@ -155,7 +155,7 @@ fi
if [ "$CONFIG_PPC" = "y" ]; then
dep_tristate 'MESH (Power Mac internal SCSI) support' CONFIG_SCSI_MESH $CONFIG_SCSI
if [ "$CONFIG_SCSI_MESH" != "n" ]; then
- int 'maximum synchronous transfer rate (MB/s) (0 = async)' CONFIG_SCSI_MESH_SYNC_RATE 5
+ int ' maximum synchronous transfer rate (MB/s) (0 = async)' CONFIG_SCSI_MESH_SYNC_RATE 5
fi
dep_tristate '53C94 (Power Mac external SCSI) support' CONFIG_SCSI_MAC53C94 $CONFIG_SCSI
fi
@@ -165,4 +165,8 @@ fi
if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then
bool 'MIPS JAZZ FAS216 SCSI support' CONFIG_JAZZ_ESP
fi
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ dep_tristate '3Ware Hardware ATA-RAID support (EXPERIMENTAL)' CONFIG_BLK_DEV_3W_XXXX_RAID $CONFIG_SCSI
+fi
+
endmenu
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index b4fed17cf..8cf0d3bda 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -41,7 +41,7 @@ ifeq ($(CONFIG_SCSI),y)
endif
L_OBJS += scsi_n_syms.o hosts.o scsi_ioctl.o constants.o scsicam.o
L_OBJS += scsi_error.o scsi_obsolete.o scsi_queue.o scsi_lib.o
- L_OBJS += scsi_merge.o scsi_proc.o
+ L_OBJS += scsi_merge.o scsi_proc.o scsi_dma.o scsi_scan.o
else
ifeq ($(CONFIG_SCSI),m)
MIX_OBJS += scsi_syms.o
@@ -679,6 +679,14 @@ ifeq ($(CONFIG_SUN3X_ESP),y)
L_OBJS += NCR53C9x.o sun3x_esp.o
endif
+ifeq ($(CONFIG_BLK_DEV_3W_XXXX_RAID),y)
+L_OBJS += 3w-xxxx.o
+else
+ ifeq ($(CONFIG_BLK_DEV_3W_XXXX_RAID),m)
+ M_OBJS += 3w-xxxx.o
+ endif
+endif
+
include $(TOPDIR)/Rules.make
53c8xx_d.h: 53c7,8xx.scr script_asm.pl
@@ -726,10 +734,11 @@ megaraid.o: megaraid.c
scsi_mod.o: $(MIX_OBJS) hosts.o scsi.o scsi_ioctl.o constants.o \
scsicam.o scsi_proc.o scsi_error.o scsi_obsolete.o \
- scsi_queue.o scsi_lib.o scsi_merge.o
+ scsi_queue.o scsi_lib.o scsi_merge.o scsi_dma.o scsi_scan.o
$(LD) $(LD_RFLAG) -r -o $@ $(MIX_OBJS) hosts.o scsi.o scsi_ioctl.o \
constants.o scsicam.o scsi_proc.o scsi_merge.o \
- scsi_error.o scsi_obsolete.o scsi_queue.o scsi_lib.o
+ scsi_error.o scsi_obsolete.o scsi_queue.o scsi_lib.o \
+ scsi_dma.o scsi_scan.o
sr_mod.o: sr.o sr_ioctl.o sr_vendor.o
$(LD) $(LD_RFLAG) -r -o $@ sr.o sr_ioctl.o sr_vendor.o
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index 2302d39a8..319f961f4 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -188,9 +188,8 @@ int __init a2091_detect(Scsi_Host_Template *tpnt)
{
static unsigned char called = 0;
struct Scsi_Host *instance;
- caddr_t address;
- unsigned int key;
- const struct ConfigDev *cd;
+ unsigned long address;
+ struct zorro_dev *z = NULL;
if (!MACH_IS_AMIGA || called)
return 0;
@@ -199,14 +198,19 @@ int __init a2091_detect(Scsi_Host_Template *tpnt)
tpnt->proc_name = "A2091";
tpnt->proc_info = &wd33c93_proc_info;
- while ((key = zorro_find(ZORRO_PROD_CBM_A590_A2091_1, 0, 0)) ||
- (key = zorro_find(ZORRO_PROD_CBM_A590_A2091_2, 0, 0))) {
- cd = zorro_get_board(key);
- address = cd->cd_BoardAddr;
+ while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
+ if (z->id != ZORRO_PROD_CBM_A590_A2091_1 &&
+ z->id != ZORRO_PROD_CBM_A590_A2091_2)
+ continue;
+ address = z->resource.start;
+ if (!request_mem_region(address, 256, "wd33c93"))
+ continue;
+ strcpy(z->name, "A590/A2091 SCSI Host Adapter");
+
instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata));
- instance->base = (unsigned char *)ZTWO_VADDR(address);
+ instance->base = ZTWO_VADDR(address);
instance->irq = IRQ_AMIGA_PORTS;
- instance->unique_id = key;
+ instance->unique_id = z->slotaddr;
DMA(instance)->DAWR = DAWR_A2091;
wd33c93_init(instance, (wd33c93_regs *)&(DMA(instance)->SASR),
dma_setup, dma_stop, WD33C93_FS_8_10);
@@ -217,7 +221,6 @@ int __init a2091_detect(Scsi_Host_Template *tpnt)
a2091_intr);
}
DMA(instance)->CNTR = CNTR_PDMD | CNTR_INTEN;
- zorro_config_board(key, 0);
}
return num_a2091;
@@ -239,7 +242,7 @@ int a2091_release(struct Scsi_Host *instance)
{
#ifdef MODULE
DMA(instance)->CNTR = 0;
- zorro_unconfig_board(instance->unique_id, 0);
+ release_mem_region(ZTWO_PADDR(instance->base), 256);
if (--num_a2091 == 0)
free_irq(IRQ_AMIGA_PORTS, a2091_intr);
wd33c93_release();
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c
index 1bc8f05fa..fd28a9ef2 100644
--- a/drivers/scsi/a3000.c
+++ b/drivers/scsi/a3000.c
@@ -175,7 +175,7 @@ int __init a3000_detect(Scsi_Host_Template *tpnt)
tpnt->proc_info = &wd33c93_proc_info;
a3000_host = scsi_register (tpnt, sizeof(struct WD33C93_hostdata));
- a3000_host->base = (unsigned char *)ZTWO_VADDR(0xDD0000);
+ a3000_host->base = ZTWO_VADDR(0xDD0000);
a3000_host->irq = IRQ_AMIGA_PORTS;
DMA(a3000_host)->DAWR = DAWR_A3000;
wd33c93_init(a3000_host, (wd33c93_regs *)&(DMA(a3000_host)->SASR),
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index e2f4397b2..f4834a51f 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -21,8 +21,11 @@
* Modified by Chris Faulhaber <jedgar@fxp.org>
* Added module command-line options
* 19-Jul-99
+ * Modified by Adam Fritzler <mid@auk.cx>
+ * Added proper detection of the AHA-1640 (MCA version of AHA-1540)
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -40,6 +43,8 @@
#include <asm/system.h>
#include <asm/io.h>
#include <linux/blk.h>
+#include <linux/mca.h>
+
#include "scsi.h"
#include "hosts.h"
@@ -96,7 +101,7 @@ static void BAD_SG_DMA(Scsi_Cmnd * SCpnt,
#define MAXBOARDS 4 /* Increase this and the sizes of the
arrays below, if you need more.. */
-/* Boards 3,4 slots are reserved for ISAPnP scans */
+/* Boards 3,4 slots are reserved for ISAPnP/MCA scans */
static unsigned int bases[MAXBOARDS] = {0x330, 0x334, 0, 0};
@@ -1043,6 +1048,69 @@ int aha1542_detect(Scsi_Host_Template * tpnt)
setup_dmaspeed[0] = atbt;
}
#endif
+
+ /*
+ * Find MicroChannel cards (AHA1640)
+ */
+#ifdef CONFIG_MCA
+ if(MCA_bus) {
+ int slot = 0;
+ int pos = 0;
+
+ for (indx = 0; (slot != MCA_NOTFOUND) &&
+ (indx < sizeof(bases)/sizeof(bases[0])); indx++) {
+
+ if (bases[indx])
+ continue;
+
+ /* Detect only AHA-1640 cards -- MCA ID 0F1F */
+ slot = mca_find_unused_adapter(0x0f1f, slot);
+ if (slot == MCA_NOTFOUND)
+ break;
+
+
+ /* Found one */
+ pos = mca_read_stored_pos(slot, 3);
+
+ /* Decode address */
+ if (pos & 0x80) {
+ if (pos & 0x02) {
+ if (pos & 0x01)
+ bases[indx] = 0x334;
+ else
+ bases[indx] = 0x234;
+ } else {
+ if (pos & 0x01)
+ bases[indx] = 0x134;
+ }
+ } else {
+ if (pos & 0x02) {
+ if (pos & 0x01)
+ bases[indx] = 0x330;
+ else
+ bases[indx] = 0x230;
+ } else {
+ if (pos & 0x01)
+ bases[indx] = 0x130;
+ }
+ }
+
+ /* No need to decode IRQ and Arb level -- those are
+ * read off the card later.
+ */
+ printk(KERN_INFO "Found an AHA-1640 in MCA slot %d, I/O 0x%04x\n", slot, bases[indx]);
+
+ mca_set_adapter_name(slot, "Adapter AHA-1640");
+ mca_set_adapter_procfn(slot, NULL, NULL);
+ mca_mark_as_used(slot);
+
+ /* Go on */
+ slot++;
+ }
+
+ }
+#endif
+
/*
* Hunt for ISA Plug'n'Pray Adaptecs (AHA1535)
*/
diff --git a/drivers/scsi/aic7xxx/aic7xxx.seq b/drivers/scsi/aic7xxx/aic7xxx.seq
index 07729599f..8e8dc98ee 100644
--- a/drivers/scsi/aic7xxx/aic7xxx.seq
+++ b/drivers/scsi/aic7xxx/aic7xxx.seq
@@ -48,7 +48,7 @@
* a later time. This problem cannot be resolved by holding a single entry
* in scratch ram since a reconnecting target can request sense and this will
* create yet another SCB waiting for selection. The solution used here is to
- * use byte 27 of the SCB as a psuedo-next pointer and to thread a list
+ * use byte 27 of the SCB as a pseudo-next pointer and to thread a list
* of SCBs that are awaiting selection. Since 0-0xfe are valid SCB indexes,
* SCB_LIST_NULL is 0xff which is out of range. An entry is also added to
* this list everytime a request sense occurs or after completing a non-tagged
diff --git a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c
index f35eac3ad..217d79819 100644
--- a/drivers/scsi/amiga7xx.c
+++ b/drivers/scsi/amiga7xx.c
@@ -38,107 +38,105 @@ extern int ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip,
int __init amiga7xx_detect(Scsi_Host_Template *tpnt)
{
static unsigned char called = 0;
- unsigned int key;
int num = 0, clock;
long long options;
- const struct ConfigDev *cd;
+ struct zorro_dev *z = NULL;
+ unsigned long address;
if (called || !MACH_IS_AMIGA)
return 0;
tpnt->proc_name = "Amiga7xx";
-#ifdef CONFIG_BLZ603EPLUS_SCSI
- if ((key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS, 0, 0)))
- {
- cd = zorro_get_board(key);
-
- options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT;
-
- clock = 50000000; /* 50MHz SCSI Clock */
-
- ncr53c7xx_init(tpnt, 0, 710, (u32)ZTWO_VADDR(0xf40000), 0,
- IRQ_AMIGA_PORTS, DMA_NONE, options, clock);
-
- zorro_config_board(key, 0);
- num++;
+#ifdef CONFIG_A4000T_SCSI
+ if (AMIGAHW_PRESENT(A4000_SCSI)) {
+ address = 0xdd0040;
+ if (request_mem_region(address, 0x1000, "ncr53c710")) {
+ address = ZTWO_VADDR(address);
+ options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 |
+ OPTION_INTFLY | OPTION_SYNCHRONOUS |
+ OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT;
+ clock = 50000000; /* 50MHz SCSI Clock */
+ ncr53c7xx_init(tpnt, 0, 710, address, 0, IRQ_AMIGA_PORTS, DMA_NONE,
+ options, clock);
+ num++;
+ }
}
#endif
-#ifdef CONFIG_WARPENGINE_SCSI
- if ((key = zorro_find(ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx, 0, 0)))
- {
- unsigned long address;
- cd = zorro_get_board(key);
- address = (unsigned long)ioremap((unsigned long)cd->cd_BoardAddr,
- cd->cd_BoardSize);
-
- options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT;
-
- clock = 50000000; /* 50MHz SCSI Clock */
-
- ncr53c7xx_init(tpnt, 0, 710, (u32)(unsigned char *)(address + 0x40000),
- 0, IRQ_AMIGA_PORTS, DMA_NONE, options, clock);
-
- zorro_config_board(key, 0);
- num++;
- }
+ while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
+ unsigned long address = z->resource.start;
+ unsigned long size = z->resource.end-z->resource.start+1;
+ switch (z->id) {
+#ifdef CONFIG_BLZ603EPLUS_SCSI
+ case ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS:
+ address = 0xf40000;
+ if (request_mem_region(address, 0x1000, "ncr53c710")) {
+ strcpy(z->name,
+ "Blizzard 603e+ Accelerator and SCSI Host Adapter");
+ address = ZTWO_VADDR(address);
+ options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 |
+ OPTION_INTFLY | OPTION_SYNCHRONOUS |
+ OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT;
+ clock = 50000000; /* 50MHz SCSI Clock */
+ ncr53c7xx_init(tpnt, 0, 710, address, 0, IRQ_AMIGA_PORTS,
+ DMA_NONE, options, clock);
+ num++;
+ }
+ break;
#endif
-#ifdef CONFIG_A4000T_SCSI
- if (AMIGAHW_PRESENT(A4000_SCSI))
- {
- options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT;
-
- clock = 50000000; /* 50MHz SCSI Clock */
-
- ncr53c7xx_init(tpnt, 0, 710, (u32)ZTWO_VADDR(0xDD0040), 0,
- IRQ_AMIGA_PORTS, DMA_NONE, options, clock);
- num++;
- }
+#ifdef CONFIG_WARPENGINE_SCSI
+ case ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx:
+ if (request_mem_region(address+0x40000, 0x1000, "ncr53c710")) {
+ strcpy(z->name, "Warp Engine 40xx Accelerator, SCSI Host "
+ "Adapter and RAM Expansion");
+ address = (unsigned long)ioremap(address, size);
+ options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 |
+ OPTION_INTFLY | OPTION_SYNCHRONOUS |
+ OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT;
+ clock = 50000000; /* 50MHz SCSI Clock */
+ ncr53c7xx_init(tpnt, 0, 710, address+0x40000, 0,
+ IRQ_AMIGA_PORTS, DMA_NONE, options, clock);
+ num++;
+ }
+ break;
#endif
#ifdef CONFIG_A4091_SCSI
- while ( (key = zorro_find(ZORRO_PROD_CBM_A4091_1, 0, 0)) ||
- (key = zorro_find(ZORRO_PROD_CBM_A4091_2, 0, 0)) )
- {
- unsigned long address;
- cd = zorro_get_board(key);
- address = (unsigned long)ioremap((unsigned long)cd->cd_BoardAddr,
- cd->cd_BoardSize);
-
- options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT;
-
- clock = 50000000; /* 50MHz SCSI Clock */
-
- ncr53c7xx_init(tpnt, 0, 710, (u32)(unsigned char *)(address+0x800000),
- 0, IRQ_AMIGA_PORTS, DMA_NONE, options, clock);
-
- zorro_config_board(key, 0);
- num++;
- }
+ case ZORRO_PROD_CBM_A4091_1:
+ case ZORRO_PROD_CBM_A4091_2:
+ if (request_mem_region(address+0x800000, 0x1000, "ncr53c710")) {
+ strcpy(z->name, "A4091 SCSI Host Adapter");
+ address = (unsigned long)ioremap(address, size);
+ options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 |
+ OPTION_INTFLY | OPTION_SYNCHRONOUS |
+ OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT;
+ clock = 50000000; /* 50MHz SCSI Clock */
+ ncr53c7xx_init(tpnt, 0, 710, address+0x800000, 0,
+ IRQ_AMIGA_PORTS, DMA_NONE, options, clock);
+ num++;
+ }
+ break;
#endif
#ifdef CONFIG_GVP_TURBO_SCSI
- if((key = zorro_find(ZORRO_PROD_GVP_GFORCE_040_060, 0, 0)))
- {
- cd = zorro_get_board(key);
- address = ZTWO_VADDR((unsigned long)cd->cd_BoardAddr);
-
- options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 |
- OPTION_INTFLY | OPTION_SYNCHRONOUS |
- OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT;
-
- clock = 50000000; /* 50MHz SCSI Clock */
-
- ncr53c7xx_init(tpnt, 0, 710,
- (u32)(unsigned char *)(address + 0x40000),
- 0, IRQ_AMIGA_PORTS, DMA_NONE, options, clock);
-
- zorro_config_board(key, 0);
- num++;
- }
+ case ZORRO_PROD_GVP_GFORCE_040_060:
+ if (request_mem_region(address+0x40000, 0x1000, "ncr53c710")) {
+ strcpy(z->name, "GForce 040/060 Accelerator and SCSI Host "
+ "Adapter");
+ address = ZTWO_VADDR(address);
+ options = OPTION_MEMORY_MAPPED | OPTION_DEBUG_TEST1 |
+ OPTION_INTFLY | OPTION_SYNCHRONOUS |
+ OPTION_ALWAYS_SYNCHRONOUS | OPTION_DISCONNECT;
+ clock = 50000000; /* 50MHz SCSI Clock */
+ ncr53c7xx_init(tpnt, 0, 710, address+0x40000, 0,
+ IRQ_AMIGA_PORTS, DMA_NONE, options, clock);
+ num++;
+ }
#endif
+ }
+ }
called = 1;
return num;
diff --git a/drivers/scsi/blz1230.c b/drivers/scsi/blz1230.c
index 143bdf9eb..bd437e7e1 100644
--- a/drivers/scsi/blz1230.c
+++ b/drivers/scsi/blz1230.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
+#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/types.h>
@@ -60,37 +61,41 @@ volatile unsigned char cmd_buffer[16];
int __init blz1230_esp_detect(Scsi_Host_Template *tpnt)
{
struct NCR_ESP *esp;
- const struct ConfigDev *esp_dev;
- unsigned int key;
+ struct zorro_dev *z = NULL;
unsigned long address;
struct ESP_regs *eregs;
#if MKIV
- if ((key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_1230_IV_1260, 0, 0))){
+#define REAL_BLZ1230_ID ZORRO_PROD_PHASE5_BLIZZARD_1230_IV_1260
+#define REAL_BLZ1230_ESP_ADDR BLZ1230_ESP_ADDR
+#define REAL_BLZ1230_DMA_ADDR BLZ1230_DMA_ADDR
#else
- if ((key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060, 0, 0))){
+#define REAL_BLZ1230_ID ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060
+#define REAL_BLZ1230_ESP_ADDR BLZ1230II_ESP_ADDR
+#define REAL_BLZ1230_DMA_ADDR BLZ1230II_DMA_ADDR
#endif
- esp_dev = zorro_get_board(key);
+ if ((z = zorro_find_device(REAL_BLZ1230_ID, z))) {
+ unsigned long board = z->resource.start;
+ if (request_mem_region(board+REAL_BLZ1230_ESP_ADDR,
+ sizeof(struct ESP_regs), "NCR53C9x")) {
/* Do some magic to figure out if the blizzard is
* equipped with a SCSI controller
*/
- address = (unsigned long)ZTWO_VADDR(esp_dev->cd_BoardAddr);
-#if MKIV
- eregs = (struct ESP_regs *)(address + BLZ1230_ESP_ADDR);
-#else
- eregs = (struct ESP_regs *)(address + BLZ1230II_ESP_ADDR);
-#endif
-
- esp = esp_allocate(tpnt, (void *) esp_dev);
+ address = ZTWO_VADDR(board);
+ eregs = (struct ESP_regs *)(address + REAL_BLZ1230_ESP_ADDR);
+ esp = esp_allocate(tpnt, (void *)board+REAL_BLZ1230_ESP_ADDR);
esp_write(eregs->esp_cfg1, (ESP_CONFIG1_PENABLE | 7));
udelay(5);
if(esp_read(eregs->esp_cfg1) != (ESP_CONFIG1_PENABLE | 7)){
esp_deallocate(esp);
scsi_unregister(esp->ehost);
+ release_mem_region(board+REAL_BLZ1230_ESP_ADDR,
+ sizeof(struct ESP_regs));
return 0; /* Bail out if address did not hold data */
}
+ strcpy(z->name, "Blizzard 1230 SCSI IV");
/* Do command transfer with programmed I/O */
esp->do_pio_cmds = 1;
@@ -125,11 +130,7 @@ int __init blz1230_esp_detect(Scsi_Host_Template *tpnt)
* relative to the device (i.e. in the same Zorro
* I/O block).
*/
-#if MKIV
- esp->dregs = (void *)(address + BLZ1230_DMA_ADDR);
-#else
- esp->dregs = (void *)(address + BLZ1230II_DMA_ADDR);
-#endif
+ esp->dregs = (void *)(address + REAL_BLZ1230_DMA_ADDR);
/* ESP register base */
esp->eregs = eregs;
@@ -139,7 +140,7 @@ int __init blz1230_esp_detect(Scsi_Host_Template *tpnt)
esp->esp_command_dvma = virt_to_bus(cmd_buffer);
esp->irq = IRQ_AMIGA_PORTS;
- esp->slot = key;
+ esp->slot = board+REAL_BLZ1230_ESP_ADDR;
request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ,
"Blizzard 1230 SCSI IV", esp_intr);
@@ -151,11 +152,10 @@ int __init blz1230_esp_detect(Scsi_Host_Template *tpnt)
esp_initialize(esp);
- zorro_config_board(key, 0);
-
printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use);
esps_running = esps_in_use;
return esps_in_use;
+ }
}
return 0;
}
@@ -289,12 +289,10 @@ Scsi_Host_Template driver_template = SCSI_BLZ1230;
int blz1230_esp_release(struct Scsi_Host *instance)
{
#ifdef MODULE
- unsigned int key;
-
- key = ((struct NCR_ESP *)instance->hostdata)->slot;
+ unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev;
esp_deallocate((struct NCR_ESP *)instance->hostdata);
esp_release();
- zorro_unconfig_board(key, 0);
+ release_mem_region(address, sizeof(struct ESP_regs));
free_irq(IRQ_AMIGA_PORTS, esp_intr);
#endif
return 1;
diff --git a/drivers/scsi/blz2060.c b/drivers/scsi/blz2060.c
index 3301528e4..72a67027b 100644
--- a/drivers/scsi/blz2060.c
+++ b/drivers/scsi/blz2060.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
+#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/types.h>
@@ -60,13 +61,16 @@ volatile unsigned char cmd_buffer[16];
int __init blz2060_esp_detect(Scsi_Host_Template *tpnt)
{
struct NCR_ESP *esp;
- const struct ConfigDev *esp_dev;
- unsigned int key;
+ struct zorro_dev *z = NULL;
unsigned long address;
- if ((key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_2060, 0, 0))){
- esp_dev = zorro_get_board(key);
- esp = esp_allocate(tpnt, (void *) esp_dev);
+ if ((z = zorro_find_device(ZORRO_PROD_PHASE5_BLIZZARD_2060, z))) {
+ unsigned long board = z->resource.start;
+ if (request_mem_region(board+BLZ2060_ESP_ADDR,
+ sizeof(struct ESP_regs), "NCR53C9x")) {
+ strcpy(z->name, "Blizzard 2060 Accelerator");
+
+ esp = esp_allocate(tpnt, (void *)board+BLZ2060_ESP_ADDR);
/* Do command transfer with programmed I/O */
esp->do_pio_cmds = 1;
@@ -101,7 +105,7 @@ int __init blz2060_esp_detect(Scsi_Host_Template *tpnt)
* relative to the device (i.e. in the same Zorro
* I/O block).
*/
- address = (unsigned long)ZTWO_VADDR(esp_dev->cd_BoardAddr);
+ address = (unsigned long)ZTWO_VADDR(board);
esp->dregs = (void *)(address + BLZ2060_DMA_ADDR);
/* ESP register base */
@@ -112,7 +116,6 @@ int __init blz2060_esp_detect(Scsi_Host_Template *tpnt)
esp->esp_command_dvma = virt_to_bus(cmd_buffer);
esp->irq = IRQ_AMIGA_PORTS;
- esp->slot = key;
request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ,
"Blizzard 2060 SCSI", esp_intr);
@@ -124,11 +127,10 @@ int __init blz2060_esp_detect(Scsi_Host_Template *tpnt)
esp_initialize(esp);
- zorro_config_board(key, 0);
-
printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use);
esps_running = esps_in_use;
return esps_in_use;
+ }
}
return 0;
}
@@ -249,12 +251,11 @@ Scsi_Host_Template driver_template = SCSI_BLZ2060;
int blz2060_esp_release(struct Scsi_Host *instance)
{
#ifdef MODULE
- unsigned int key;
+ unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev;
- key = ((struct NCR_ESP *)instance->hostdata)->slot;
esp_deallocate((struct NCR_ESP *)instance->hostdata);
esp_release();
- zorro_unconfig_board(key, 0);
+ release_mem_region(address, sizeof(struct ESP_regs));
free_irq(IRQ_AMIGA_PORTS, esp_intr);
#endif
return 1;
diff --git a/drivers/scsi/cyberstorm.c b/drivers/scsi/cyberstorm.c
index 6f89486a5..4d720b99a 100644
--- a/drivers/scsi/cyberstorm.c
+++ b/drivers/scsi/cyberstorm.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
+#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/types.h>
@@ -69,24 +70,28 @@ volatile unsigned char cmd_buffer[16];
int __init cyber_esp_detect(Scsi_Host_Template *tpnt)
{
struct NCR_ESP *esp;
- const struct ConfigDev *esp_dev;
- unsigned int key;
+ struct zorro_dev *z = NULL;
unsigned long address;
-
- if ((key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM, 0, 0)) ||
- (key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060, 0, 0))){
- esp_dev = zorro_get_board(key);
-
+ while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
+ unsigned long board = z->resource.start;
+ if ((z->id == ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM ||
+ z->id == ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060) &&
+ request_mem_region(board+CYBER_ESP_ADDR,
+ sizeof(struct ESP_regs), "NCR53C9x")) {
/* Figure out if this is a CyberStorm or really a
* Fastlane/Blizzard Mk II by looking at the board size.
* CyberStorm maps 64kB
* (ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM does anyway)
*/
- if((unsigned long)esp_dev->cd_BoardSize != 0x10000)
+ if(z->resource.end-board != 0xffff) {
+ release_mem_region(board+CYBER_ESP_ADDR,
+ sizeof(struct ESP_regs));
return 0;
+ }
+ strcpy(z->name, "Cyberstorm SCSI Host Adapter");
- esp = esp_allocate(tpnt, (void *) esp_dev);
+ esp = esp_allocate(tpnt, (void *)board+CYBER_ESP_ADDR);
/* Do command transfer with programmed I/O */
esp->do_pio_cmds = 1;
@@ -121,7 +126,7 @@ int __init cyber_esp_detect(Scsi_Host_Template *tpnt)
* relative to the device (i.e. in the same Zorro
* I/O block).
*/
- address = (unsigned long)ZTWO_VADDR(esp_dev->cd_BoardAddr);
+ address = (unsigned long)ZTWO_VADDR(board);
esp->dregs = (void *)(address + CYBER_DMA_ADDR);
/* ESP register base */
@@ -132,7 +137,6 @@ int __init cyber_esp_detect(Scsi_Host_Template *tpnt)
esp->esp_command_dvma = virt_to_bus(cmd_buffer);
esp->irq = IRQ_AMIGA_PORTS;
- esp->slot = key;
request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ,
"CyberStorm SCSI", esp_intr);
/* Figure out our scsi ID on the bus */
@@ -148,11 +152,10 @@ int __init cyber_esp_detect(Scsi_Host_Template *tpnt)
esp_initialize(esp);
- zorro_config_board(key, 0);
-
printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use);
esps_running = esps_in_use;
return esps_in_use;
+ }
}
return 0;
}
@@ -314,12 +317,11 @@ Scsi_Host_Template driver_template = SCSI_CYBERSTORM;
int cyber_esp_release(struct Scsi_Host *instance)
{
#ifdef MODULE
- unsigned int key;
+ unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev;
- key = ((struct NCR_ESP *)instance->hostdata)->slot;
esp_deallocate((struct NCR_ESP *)instance->hostdata);
esp_release();
- zorro_unconfig_board(key, 0);
+ release_mem_region(address, sizeof(struct ESP_regs));
free_irq(IRQ_AMIGA_PORTS, esp_intr);
#endif
return 1;
diff --git a/drivers/scsi/cyberstormII.c b/drivers/scsi/cyberstormII.c
index 3f2b85de8..9ff180665 100644
--- a/drivers/scsi/cyberstormII.c
+++ b/drivers/scsi/cyberstormII.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
+#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/types.h>
@@ -59,29 +60,32 @@ volatile unsigned char cmd_buffer[16];
int __init cyberII_esp_detect(Scsi_Host_Template *tpnt)
{
struct NCR_ESP *esp;
- const struct ConfigDev *esp_dev;
- unsigned int key;
+ struct zorro_dev *z = NULL;
unsigned long address;
struct ESP_regs *eregs;
- if((key = zorro_find(ZORRO_PROD_PHASE5_CYBERSTORM_MK_II, 0, 0))){
- esp_dev = zorro_get_board(key);
-
+ if ((z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERSTORM_MK_II, z))) {
+ unsigned long board = z->resource.start;
+ if (request_mem_region(board+CYBERII_ESP_ADDR,
+ sizeof(struct ESP_regs), "NCR53C9x")) {
/* Do some magic to figure out if the CyberStorm Mk II
* is equipped with a SCSI controller
*/
- address = (unsigned long)ZTWO_VADDR(esp_dev->cd_BoardAddr);
+ address = (unsigned long)ZTWO_VADDR(board);
eregs = (struct ESP_regs *)(address + CYBERII_ESP_ADDR);
- esp = esp_allocate(tpnt, (void *) esp_dev);
+ esp = esp_allocate(tpnt, (void *)board+CYBERII_ESP_ADDR);
esp_write(eregs->esp_cfg1, (ESP_CONFIG1_PENABLE | 7));
udelay(5);
if(esp_read(eregs->esp_cfg1) != (ESP_CONFIG1_PENABLE | 7)) {
esp_deallocate(esp);
scsi_unregister(esp->ehost);
+ release_mem_region(board+CYBERII_ESP_ADDR,
+ sizeof(struct ESP_regs));
return 0; /* Bail out if address did not hold data */
}
+ strcpy(z->name, "CyberStorm Mk II SCSI Host Adapter");
/* Do command transfer with programmed I/O */
esp->do_pio_cmds = 1;
@@ -126,7 +130,6 @@ int __init cyberII_esp_detect(Scsi_Host_Template *tpnt)
esp->esp_command_dvma = virt_to_bus(cmd_buffer);
esp->irq = IRQ_AMIGA_PORTS;
- esp->slot = key;
request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ,
"CyberStorm SCSI Mk II", esp_intr);
@@ -138,11 +141,10 @@ int __init cyberII_esp_detect(Scsi_Host_Template *tpnt)
esp_initialize(esp);
- zorro_config_board(key, 0);
-
printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use);
esps_running = esps_in_use;
return esps_in_use;
+ }
}
return 0;
}
@@ -264,12 +266,11 @@ Scsi_Host_Template driver_template = SCSI_CYBERSTORMII;
int cyberII_esp_release(struct Scsi_Host *instance)
{
#ifdef MODULE
- unsigned int key;
+ unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev;
- key = ((struct NCR_ESP *)instance->hostdata)->slot;
esp_deallocate((struct NCR_ESP *)instance->hostdata);
esp_release();
- zorro_unconfig_board(key, 0);
+ release_mem_region(address, sizeof(struct ESP_regs));
free_irq(IRQ_AMIGA_PORTS, esp_intr);
#endif
return 1;
diff --git a/drivers/scsi/eata_dma.c b/drivers/scsi/eata_dma.c
index 4e45fc849..97f94f442 100644
--- a/drivers/scsi/eata_dma.c
+++ b/drivers/scsi/eata_dma.c
@@ -113,16 +113,6 @@ static int fake_int_happened;
static ulong int_counter = 0;
static ulong queue_counter = 0;
-void eata_scsi_done (Scsi_Cmnd * scmd)
-{
- scmd->request.rq_status = RQ_SCSI_DONE;
-
- if (scmd->request.sem != NULL)
- up(scmd->request.sem);
-
- return;
-}
-
void eata_fake_int_handler(s32 irq, void *dev_id, struct pt_regs * regs)
{
fake_int_result = inb((ulong)fake_int_base + HA_RSTATUS);
diff --git a/drivers/scsi/eata_dma_proc.c b/drivers/scsi/eata_dma_proc.c
index c32b9480a..dd6034561 100644
--- a/drivers/scsi/eata_dma_proc.c
+++ b/drivers/scsi/eata_dma_proc.c
@@ -67,10 +67,10 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length,
int hostno, int inout)
{
- Scsi_Device *scd, SDev;
+ Scsi_Device *scd, *SDev;
struct Scsi_Host *HBA_ptr;
- Scsi_Cmnd scmd;
- char cmnd[10];
+ Scsi_Cmnd * scmd;
+ char cmnd[MAX_COMMAND_SIZE];
static u8 buff[512];
static u8 buff2[512];
hst_cmd_stat *rhcs, *whcs;
@@ -152,13 +152,8 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length,
pos = begin + len;
} else {
- memset(&SDev, 0, sizeof(Scsi_Device));
- memset(&scmd, 0, sizeof(Scsi_Cmnd));
-
- SDev.host = HBA_ptr;
- SDev.id = HBA_ptr->this_id;
- SDev.lun = 0;
- SDev.channel = 0;
+ SDev = scsi_get_host_dev(HBA_ptr);
+ scmd = scsi_allocate_device(SDev, 1, FALSE);
cmnd[0] = LOG_SENSE;
cmnd[1] = 0;
@@ -171,26 +166,13 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length,
cmnd[8] = 0x66;
cmnd[9] = 0;
- scmd.cmd_len = 10;
+ scmd->cmd_len = 10;
- scmd.host = HBA_ptr;
- scmd.device = &SDev;
- scmd.target = HBA_ptr->this_id;
- scmd.lun = 0;
- scmd.channel = 0;
- scmd.use_sg = 0;
-
/*
* Do the command and wait for it to finish.
*/
- {
- DECLARE_MUTEX_LOCKED(sem);
- scmd.request.rq_status = RQ_SCSI_BUSY;
- scmd.request.sem = &sem;
- scsi_do_cmd (&scmd, cmnd, buff + 0x144, 0x66,
- eata_scsi_done, 1 * HZ, 1);
- down(&sem);
- }
+ scsi_wait_cmd (scmd, cmnd, buff + 0x144, 0x66,
+ 1 * HZ, 1);
size = sprintf(buffer + len, "IRQ: %2d, %s triggered\n", cc->interrupt,
(cc->intt == TRUE)?"level":"edge");
@@ -308,19 +290,13 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length,
cmnd[8] = 0x44;
cmnd[9] = 0;
- scmd.cmd_len = 10;
+ scmd->cmd_len = 10;
/*
* Do the command and wait for it to finish.
*/
- {
- DECLARE_MUTEX_LOCKED(sem);
- scmd.request.rq_status = RQ_SCSI_BUSY;
- scmd.request.sem = &sem;
- scsi_do_cmd (&scmd, cmnd, buff2, 0x144,
- eata_scsi_done, 1 * HZ, 1);
- down(&sem);
- }
+ scsi_wait_cmd (scmd, cmnd, buff2, 0x144,
+ 1 * HZ, 1);
swap_statistics(buff2);
rhcs = (hst_cmd_stat *)(buff2 + 0x2c);
@@ -354,6 +330,9 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length,
len += size;
pos = begin + len;
}
+
+ scsi_release_command(scmd);
+ scsi_free_host_dev(SDev);
}
if (pos < offset) {
diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c
index b03d41316..fd315c1f7 100644
--- a/drivers/scsi/esp.c
+++ b/drivers/scsi/esp.c
@@ -791,7 +791,7 @@ static int __init esp_map_cmdarea(struct esp *esp)
{
struct sbus_dev *sdev = esp->sdev;
- esp->esp_command = sbus_alloc_consistant(sdev, 16,
+ esp->esp_command = sbus_alloc_consistent(sdev, 16,
&esp->esp_command_dvma);
if (esp->esp_command == NULL ||
esp->esp_command_dvma == 0)
@@ -1114,7 +1114,7 @@ static int __init detect_one_esp(Scsi_Host_Template *tpnt, struct sbus_dev *esp_
return 0;
fail_unmap_cmdarea:
- sbus_free_consistant(esp->sdev, 16,
+ sbus_free_consistent(esp->sdev, 16,
(void *) esp->esp_command,
esp->esp_command_dvma);
@@ -1420,8 +1420,8 @@ static void esp_get_dmabufs(struct esp *esp, Scsi_Cmnd *sp)
sp->SCp.buffers_residual = sbus_map_sg(esp->sdev,
sp->SCp.buffer,
sp->use_sg);
- sp->SCp.this_residual = sp->SCp.buffer->dvma_length;
- sp->SCp.ptr = (char *) ((unsigned long)sp->SCp.buffer->dvma_address);
+ sp->SCp.this_residual = sg_dma_len(sp->SCp.buffer);
+ sp->SCp.ptr = (char *) ((unsigned long)sg_dma_address(sp->SCp.buffer));
}
}
@@ -2537,8 +2537,8 @@ static inline void advance_sg(Scsi_Cmnd *sp)
{
++sp->SCp.buffer;
--sp->SCp.buffers_residual;
- sp->SCp.this_residual = sp->SCp.buffer->dvma_length;
- sp->SCp.ptr = (char *)((unsigned long)sp->SCp.buffer->dvma_address);
+ sp->SCp.this_residual = sg_dma_len(sp->SCp.buffer);
+ sp->SCp.ptr = (char *)((unsigned long)sg_dma_address(sp->SCp.buffer));
}
/* Please note that the way I've coded these routines is that I _always_
diff --git a/drivers/scsi/fastlane.c b/drivers/scsi/fastlane.c
index 998fdb8bc..1c23fd858 100644
--- a/drivers/scsi/fastlane.c
+++ b/drivers/scsi/fastlane.c
@@ -24,6 +24,7 @@
#include <linux/module.h>
+#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/types.h>
@@ -83,22 +84,25 @@ volatile unsigned char cmd_buffer[16];
int __init fastlane_esp_detect(Scsi_Host_Template *tpnt)
{
struct NCR_ESP *esp;
- const struct ConfigDev *esp_dev;
- unsigned int key;
+ struct zorro_dev *z = NULL;
unsigned long address;
- if ((key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060, 0, 0))){
-
- esp_dev = zorro_get_board(key);
-
+ if ((z = zorro_find_device(ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060, z))) {
+ unsigned long board = z->resource.start;
+ if (request_mem_region(board+FASTLANE_ESP_ADDR,
+ sizeof(struct ESP_regs), "NCR53C9x")) {
/* Check if this is really a fastlane controller. The problem
* is that also the cyberstorm and blizzard controllers use
* this ID value. Fortunately only Fastlane maps in Z3 space
*/
- if((unsigned long)esp_dev->cd_BoardAddr < 0x1000000)
+ if (board < 0x1000000) {
+ release_mem_region(board+FASTLANE_ESP_ADDR,
+ sizeof(struct ESP_regs));
return 0;
+ }
+ strcpy(z->name, "Fastlane Z3 SCSI Host Adapter");
- esp = esp_allocate(tpnt, (void *) esp_dev);
+ esp = esp_allocate(tpnt, (void *)board+FASTLANE_ESP_ADDR);
/* Do command transfer with programmed I/O */
esp->do_pio_cmds = 1;
@@ -140,12 +144,13 @@ int __init fastlane_esp_detect(Scsi_Host_Template *tpnt)
/* Map the physical address space into virtual kernel space */
address = (unsigned long)
- ioremap_nocache((unsigned long)esp_dev->cd_BoardAddr,
- esp_dev->cd_BoardSize);
+ ioremap_nocache(board, z->resource.end-board+1);
if(!address){
printk("Could not remap Fastlane controller memory!");
scsi_unregister (esp->ehost);
+ release_mem_region(board+FASTLANE_ESP_ADDR,
+ sizeof(struct ESP_regs));
return 0;
}
@@ -167,7 +172,7 @@ int __init fastlane_esp_detect(Scsi_Host_Template *tpnt)
esp->esp_command_dvma = virt_to_bus(cmd_buffer);
esp->irq = IRQ_AMIGA_PORTS;
- esp->slot = key;
+ esp->slot = board+FASTLANE_ESP_ADDR;
request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ,
"Fastlane SCSI", esp_intr);
@@ -180,11 +185,10 @@ int __init fastlane_esp_detect(Scsi_Host_Template *tpnt)
dma_clear(esp);
esp_initialize(esp);
- zorro_config_board(key, 0);
-
printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use);
esps_running = esps_in_use;
return esps_in_use;
+ }
}
return 0;
}
@@ -360,12 +364,10 @@ Scsi_Host_Template driver_template = SCSI_FASTLANE;
int fastlane_esp_release(struct Scsi_Host *instance)
{
#ifdef MODULE
- unsigned int key;
-
- key = ((struct NCR_ESP *)instance->hostdata)->slot;
+ unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev;
esp_deallocate((struct NCR_ESP *)instance->hostdata);
esp_release();
- zorro_unconfig_board(key, 0);
+ release_mem_region(address, sizeof(struct ESP_regs));
free_irq(IRQ_AMIGA_PORTS, esp_intr);
#endif
return 1;
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index e318395b2..cb42f6b7a 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -3157,7 +3157,7 @@ int __init gdth_detect(Scsi_Host_Template *shtp)
NUMDATA(shp)->busnum= 0;
ha->pccb = CMDDATA(shp);
- ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
+ ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, GDTH_SCRATCH_ORD);
ha->scratch_busy = FALSE;
ha->req_first = NULL;
ha->tid_cnt = MAX_HDRIVES;
@@ -3172,7 +3172,7 @@ int __init gdth_detect(Scsi_Host_Template *shtp)
--gdth_ctr_count;
--gdth_ctr_vcount;
if (ha->pscratch != NULL)
- scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
+ free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD);
free_irq(ha->irq,NULL);
scsi_unregister(shp);
continue;
@@ -3223,7 +3223,7 @@ int __init gdth_detect(Scsi_Host_Template *shtp)
NUMDATA(shp)->hanum));
ha->pccb = CMDDATA(shp);
- ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
+ ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, GDTH_SCRATCH_ORD);
ha->scratch_busy = FALSE;
ha->req_first = NULL;
ha->tid_cnt = MAX_HDRIVES;
@@ -3238,7 +3238,7 @@ int __init gdth_detect(Scsi_Host_Template *shtp)
--gdth_ctr_count;
--gdth_ctr_vcount;
if (ha->pscratch != NULL)
- scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
+ free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD);
free_irq(ha->irq,NULL);
scsi_unregister(shp);
continue;
@@ -3293,7 +3293,7 @@ int __init gdth_detect(Scsi_Host_Template *shtp)
NUMDATA(shp)->busnum= 0;
ha->pccb = CMDDATA(shp);
- ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
+ ha->pscratch = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, GDTH_SCRATCH_ORD);
ha->scratch_busy = FALSE;
ha->req_first = NULL;
ha->tid_cnt = pcistr[ctr].device_id >= 0x200 ? MAXID : MAX_HDRIVES;
@@ -3308,7 +3308,7 @@ int __init gdth_detect(Scsi_Host_Template *shtp)
--gdth_ctr_count;
--gdth_ctr_vcount;
if (ha->pscratch != NULL)
- scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
+ free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD);
free_irq(ha->irq,NULL);
scsi_unregister(shp);
continue;
@@ -3359,7 +3359,7 @@ int gdth_release(struct Scsi_Host *shp)
if (shp->dma_channel != 0xff) {
free_dma(shp->dma_channel);
}
- scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
+ free_pages((unsigned long)ha->pscratch, GDTH_SCRATCH_ORD);
gdth_ctr_released++;
TRACE2(("gdth_release(): HA %d of %d\n",
gdth_ctr_released, gdth_ctr_count));
@@ -3561,21 +3561,18 @@ static void gdth_flush(int hanum)
{
int i;
gdth_ha_str *ha;
- Scsi_Cmnd scp;
- Scsi_Device sdev;
+ Scsi_Cmnd * scp;
+ Scsi_Device * sdev;
gdth_cmd_str gdtcmd;
TRACE2(("gdth_flush() hanum %d\n",hanum));
ha = HADATA(gdth_ctr_tab[hanum]);
- memset(&sdev,0,sizeof(Scsi_Device));
- memset(&scp, 0,sizeof(Scsi_Cmnd));
- sdev.host = gdth_ctr_tab[hanum];
- sdev.id = sdev.host->this_id;
- scp.cmd_len = 12;
- scp.host = gdth_ctr_tab[hanum];
- scp.target = sdev.host->this_id;
- scp.device = &sdev;
- scp.use_sg = 0;
+
+ sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+ scp = scsi_allocate_device(sdev, 1, FALSE);
+
+ scp->cmd_len = 12;
+ scp->use_sg = 0;
for (i = 0; i < MAX_HDRIVES; ++i) {
if (ha->hdr[i].present) {
@@ -3586,9 +3583,11 @@ static void gdth_flush(int hanum)
gdtcmd.u.cache.BlockNo = 1;
gdtcmd.u.cache.sg_canz = 0;
TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i));
- gdth_do_cmd(&scp, &gdtcmd, 30);
+ gdth_do_cmd(scp, &gdtcmd, 30);
}
}
+ scsi_release_command(scp);
+ scsi_free_host_dev(sdev);
}
/* shutdown routine */
@@ -3596,8 +3595,8 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
{
int hanum;
#ifndef __alpha__
- Scsi_Cmnd scp;
- Scsi_Device sdev;
+ Scsi_Cmnd * scp;
+ Scsi_Device * sdev;
gdth_cmd_str gdtcmd;
#endif
@@ -3610,23 +3609,21 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
#ifndef __alpha__
/* controller reset */
- memset(&sdev,0,sizeof(Scsi_Device));
- memset(&scp, 0,sizeof(Scsi_Cmnd));
- sdev.host = gdth_ctr_tab[hanum];
- sdev.id = sdev.host->this_id;
- scp.cmd_len = 12;
- scp.host = gdth_ctr_tab[hanum];
- scp.target = sdev.host->this_id;
- scp.device = &sdev;
- scp.use_sg = 0;
+ sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
+ scp = scsi_allocate_device(sdev, 1, FALSE);
+ scp->cmd_len = 12;
+ scp->use_sg = 0;
gdtcmd.BoardNode = LOCALBOARD;
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_RESET;
TRACE2(("gdth_halt(): reset controller %d\n", hanum));
- gdth_do_cmd(&scp, &gdtcmd, 10);
+ gdth_do_cmd(scp, &gdtcmd, 10);
+ scsi_release_command(scp);
+ scsi_free_host_dev(sdev);
#endif
}
+
printk("Done.\n");
#ifdef GDTH_STATISTICS
diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h
index 2fa420b25..946c78254 100644
--- a/drivers/scsi/gdth.h
+++ b/drivers/scsi/gdth.h
@@ -126,7 +126,8 @@
#endif
/* limits */
-#define GDTH_SCRATCH 4096 /* 4KB scratch buffer */
+#define GDTH_SCRATCH PAGE_SIZE /* 4KB scratch buffer */
+#define GDTH_SCRATCH_ORD 0 /* order 0 means 1 page */
#define GDTH_MAXCMDS 124
#define GDTH_MAXC_P_L 16 /* max. cmds per lun */
#define GDTH_MAX_RAW 2 /* max. cmds per raw device */
diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c
index 6d0112aba..24861d034 100644
--- a/drivers/scsi/gdth_proc.c
+++ b/drivers/scsi/gdth_proc.c
@@ -31,22 +31,17 @@ int gdth_proc_info(char *buffer,char **start,off_t offset,int length,
static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum)
{
int ret_val;
- Scsi_Cmnd scp;
- Scsi_Device sdev;
+ Scsi_Cmnd * scp;
+ Scsi_Device * sdev;
gdth_iowr_str *piowr;
TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum));
piowr = (gdth_iowr_str *)buffer;
- memset(&sdev,0,sizeof(Scsi_Device));
- memset(&scp, 0,sizeof(Scsi_Cmnd));
- sdev.host = gdth_ctr_vtab[vh];
- sdev.id = sdev.host->this_id;
- scp.cmd_len = 12;
- scp.host = gdth_ctr_vtab[vh];
- scp.target = sdev.host->this_id;
- scp.device = &sdev;
- scp.use_sg = 0;
+ sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
+ scp = scsi_allocate_device(sdev, 1, FALSE);
+ scp->cmd_len = 12;
+ scp->use_sg = 0;
if (length >= 4) {
if (strncmp(buffer,"gdth",4) == 0) {
@@ -62,10 +57,14 @@ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum)
} else {
ret_val = -EINVAL;
}
+
+ scsi_release_command(scp);
+ scsi_free_host_dev(sdev);
+
return ret_val;
}
-static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
+static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd * scp)
{
int orig_length, drive, wb_mode;
int i, found;
@@ -105,7 +104,7 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd.u.cache.DeviceNo = i;
gdtcmd.u.cache.BlockNo = 1;
gdtcmd.u.cache.sg_canz = 0;
- gdth_do_cmd(&scp, &gdtcmd, 30);
+ gdth_do_cmd(scp, &gdtcmd, 30);
}
}
if (!found)
@@ -158,7 +157,7 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd.u.ioctl.subfunc = CACHE_CONFIG;
gdtcmd.u.ioctl.channel = INVALID_CHANNEL;
pcpar->write_back = wb_mode==1 ? 0:1;
- gdth_do_cmd(&scp, &gdtcmd, 30);
+ gdth_do_cmd(scp, &gdtcmd, 30);
gdth_ioctl_free(hanum);
printk("Done.\n");
return(orig_length);
@@ -168,7 +167,7 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
return(-EINVAL);
}
-static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
+static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd * scp)
{
unchar i, j;
gdth_ha_str *ha;
@@ -241,8 +240,8 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
*ppadd2 = virt_to_bus(piord->iu.general.data+add_size);
}
/* do IOCTL */
- gdth_do_cmd(&scp, pcmd, piowr->timeout);
- piord->status = (ulong32)scp.SCp.Message;
+ gdth_do_cmd(scp, pcmd, piowr->timeout);
+ piord->status = (ulong32)scp->SCp.Message;
break;
case GDTIOCTL_DRVERS:
@@ -401,8 +400,8 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
gdth_cmd_str gdtcmd;
gdth_evt_str estr;
- Scsi_Cmnd scp;
- Scsi_Device sdev;
+ Scsi_Cmnd * scp;
+ Scsi_Device *sdev;
char hrec[161];
struct timeval tv;
@@ -417,15 +416,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
ha = HADATA(gdth_ctr_tab[hanum]);
id = length;
- memset(&sdev,0,sizeof(Scsi_Device));
- memset(&scp, 0,sizeof(Scsi_Cmnd));
- sdev.host = gdth_ctr_vtab[vh];
- sdev.id = sdev.host->this_id;
- scp.cmd_len = 12;
- scp.host = gdth_ctr_vtab[vh];
- scp.target = sdev.host->this_id;
- scp.device = &sdev;
- scp.use_sg = 0;
+ sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
+ scp = scsi_allocate_device(sdev, 1, FALSE);
+ scp->cmd_len = 12;
+ scp->use_sg = 0;
/* look for buffer ID in length */
if (id > 1) {
@@ -531,11 +525,11 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
sizeof(pds->list[0]);
if (pds->entries > cnt)
pds->entries = cnt;
- gdth_do_cmd(&scp, &gdtcmd, 30);
- if (scp.SCp.Message != S_OK)
+ gdth_do_cmd(scp, &gdtcmd, 30);
+ if (scp->SCp.Message != S_OK)
pds->count = 0;
TRACE2(("pdr_statistics() entries %d status %d\n",
- pds->count, scp.SCp.Message));
+ pds->count, scp->SCp.Message));
/* other IOCTLs must fit into area GDTH_SCRATCH/4 */
for (j = 0; j < ha->raw[i].pdev_cnt; ++j) {
@@ -551,8 +545,8 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
gdtcmd.u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN;
gdtcmd.u.ioctl.channel =
ha->raw[i].address | ha->raw[i].id_list[j];
- gdth_do_cmd(&scp, &gdtcmd, 30);
- if (scp.SCp.Message == S_OK) {
+ gdth_do_cmd(scp, &gdtcmd, 30);
+ if (scp->SCp.Message == S_OK) {
strncpy(hrec,pdi->vendor,8);
strncpy(hrec+8,pdi->product,16);
strncpy(hrec+24,pdi->revision,4);
@@ -602,8 +596,8 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
gdtcmd.u.ioctl.channel =
ha->raw[i].address | ha->raw[i].id_list[j];
pdef->sddc_type = 0x08;
- gdth_do_cmd(&scp, &gdtcmd, 30);
- if (scp.SCp.Message == S_OK) {
+ gdth_do_cmd(scp, &gdtcmd, 30);
+ if (scp->SCp.Message == S_OK) {
size = sprintf(buffer+len,
" Grown Defects:\t%d\n",
pdef->sddc_cnt);
@@ -649,8 +643,8 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
gdtcmd.u.ioctl.param_size = sizeof(gdth_cdrinfo_str);
gdtcmd.u.ioctl.subfunc = CACHE_DRV_INFO;
gdtcmd.u.ioctl.channel = drv_no;
- gdth_do_cmd(&scp, &gdtcmd, 30);
- if (scp.SCp.Message != S_OK)
+ gdth_do_cmd(scp, &gdtcmd, 30);
+ if (scp->SCp.Message != S_OK)
break;
pcdi->ld_dtype >>= 16;
j++;
@@ -746,8 +740,8 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
gdtcmd.u.ioctl.param_size = sizeof(gdth_arrayinf_str);
gdtcmd.u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN;
gdtcmd.u.ioctl.channel = i;
- gdth_do_cmd(&scp, &gdtcmd, 30);
- if (scp.SCp.Message == S_OK) {
+ gdth_do_cmd(scp, &gdtcmd, 30);
+ if (scp->SCp.Message == S_OK) {
if (pai->ai_state == 0)
strcpy(hrec, "idle");
else if (pai->ai_state == 2)
@@ -821,8 +815,8 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
gdtcmd.u.ioctl.channel = i;
phg->entries = MAX_HDRIVES;
phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]);
- gdth_do_cmd(&scp, &gdtcmd, 30);
- if (scp.SCp.Message != S_OK) {
+ gdth_do_cmd(scp, &gdtcmd, 30);
+ if (scp->SCp.Message != S_OK) {
ha->hdr[i].ldr_no = i;
ha->hdr[i].rw_attribs = 0;
ha->hdr[i].start_sec = 0;
@@ -837,7 +831,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
}
}
TRACE2(("host_get entries %d status %d\n",
- phg->entries, scp.SCp.Message));
+ phg->entries, scp->SCp.Message));
}
gdth_ioctl_free(hanum);
@@ -915,6 +909,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
}
stop_output:
+
+ scsi_release_command(scp);
+ scsi_free_host_dev(sdev);
+
*start = buffer +(offset-begin);
len -= (offset-begin);
if (len > length)
@@ -926,11 +924,11 @@ stop_output:
static void gdth_do_cmd(Scsi_Cmnd *scp,gdth_cmd_str *gdtcmd,int timeout)
{
- char cmnd[12];
+ char cmnd[MAX_COMMAND_SIZE];
DECLARE_MUTEX_LOCKED(sem);
TRACE2(("gdth_do_cmd()\n"));
- memset(cmnd, 0, 12);
+ memset(cmnd, 0, MAX_COMMAND_SIZE);
scp->request.rq_status = RQ_SCSI_BUSY;
scp->request.sem = &sem;
scp->SCp.this_residual = IOCTL_PRI;
diff --git a/drivers/scsi/gdth_proc.h b/drivers/scsi/gdth_proc.h
index 1a6f2d164..8af8e71e6 100644
--- a/drivers/scsi/gdth_proc.h
+++ b/drivers/scsi/gdth_proc.h
@@ -6,8 +6,8 @@
*/
static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum);
-static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp);
-static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp);
+static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd * scp);
+static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd * scp);
static int gdth_get_info(char *buffer,char **start,off_t offset,
int length,int vh,int hanum,int busnum);
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c
index d905012ba..0c6150964 100644
--- a/drivers/scsi/gvp11.c
+++ b/drivers/scsi/gvp11.c
@@ -75,7 +75,8 @@ static int dma_setup (Scsi_Cmnd *cmd, int dir_in)
if ( scsi_alloc_out_of_range || !HDATA(cmd->host)->dma_bounce_buffer) {
HDATA(cmd->host)->dma_bounce_buffer =
- amiga_chip_alloc(HDATA(cmd->host)->dma_bounce_len);
+ amiga_chip_alloc(HDATA(cmd->host)->dma_bounce_len,
+ "GVP II SCSI Bounce Buffer");
if(!HDATA(cmd->host)->dma_bounce_buffer)
{
@@ -100,7 +101,8 @@ static int dma_setup (Scsi_Cmnd *cmd, int dir_in)
}
HDATA(cmd->host)->dma_bounce_buffer =
- amiga_chip_alloc(HDATA(cmd->host)->dma_bounce_len);
+ amiga_chip_alloc(HDATA(cmd->host)->dma_bounce_len,
+ "GVP II SCSI Bounce Buffer");
if(!HDATA(cmd->host)->dma_bounce_buffer)
{
@@ -180,10 +182,9 @@ int __init gvp11_detect(Scsi_Host_Template *tpnt)
{
static unsigned char called = 0;
struct Scsi_Host *instance;
- caddr_t address;
+ unsigned long address;
unsigned int epc;
- unsigned int key = 0, skey;
- const struct ConfigDev *cd;
+ struct zorro_dev *z = NULL;
unsigned int default_dma_xfer_mask;
#ifdef CHECK_WD33C93
volatile unsigned char *sasr_3393, *scmd_3393;
@@ -198,38 +199,39 @@ int __init gvp11_detect(Scsi_Host_Template *tpnt)
tpnt->proc_name = "GVP11";
tpnt->proc_info = &wd33c93_proc_info;
- while (1) {
+ while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
/*
* This should (hopefully) be the correct way to identify
* all the different GVP SCSI controllers (except for the
* SERIES I though).
*/
- skey = key;
- if ((key = zorro_find(ZORRO_PROD_GVP_COMBO_030_R3_SCSI, 0, skey)) ||
- (key = zorro_find(ZORRO_PROD_GVP_SERIES_II, 0, skey)))
+ if (z->id == ZORRO_PROD_GVP_COMBO_030_R3_SCSI ||
+ z->id == ZORRO_PROD_GVP_SERIES_II)
default_dma_xfer_mask = ~0x00ffffff;
- else if ((key = zorro_find(ZORRO_PROD_GVP_GFORCE_030_SCSI, 0, skey)) ||
- (key = zorro_find(ZORRO_PROD_GVP_A530_SCSI, 0, skey)) ||
- (key = zorro_find(ZORRO_PROD_GVP_COMBO_030_R4_SCSI, 0, skey)))
+ else if (z->id == ZORRO_PROD_GVP_GFORCE_030_SCSI ||
+ z->id == ZORRO_PROD_GVP_A530_SCSI ||
+ z->id == ZORRO_PROD_GVP_COMBO_030_R4_SCSI)
default_dma_xfer_mask = ~0x01ffffff;
- else if ((key = zorro_find(ZORRO_PROD_GVP_A1291, 0, skey)) ||
- (key = zorro_find(ZORRO_PROD_GVP_GFORCE_040_SCSI_1, 0, skey)))
+ else if (z->id == ZORRO_PROD_GVP_A1291 ||
+ z->id == ZORRO_PROD_GVP_GFORCE_040_SCSI_1)
default_dma_xfer_mask = ~0x07ffffff;
else
- break;
-
- cd = zorro_get_board(key);
- address = cd->cd_BoardAddr;
+ continue;
/*
* Rumors state that some GVP ram boards use the same product
* code as the SCSI controllers. Therefore if the board-size
* is not 64KB we asume it is a ram board and bail out.
*/
- if (cd->cd_BoardSize != 0x10000)
+ if (z->resource.end-z->resource.start != 0xffff)
continue;
+ address = z->resource.start;
+ if (!request_mem_region(address, 256, "wd33c93"))
+ continue;
+ strcpy(z->name, "GVP Series II SCSI");
+
#ifdef CHECK_WD33C93
/*
@@ -251,18 +253,18 @@ int __init gvp11_detect(Scsi_Host_Template *tpnt)
q = *sasr_3393; /* read it */
if (q & 0x08) /* bit 3 should always be clear */
- continue;
+ goto release;
*sasr_3393 = WD_AUXILIARY_STATUS; /* setup indirect address */
if (*sasr_3393 == WD_AUXILIARY_STATUS) { /* shouldn't retain the write */
*sasr_3393 = save_sasr; /* Oops - restore this byte */
- continue;
+ goto release;
}
if (*sasr_3393 != q) { /* should still read the same */
*sasr_3393 = save_sasr; /* Oops - restore this byte */
- continue;
+ goto release;
}
if (*scmd_3393 != q) /* and so should the image at 0x1f */
- continue;
+ goto release;
/* Ok, we probably have a wd33c93, but let's check a few other places
@@ -279,7 +281,7 @@ int __init gvp11_detect(Scsi_Host_Template *tpnt)
*sasr_3393 = WD_SCSI_STATUS;
*scmd_3393 = q;
if (qq != q) /* should be read only */
- continue;
+ goto release;
*sasr_3393 = 0x1e; /* this register is unimplemented */
q = *scmd_3393;
*sasr_3393 = 0x1e;
@@ -289,7 +291,7 @@ int __init gvp11_detect(Scsi_Host_Template *tpnt)
*sasr_3393 = 0x1e;
*scmd_3393 = q;
if (qq != q || qq != 0xff) /* should be read only, all 1's */
- continue;
+ goto release;
*sasr_3393 = WD_TIMEOUT_PERIOD;
q = *scmd_3393;
*sasr_3393 = WD_TIMEOUT_PERIOD;
@@ -299,13 +301,13 @@ int __init gvp11_detect(Scsi_Host_Template *tpnt)
*sasr_3393 = WD_TIMEOUT_PERIOD;
*scmd_3393 = q;
if (qq != (~q & 0xff)) /* should be read/write */
- continue;
+ goto release;
#endif
instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata));
- instance->base = (unsigned char *)ZTWO_VADDR(address);
+ instance->base = ZTWO_VADDR(address);
instance->irq = IRQ_AMIGA_PORTS;
- instance->unique_id = key;
+ instance->unique_id = z->slotaddr;
if (gvp11_xfer_mask)
HDATA(instance)->dma_xfer_mask = gvp11_xfer_mask;
@@ -340,7 +342,10 @@ int __init gvp11_detect(Scsi_Host_Template *tpnt)
"GVP11 SCSI", gvp11_intr);
}
DMA(instance)->CNTR = GVP11_DMAC_INT_ENABLE;
- zorro_config_board(key, 0);
+ continue;
+
+release:
+ release_mem_region(ZTWO_PADDR(instance->base), 256);
}
return num_gvp11;
@@ -363,7 +368,7 @@ int gvp11_release(struct Scsi_Host *instance)
{
#ifdef MODULE
DMA(instance)->CNTR = 0;
- zorro_unconfig_board(instance->unique_id, 0);
+ release_mem_region(ZTWO_PADDR(instance->base), 256);
if (--num_gvp11 == 0)
free_irq(IRQ_AMIGA_PORTS, gvp11_intr);
wd33c93_release();
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 81a94ad30..33aaaeabe 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -355,6 +355,10 @@
#include "../net/fc/iph5526_scsi.h"
#endif
+#ifdef CONFIG_BLK_DEV_3W_XXXX_RAID
+#include "3w-xxxx.h"
+#endif
+
/*
* Moved ppa driver to the end of the probe list
* since it is a removable host adapter.
@@ -635,7 +639,10 @@ static Scsi_Host_Template builtin_scsi_hosts[] =
#endif
#ifdef CONFIG_SCSI_DECNCR
SCSI_DEC_ESP,
-#endif
+#endif
+#ifdef CONFIG_BLK_DEV_3W_XXXX_RAID
+ TWXXXX,
+#endif
/* "Removable host adapters" below this line (Parallel Port/USB/other) */
#ifdef CONFIG_SCSI_PPA
PPA,
@@ -886,7 +893,6 @@ unsigned int __init scsi_init(void)
printk ("scsi : %d host%s.\n", next_scsi_host,
(next_scsi_host == 1) ? "" : "s");
-
/* Now attach the high level drivers */
#ifdef CONFIG_BLK_DEV_SD
scsi_register_device(&sd_template);
diff --git a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
index a2c810f97..1ce17904a 100644
--- a/drivers/scsi/hosts.h
+++ b/drivers/scsi/hosts.h
@@ -334,7 +334,6 @@ struct Scsi_Host
unsigned int max_lun;
unsigned int max_channel;
-
/* These parameters should be set by the detect routine */
unsigned long base;
unsigned long io_port;
@@ -435,6 +434,17 @@ unsigned int scsi_init(void);
extern struct Scsi_Host * scsi_register(Scsi_Host_Template *, int j);
extern void scsi_unregister(struct Scsi_Host * i);
+extern request_fn_proc * scsi_get_request_handler(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt);
+
+/*
+ * Prototypes for functions/data in scsi_scan.c
+ */
+extern void scan_scsis(struct Scsi_Host *shpnt,
+ unchar hardcoded,
+ unchar hchannel,
+ unchar hid,
+ unchar hlun);
+
extern void scsi_mark_host_reset(struct Scsi_Host *Host);
#define BLANK_HOST {"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 863bb3fce..959195aef 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -237,52 +237,17 @@ static void mega_Convert8ldTo40ld( mega_RAIDINQ *inquiry,
megaRaidProductInfo *productInfo );
+#include <linux/smp.h>
-
-#if LINUX_VERSION_CODE > 0x020100
-# include <asm/spinlock.h>
-# include <linux/smp.h>
-# define cpuid smp_processor_id()
-# if LINUX_VERSION_CODE < 0x020195
-# define DRIVER_LOCK_T unsigned long cpu_flags = 0;
-# define DRIVER_LOCK_INIT(p) \
- spin_lock_init(&p->mega_lock);
-# define DRIVER_LOCK(p) \
- if(!p->cpu_lock_count[cpuid]) { \
- spin_lock_irqsave(&p->mega_lock, cpu_flags); \
- p->cpu_lock_count[cpuid]++; \
- } else { \
- p->cpu_lock_count[cpuid]++; \
- }
-# define DRIVER_UNLOCK(p) \
- if(--p->cpu_lock_count[cpuid] == 0) \
- spin_unlock_irqrestore(&p->mega_lock, cpu_flags);
-# define IO_LOCK(p) spin_lock_irqsave(&io_request_lock,cpu_flags);
-# define IO_UNLOCK(p) spin_unlock_irqrestore(&io_request_lock,cpu_flags);
-# else
-# define DRIVER_LOCK_T
-# define DRIVER_LOCK_INIT(p)
-# define DRIVER_LOCK(p)
-# define DRIVER_UNLOCK(p)
-# define IO_LOCK_T unsigned long io_flags = 0;
-# define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags);
-# define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags);
-# endif
-#else
-# define cpuid 0
-# define DRIVER_LOCK_T long cpu_flags;
-# define DRIVER_LOCK_INIT(p)
-# define DRIVER_LOCK(p) \
- save_flags(cpu_flags); \
- cli();
-# define DRIVER_UNLOCK(p) \
- restore_flags(cpu_flags);
-# define IO_LOCK(p) DRIVER_LOCK(p)
-# define IO_UNLOCK(p) DRIVER_UNLOCK(p)
-# define le32_to_cpu(x) (x)
-# define cpu_to_le32(x) (x)
-#endif
+#define cpuid smp_processor_id()
+#define DRIVER_LOCK_T
+#define DRIVER_LOCK_INIT(p)
+#define DRIVER_LOCK(p)
+#define DRIVER_UNLOCK(p)
+#define IO_LOCK_T unsigned long io_flags = 0;
+#define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags);
+#define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags);
/* set SERDEBUG to 1 to enable serial debugging */
#define SERDEBUG 0
diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
index 9a8935935..f650b5ae6 100644
--- a/drivers/scsi/megaraid.h
+++ b/drivers/scsi/megaraid.h
@@ -152,7 +152,7 @@
sg_tablesize: MAX_SGLIST, /* Scatter/Gather Table Size */\
cmd_per_lun: MAX_CMD_PER_LUN, /* SCSI Commands per LUN */\
present: 0, /* Present */\
- unchecked_isa_dma:1, /* Default Unchecked ISA DMA */\
+ unchecked_isa_dma:0, /* Default Unchecked ISA DMA */\
use_clustering: ENABLE_CLUSTERING /* Enable Clustering */\
}
#endif
diff --git a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c
index ecfbb8778..61a8128c2 100644
--- a/drivers/scsi/oktagon_esp.c
+++ b/drivers/scsi/oktagon_esp.c
@@ -116,24 +116,25 @@ volatile unsigned char cmd_buffer[16];
int oktagon_esp_detect(Scsi_Host_Template *tpnt)
{
struct NCR_ESP *esp;
- const struct ConfigDev *esp_dev;
- int key;
+ struct zorro_dev *z = NULL;
unsigned long address;
struct ESP_regs *eregs;
- if((key = zorro_find(ZORRO_PROD_BSC_OKTAGON_2008, 0, 0))){
- esp_dev = zorro_get_board(key);
-
+ while ((z = zorro_find_device(ZORRO_PROD_BSC_OKTAGON_2008, z))) {
+ unsigned long board = z->resource.start;
+ if (request_mem_region(board+OKTAGON_ESP_ADDR,
+ sizeof(struct ESP_regs), "NCR53C9x")) {
+ strcpy(z->name, "Oktagon 2008 SCSI Host Adapter");
/*
* It is a SCSI controller.
* Hardwire Host adapter to SCSI ID 7
*/
- address = (unsigned long)ZTWO_VADDR(esp_dev->cd_BoardAddr);
+ address = (unsigned long)ZTWO_VADDR(board);
eregs = (struct ESP_regs *)(address + OKTAGON_ESP_ADDR);
/* This line was 5 lines lower */
- esp = esp_allocate(tpnt, (void *) esp_dev);
+ esp = esp_allocate(tpnt, (void *)board+OKTAGON_ESP_ADDR);
/* we have to shift the registers only one bit for oktagon */
esp->shift = 1;
@@ -197,7 +198,6 @@ int oktagon_esp_detect(Scsi_Host_Template *tpnt)
esp->esp_command_dvma = (__u32) cmd_buffer;
esp->irq = IRQ_AMIGA_PORTS;
- esp->slot = key;
request_irq(IRQ_AMIGA_PORTS, esp_intr, SA_SHIRQ,
"BSC Oktagon SCSI", esp_intr);
@@ -209,7 +209,6 @@ int oktagon_esp_detect(Scsi_Host_Template *tpnt)
esp_initialize(esp);
- zorro_config_board(key, 0);
printk("ESP_Oktagon Driver 1.1"
#ifdef USE_BOTTOM_HALF
" [BOTTOM_HALF]"
@@ -222,6 +221,7 @@ int oktagon_esp_detect(Scsi_Host_Template *tpnt)
current_esp = esp;
register_reboot_notifier(&oktagon_notifier);
return esps_in_use;
+ }
}
return 0;
}
@@ -585,11 +585,9 @@ Scsi_Host_Template driver_template = SCSI_OKTAGON_ESP;
int oktagon_esp_release(struct Scsi_Host *instance)
{
#ifdef MODULE
- unsigned int key;
-
- key = ((struct NCR_ESP *)instance->hostdata)->slot;
+ unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev;
esp_release();
- zorro_unconfig_board(key, 0);
+ release_mem_region(address, sizeof(struct ESP_regs));
free_irq(IRQ_AMIGA_PORTS, esp_intr);
unregister_reboot_notifier(&oktagon_notifier);
#endif
diff --git a/drivers/scsi/pci2220i.h b/drivers/scsi/pci2220i.h
index c3b80dd9c..1c75c8c3b 100644
--- a/drivers/scsi/pci2220i.h
+++ b/drivers/scsi/pci2220i.h
@@ -248,7 +248,7 @@ typedef struct _IDENTIFY_DATA
USHORT SupportLBA :1; // 49 LBA supported
USHORT SupportIORDYDisable :1; // 49 IORDY can be disabled
USHORT SupportIORDY :1; // 49 IORDY supported
- USHORT ReservedPsuedoDMA :1; // 49 reserved for pseudo DMA mode support
+ USHORT ReservedPseudoDMA :1; // 49 reserved for pseudo DMA mode support
USHORT Reserved3 :3; // 49
USHORT Reserved4; // 50
USHORT Reserved5 :8; // 51 Transfer Cycle Timing - PIO
diff --git a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c
index 8d7dfd26c..ecdc65cd4 100644
--- a/drivers/scsi/qlogicfc.c
+++ b/drivers/scsi/qlogicfc.c
@@ -77,7 +77,7 @@
/* Set the following to 1 to include fabric support, fabric support is
* currently not as well tested as the other aspects of the driver */
-#define ISP2x00_FABRIC 0
+#define ISP2x00_FABRIC 1
/* Macros used for debugging */
/*
@@ -649,11 +649,11 @@ struct isp2x00_hostdata {
/* this is here so the queues are nicely aligned */
long send_marker; /* do we need to send a marker? */
- char res[RES_QUEUE_LEN + 1][QUEUE_ENTRY_LEN];
- char req[QLOGICFC_REQ_QUEUE_LEN + 1][QUEUE_ENTRY_LEN];
+ char * res;
+ char * req;
struct init_cb control_block;
int adapter_state;
- unsigned long int tag_ages[126];
+ unsigned long int tag_ages[QLOGICFC_MAX_ID + 1];
Scsi_Cmnd *handle_ptrs[QLOGICFC_REQ_QUEUE_LEN + 1];
unsigned long handle_serials[QLOGICFC_REQ_QUEUE_LEN + 1];
struct id_name_map port_db[QLOGICFC_MAX_ID + 1];
@@ -662,6 +662,7 @@ struct isp2x00_hostdata {
u_int port_id;
u_char queued;
u_char host_id;
+ struct timer_list explore_timer;
};
@@ -676,7 +677,7 @@ static void isp2x00_disable_irqs(struct Scsi_Host *);
static int isp2x00_init(struct Scsi_Host *);
static int isp2x00_reset_hardware(struct Scsi_Host *);
static int isp2x00_mbox_command(struct Scsi_Host *, u_short[]);
-static int isp2x00_return_status(struct Status_Entry *);
+static int isp2x00_return_status(Scsi_Cmnd *, struct Status_Entry *);
static void isp2x00_intr_handler(int, void *, struct pt_regs *);
static void do_isp2x00_intr_handler(int, void *, struct pt_regs *);
static int isp2x00_make_portdb(struct Scsi_Host *);
@@ -744,14 +745,27 @@ int isp2x00_detect(Scsi_Host_Template * tmpt)
memset(hostdata, 0, sizeof(struct isp2x00_hostdata));
hostdata->pci_dev = pdev;
+ hostdata->res = (char *) kmalloc((RES_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN, GFP_KERNEL);
+ if (!hostdata->res){
+ printk("qlogicfc%d : could not allocate memory for response queue.\n", hostdata->host_id);
+ scsi_unregister(host);
+ continue;
+ }
+ hostdata->req = (char *) kmalloc((QLOGICFC_REQ_QUEUE_LEN + 1)*QUEUE_ENTRY_LEN, GFP_KERNEL);
+ if (!hostdata->req){
+ printk("qlogicfc%d : could not allocate memory for request queue.\n", hostdata->host_id);
+ kfree(hostdata->res);
+ scsi_unregister(host);
+ continue;
+ }
hostdata->queued = 0;
/* set up the control block */
hostdata->control_block.version = 0x1;
- hostdata->control_block.firm_opts = 0x0108;
+ hostdata->control_block.firm_opts = 0x000e;
hostdata->control_block.max_frame_len = 2048;
- hostdata->control_block.max_iocb = 256;
- hostdata->control_block.exec_throttle = 8;
+ hostdata->control_block.max_iocb = QLOGICFC_REQ_QUEUE_LEN;
+ hostdata->control_block.exec_throttle = QLOGICFC_CMD_PER_LUN;
hostdata->control_block.retry_delay = 5;
hostdata->control_block.retry_cnt = 1;
hostdata->control_block.node_name[0] = 0x0020;
@@ -761,16 +775,18 @@ int isp2x00_detect(Scsi_Host_Template * tmpt)
hostdata->control_block.hard_addr = 0x0003;
hostdata->control_block.req_queue_len = QLOGICFC_REQ_QUEUE_LEN + 1;
hostdata->control_block.res_queue_len = RES_QUEUE_LEN + 1;
- hostdata->control_block.res_queue_addr_lo = virt_to_bus_low32(&hostdata->res);
- hostdata->control_block.res_queue_addr_high = virt_to_bus_high32(&hostdata->res);
- hostdata->control_block.req_queue_addr_lo = virt_to_bus_low32(&hostdata->req);
- hostdata->control_block.req_queue_addr_high = virt_to_bus_high32(&hostdata->req);
-
+ hostdata->control_block.res_queue_addr_lo = virt_to_bus_low32(hostdata->res);
+ hostdata->control_block.res_queue_addr_high = virt_to_bus_high32(hostdata->res);
+ hostdata->control_block.req_queue_addr_lo = virt_to_bus_low32(hostdata->req);
+ hostdata->control_block.req_queue_addr_high = virt_to_bus_high32(hostdata->req);
hostdata->adapter_state = AS_LOOP_DOWN;
+ hostdata->explore_timer.data = 1;
hostdata->host_id = hosts;
-
+
if (isp2x00_init(host) || isp2x00_reset_hardware(host)) {
+ kfree(hostdata->res);
+ kfree(hostdata->req);
scsi_unregister(host);
continue;
}
@@ -779,6 +795,8 @@ int isp2x00_detect(Scsi_Host_Template * tmpt)
if (request_irq(host->irq, do_isp2x00_intr_handler, SA_INTERRUPT | SA_SHIRQ, "qlogicfc", host)) {
printk("qlogicfc%d : interrupt %d already in use\n",
hostdata->host_id, host->irq);
+ kfree(hostdata->res);
+ kfree(hostdata->req);
scsi_unregister(host);
continue;
}
@@ -787,6 +805,8 @@ int isp2x00_detect(Scsi_Host_Template * tmpt)
"in use\n",
hostdata->host_id, host->io_port, host->io_port + 0xff);
free_irq(host->irq, host);
+ kfree(hostdata->res);
+ kfree(hostdata->req);
scsi_unregister(host);
continue;
}
@@ -803,6 +823,7 @@ int isp2x00_detect(Scsi_Host_Template * tmpt)
printk("qlogicfc%d : link is not up\n", hostdata->host_id);
}
hosts++;
+ hostdata->explore_timer.data = 0;
}
}
@@ -1078,6 +1099,9 @@ int isp2x00_release(struct Scsi_Host *host)
release_region(host->io_port, 0xff);
+ kfree(hostdata->res);
+ kfree(hostdata->req);
+
LEAVE("isp2x00_release");
return 0;
@@ -1133,7 +1157,12 @@ int isp2x00_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *))
hostdata->adapter_state = AS_LOOP_GOOD;
printk("qlogicfc%d : Port Database\n", hostdata->host_id);
for (i = 0; hostdata->port_db[i].wwn != 0; i++) {
- printk("wwn: %08x%08x scsi_id: %x loop_id: %x\n", (u_int) (hostdata->port_db[i].wwn >> 32), (u_int) hostdata->port_db[i].wwn, i, hostdata->port_db[i].loop_id);
+ printk("wwn: %08x%08x scsi_id: %x loop_id: ", (u_int) (hostdata->port_db[i].wwn >> 32), (u_int) hostdata->port_db[i].wwn, i);
+ if (hostdata->port_db[i].loop_id != hostdata->port_db[0].loop_id || i == 0)
+ printk("%x", hostdata->port_db[i].loop_id);
+ else
+ printk("Not Available");
+ printk("\n");
}
}
if (hostdata->adapter_state == AS_FIRMWARE_DEAD) {
@@ -1148,7 +1177,7 @@ int isp2x00_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *))
DEBUG(printk("qlogicfc%d : request queue depth %d\n", hostdata->host_id,
REQ_QUEUE_DEPTH(in_ptr, out_ptr)));
- cmd = (struct Command_Entry *) &hostdata->req[in_ptr][0];
+ cmd = (struct Command_Entry *) &hostdata->req[in_ptr*QUEUE_ENTRY_LEN];
in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN;
if (in_ptr == out_ptr) {
DEBUG(printk("qlogicfc%d : request queue overflow\n", hostdata->host_id));
@@ -1175,7 +1204,7 @@ int isp2x00_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *))
DEBUG(printk("qlogicfc%d : request queue overflow\n", hostdata->host_id));
return 1;
}
- cmd = (struct Command_Entry *) &hostdata->req[in_ptr][0];
+ cmd = (struct Command_Entry *) &hostdata->req[in_ptr*QUEUE_ENTRY_LEN];
in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN;
}
TRACE("queue command", in_ptr, Cmnd);
@@ -1197,6 +1226,7 @@ int isp2x00_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *))
printk("slot %d has %p\n", i, hostdata->handle_ptrs[i]);
}
}
+ return 1;
}
cmd->hdr.entry_type = ENTRY_COMMAND;
@@ -1234,7 +1264,7 @@ int isp2x00_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *))
while (sg_count > 0) {
++cmd->hdr.entry_cnt;
cont = (struct Continuation_Entry *)
- &hostdata->req[in_ptr][0];
+ &hostdata->req[in_ptr*QUEUE_ENTRY_LEN];
memset(cont, 0, sizeof(struct Continuation_Entry));
in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN;
if (in_ptr == out_ptr) {
@@ -1280,8 +1310,9 @@ int isp2x00_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *))
/* scsi.c expects sense info in a different buffer */
cmd->dataseg[0].d_base = virt_to_bus_low32(Cmnd->sense_buffer);
#if BITS_PER_LONG > 32
- cmd->dataseg[0].d_base_hi = virt_to_bus_high32(Cmnd->request_buffer);
+ cmd->dataseg[0].d_base_hi = virt_to_bus_high32(Cmnd->sense_buffer);
#endif
+ cmd->dataseg[0].d_count = sizeof(Cmnd->sense_buffer);
cmd->segment_cnt = 1;
cmd->control_flags = CFLAG_READ;
break;
@@ -1333,8 +1364,57 @@ int isp2x00_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *))
}
-#define ASYNC_EVENT_INTERRUPT 0x01
+/* we have received an event, such as a lip or an RSCN, which may mean that
+ * our port database is incorrect so the port database must be recreated.
+ */
+static void redo_port_db(unsigned long arg)
+{
+
+ struct Scsi_Host * host = (struct Scsi_Host *) arg;
+ struct isp2x00_hostdata * hostdata;
+ unsigned long flags;
+ int i;
+
+ hostdata = (struct isp2x00_hostdata *) host->hostdata;
+ hostdata->explore_timer.data = 0;
+ del_timer(&hostdata->explore_timer);
+
+ spin_lock_irqsave(&io_request_lock, flags);
+ if (hostdata->adapter_state & AS_REDO_FABRIC_PORTDB || hostdata->adapter_state & AS_REDO_LOOP_PORTDB) {
+ isp2x00_make_portdb(host);
+ printk("qlogicfc%d : Port Database\n", hostdata->host_id);
+ for (i = 0; hostdata->port_db[i].wwn != 0; i++) {
+ printk("wwn: %08x%08x scsi_id: %x loop_id: ", (u_int) (hostdata->port_db[i].wwn >> 32), (u_int) hostdata->port_db[i].wwn, i);
+ if (hostdata->port_db[i].loop_id != hostdata->port_db[0].loop_id || i == 0)
+ printk("%x", hostdata->port_db[i].loop_id);
+ else
+ printk("Not Available");
+ printk("\n");
+ }
+
+ for (i = 0; i < QLOGICFC_REQ_QUEUE_LEN; i++){
+ if (hostdata->handle_ptrs[i] && (hostdata->port_db[hostdata->handle_ptrs[i]->target].loop_id > QLOGICFC_MAX_LOOP_ID || hostdata->adapter_state & AS_REDO_LOOP_PORTDB)){
+ if (hostdata->port_db[hostdata->handle_ptrs[i]->target].loop_id != hostdata->port_db[0].loop_id){
+ hostdata->handle_ptrs[i]->result = DID_SOFT_ERROR << 16;
+ if (hostdata->handle_ptrs[i]->scsi_done){
+ (*hostdata->handle_ptrs[i]->scsi_done) (hostdata->handle_ptrs[i]);
+ }
+ else printk("qlogicfc%d : done is null?\n", hostdata->host_id);
+ hostdata->handle_ptrs[i] = NULL;
+ hostdata->handle_serials[i] = 0;
+ }
+ }
+ }
+
+ hostdata->adapter_state = AS_LOOP_GOOD;
+ }
+
+ spin_unlock_irqrestore(&io_request_lock, flags);
+
+}
+
+#define ASYNC_EVENT_INTERRUPT 0x01
void do_isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
{
@@ -1377,23 +1457,24 @@ void isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
switch (status) {
case LOOP_UP:
case POINT_TO_POINT_UP:
- printk("qlogicfc%d : link is up\n", hostdata->host_id);
+ printk("qlogicfc%d : Link is Up\n", hostdata->host_id);
hostdata->adapter_state = AS_REDO_FABRIC_PORTDB | AS_REDO_LOOP_PORTDB;
break;
case LOOP_DOWN:
- printk("qlogicfc%d : link is down\n", hostdata->host_id);
+ printk("qlogicfc%d : Link is Down\n", hostdata->host_id);
hostdata->adapter_state = AS_LOOP_DOWN;
break;
case CONNECTION_MODE:
printk("received CONNECTION_MODE irq %x\n", inw(host->io_port + MBOX1));
break;
case CHANGE_NOTIFICATION:
+ printk("qlogicfc%d : RSCN Received\n", hostdata->host_id);
if (hostdata->adapter_state == AS_LOOP_GOOD)
hostdata->adapter_state = AS_REDO_FABRIC_PORTDB;
break;
case LIP_OCCURED:
- case PORT_DB_CHANGED:
case LIP_RECEIVED:
+ printk("qlogicfc%d : Loop Reinitialized\n", hostdata->host_id);
if (hostdata->adapter_state == AS_LOOP_GOOD)
hostdata->adapter_state = AS_REDO_LOOP_PORTDB;
break;
@@ -1428,22 +1509,27 @@ void isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
default:
printk("qlogicfc%d : got an unknown status? %x\n", hostdata->host_id, status);
}
+ if ((hostdata->adapter_state & AS_REDO_LOOP_PORTDB || hostdata->adapter_state & AS_REDO_FABRIC_PORTDB) && hostdata->explore_timer.data == 0){
+ hostdata->explore_timer.function = redo_port_db;
+ hostdata->explore_timer.data = (unsigned long)host;
+ hostdata->explore_timer.expires = jiffies + (HZ/4);
+ init_timer(&hostdata->explore_timer);
+ add_timer(&hostdata->explore_timer);
+ }
outw(0x0, host->io_port + PCI_SEMAPHORE);
} else {
DEBUG_INTR(printk("qlogicfc%d : response queue update\n", hostdata->host_id));
DEBUG_INTR(printk("qlogicfc%d : response queue depth %d\n", hostdata->host_id, RES_QUEUE_DEPTH(in_ptr, out_ptr)));
while (out_ptr != in_ptr) {
- sts = (struct Status_Entry *) &hostdata->res[out_ptr][0];
+ sts = (struct Status_Entry *) &hostdata->res[out_ptr*QUEUE_ENTRY_LEN];
out_ptr = (out_ptr + 1) & RES_QUEUE_LEN;
TRACE("done", out_ptr, Cmnd);
DEBUG_INTR(isp2x00_print_status_entry(sts));
if (sts->hdr.entry_type == ENTRY_STATUS && (Cmnd = hostdata->handle_ptrs[sts->handle])) {
- Cmnd->result = isp2x00_return_status(sts);
- hostdata->handle_ptrs[sts->handle] = NULL;
+ Cmnd->result = isp2x00_return_status(Cmnd, sts);
hostdata->queued--;
-
/*
* if any of the following are true we do not
* call scsi_done. if the status is CS_ABORTED
@@ -1453,6 +1539,7 @@ void isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
if (hostdata->handle_serials[sts->handle] != Cmnd->serial_number
|| sts->completion_status == CS_ABORTED){
hostdata->handle_serials[sts->handle] = 0;
+ hostdata->handle_ptrs[sts->handle] = NULL;
outw(out_ptr, host->io_port + MBOX5);
continue;
}
@@ -1473,6 +1560,8 @@ void isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
continue;
}
+ hostdata->handle_ptrs[sts->handle] = NULL;
+
if (sts->completion_status == CS_RESET_OCCURRED
|| (sts->status_flags & STF_BUS_RESET))
hostdata->send_marker = 1;
@@ -1514,7 +1603,7 @@ void isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
}
-static int isp2x00_return_status(struct Status_Entry *sts)
+static int isp2x00_return_status(Scsi_Cmnd *Cmnd, struct Status_Entry *sts)
{
int host_status = DID_ERROR;
#if DEBUG_ISP2x00_INTR
@@ -1558,7 +1647,10 @@ static int isp2x00_return_status(struct Status_Entry *sts)
host_status = DID_ERROR;
break;
case CS_DATA_UNDERRUN:
- host_status = DID_OK;
+ if (Cmnd->underflow <= (Cmnd->request_bufflen - sts->residual))
+ host_status = DID_OK;
+ else
+ host_status = DID_ERROR;
break;
case CS_PORT_UNAVAILABLE:
case CS_PORT_LOGGED_OUT:
@@ -1848,7 +1940,7 @@ static int isp2x00_get_nvram_defaults(struct Scsi_Host *host, struct init_cb *co
static int isp2x00_init(struct Scsi_Host *sh)
{
- u_int io_base;
+ u_long io_base;
struct isp2x00_hostdata *hostdata;
u_char revision;
u_int irq;
diff --git a/drivers/scsi/qlogicfc_asm.c b/drivers/scsi/qlogicfc_asm.c
index 931702745..deb330167 100644
--- a/drivers/scsi/qlogicfc_asm.c
+++ b/drivers/scsi/qlogicfc_asm.c
@@ -1,7464 +1,7804 @@
-
+/************************************************************************
+ * *
+ * --- ISP2100 Fabric Initiator/Target Firmware --- *
+ * with expanded LUN addressing. *
+ * *
+ ************************************************************************
+ * Copyright (C) 1999 Qlogic, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted provided
+ * that the following conditions are met:
+ * 1. Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistribution 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 name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
+ * *
+ ************************************************************************
+ */
/*
- * Firmware Version 1.15.37 (15:37 May 03, 1999)
+ * W W A RRRR N N IIIII N N GGG
+ * W W A A R R N N I N N G G
+ * W W A A R R NN N I NN N G
+ * W W W AAAAA RRR N N N I N N N G GG
+ * W W W A A R R N NN I N NN G G
+ * W W W W A A R R N N I N N G G
+ * W W A A R R N N IIIII N N GGGG
+ *
+ * This version of firmware is a release candidate,
+ * design verification testing (DVT) has not been completed.
+ */
+/*
+ * Firmware Version 1.17.30 (14:05 Sep 30, 1999)
*/
unsigned short risc_code_addr01 = 0x1000 ;
-unsigned short risc_code_length2100 = 0x66e6;
-unsigned short risc_code_length2200 = 0x81bd;
+unsigned short risc_code_length2100 = 0x77a0;
+unsigned short risc_code_length2200 = 0x7a68;
-unsigned short risc_code2100[] = {
- 0x0078, 0x1029, 0x0000, 0x66e6, 0x0000, 0x2043, 0x4f50, 0x5952,
- 0x4947, 0x4854, 0x2031, 0x3939, 0x3620, 0x514c, 0x4f47, 0x4943,
+unsigned short risc_code2100[] = {
+ 0x0078, 0x1029, 0x0000, 0x77a0, 0x0000, 0x2043, 0x4f50, 0x5952,
+ 0x4947, 0x4854, 0x2031, 0x3939, 0x3920, 0x514c, 0x4f47, 0x4943,
0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
0x3231, 0x3030, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056,
- 0x6572, 0x7369, 0x6f6e, 0x2030, 0x312e, 0x3135, 0x2020, 0x2020,
- 0x2400, 0x20c1, 0x0021, 0x20a1, 0x76e6, 0x2009, 0x0000, 0x20a9,
- 0x071a, 0x41a4, 0x3400, 0x20c9, 0x7bff, 0x2091, 0x2000, 0x2059,
- 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x209a, 0x2051, 0x7700,
- 0x2a70, 0x705b, 0x9600, 0x705f, 0xffff, 0x7057, 0x95f9, 0x7063,
- 0x0300, 0x1078, 0x127a, 0x20a1, 0x7e00, 0x715c, 0x810d, 0x810d,
- 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0007, 0xa112, 0xa00e,
- 0x21a8, 0x41a4, 0x3400, 0x8211, 0x00c0, 0x1058, 0x715c, 0x3400,
- 0xa102, 0x0040, 0x1068, 0x0048, 0x1068, 0x20a8, 0xa00e, 0x41a4,
- 0x1078, 0x1241, 0x1078, 0x1366, 0x1078, 0x14eb, 0x1078, 0x19c0,
- 0x1078, 0x362b, 0x1078, 0x5cac, 0x1078, 0x12f1, 0x1078, 0x2429,
- 0x1078, 0x3d6e, 0x1078, 0x3b46, 0x1078, 0x45af, 0x1078, 0x1e55,
- 0x1078, 0x47ef, 0x1078, 0x428f, 0x1078, 0x1d74, 0x1078, 0x1e34,
- 0x2091, 0x3009, 0x7823, 0x0000, 0x0090, 0x109d, 0x7820, 0xa086,
- 0x0002, 0x00c0, 0x109d, 0x7823, 0x4000, 0x0068, 0x1095, 0x781b,
- 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000,
- 0x2001, 0x017f, 0x2003, 0x0000, 0x2a70, 0x7000, 0xa08e, 0x0003,
- 0x00c0, 0x10bd, 0x1078, 0x2d9c, 0x1078, 0x2451, 0x1078, 0x3dbe,
- 0x1078, 0x3c31, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048,
- 0x10c1, 0x1078, 0x45c7, 0x0078, 0x10a4, 0x1079, 0x10c5, 0x0078,
- 0x10aa, 0x1078, 0x597e, 0x0078, 0x10b9, 0x10cf, 0x10d0, 0x1143,
- 0x10cd, 0x11be, 0x123e, 0x123f, 0x1240, 0x1078, 0x12cd, 0x007c,
- 0x127e, 0x0f7e, 0x2091, 0x8000, 0x1078, 0x2ec1, 0x2079, 0x0100,
- 0x7844, 0xa005, 0x00c0, 0x1134, 0x2011, 0x3558, 0x1078, 0x4689,
- 0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011, 0x8010,
- 0x73b8, 0x1078, 0x2d59, 0x1078, 0x57c9, 0x2011, 0x0004, 0x1078,
- 0x6a6d, 0x1078, 0x3ae0, 0x70c7, 0x0000, 0x70c3, 0x0000, 0x1078,
- 0x1137, 0x72bc, 0x2079, 0x7751, 0x7804, 0xd0ac, 0x0040, 0x1101,
- 0xc295, 0x72be, 0xa296, 0x0004, 0x0040, 0x1122, 0x2011, 0x0001,
- 0x1078, 0x6a6d, 0x708b, 0x0000, 0x708f, 0xffff, 0x7003, 0x0002,
- 0x0f7f, 0x1078, 0x214a, 0x2011, 0x0005, 0x1078, 0x58d8, 0x1078,
- 0x4d96, 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f, 0x127f,
- 0x0078, 0x1136, 0x708b, 0x0000, 0x708f, 0xffff, 0x7003, 0x0002,
- 0x2011, 0x0005, 0x1078, 0x58d8, 0x1078, 0x4d96, 0x0c7e, 0x2061,
- 0x0100, 0x60e3, 0x0008, 0x0c7f, 0x0f7f, 0x127f, 0x007c, 0x0c7e,
- 0x20a9, 0x0082, 0x2009, 0x007e, 0x1078, 0x3834, 0x8108, 0x00f0,
- 0x113c, 0x0c7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x708c, 0xa086,
- 0xffff, 0x0040, 0x1151, 0x1078, 0x214a, 0x1078, 0x4d96, 0x0078,
- 0x11bc, 0x70bc, 0xd09c, 0x0040, 0x1179, 0xd084, 0x0040, 0x1179,
- 0x0f7e, 0x2079, 0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c,
- 0x0040, 0x1179, 0x70c0, 0xa086, 0xffff, 0x0040, 0x1175, 0x1078,
- 0x223f, 0x1078, 0x4d96, 0x2011, 0x0001, 0x2019, 0x0000, 0x1078,
- 0x2277, 0x1078, 0x4d96, 0x0078, 0x11bc, 0x70c4, 0xa005, 0x00c0,
- 0x11bc, 0x7088, 0xa005, 0x00c0, 0x11bc, 0x2001, 0x7752, 0x2004,
- 0xd0ac, 0x0040, 0x119f, 0x157e, 0x0c7e, 0x20a9, 0x007f, 0x2009,
- 0x0000, 0x017e, 0x1078, 0x384c, 0x00c0, 0x1192, 0x6000, 0xd0ec,
- 0x00c0, 0x119a, 0x017f, 0x8108, 0x00f0, 0x1189, 0x0c7f, 0x157f,
- 0x0078, 0x119f, 0x017f, 0x0c7f, 0x157f, 0x0078, 0x11bc, 0x7003,
- 0x0003, 0x708f, 0xffff, 0x2001, 0x0000, 0x1078, 0x2025, 0x1078,
- 0x2dd7, 0x2001, 0x7937, 0x2004, 0xa086, 0x0005, 0x00c0, 0x11b4,
- 0x2011, 0x0000, 0x1078, 0x58d8, 0x2011, 0x0000, 0x1078, 0x58e2,
- 0x1078, 0x4d96, 0x1078, 0x4e56, 0x127f, 0x007c, 0x017e, 0x0f7e,
- 0x127e, 0x2091, 0x8000, 0x2079, 0x0100, 0x7940, 0xa18c, 0x0010,
- 0x7942, 0x7924, 0xd1b4, 0x0040, 0x11cf, 0x7827, 0x0040, 0xd19c,
- 0x0040, 0x11d4, 0x7827, 0x0008, 0x007e, 0x037e, 0x157e, 0x7900,
- 0xa18a, 0x0003, 0x0050, 0x11fa, 0x7954, 0xd1ac, 0x00c0, 0x11fa,
- 0x2009, 0x00f8, 0x1078, 0x35fa, 0x7843, 0x0090, 0x7843, 0x0010,
- 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x00c0, 0x11f2, 0x7824, 0xd0ac,
- 0x00c0, 0x122e, 0x00f0, 0x11ea, 0x2001, 0x0001, 0x1078, 0x2025,
- 0x0078, 0x1237, 0x7853, 0x0000, 0x782f, 0x0020, 0x20a9, 0x0008,
- 0x00e0, 0x1200, 0x2091, 0x6000, 0x00f0, 0x1200, 0x7853, 0x0400,
- 0x782f, 0x0000, 0x2009, 0x00f8, 0x1078, 0x35fa, 0x20a9, 0x000e,
- 0x0005, 0x00f0, 0x1210, 0x7853, 0x1400, 0x7843, 0x0090, 0x7843,
- 0x0010, 0x2019, 0x61a8, 0x7854, 0x0005, 0x0005, 0xd08c, 0x0040,
- 0x1225, 0x7824, 0xd0ac, 0x00c0, 0x122e, 0x8319, 0x00c0, 0x121b,
- 0x2001, 0x0001, 0x1078, 0x2025, 0x0078, 0x1235, 0x7828, 0xc09d,
- 0x782a, 0x7827, 0x0008, 0x7827, 0x0040, 0x7853, 0x0400, 0x157f,
- 0x037f, 0x007f, 0x127f, 0x0f7f, 0x017f, 0x007c, 0x007c, 0x007c,
- 0x007c, 0x2a70, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048,
- 0x124d, 0x704f, 0xffff, 0x0078, 0x124f, 0x704f, 0x0000, 0x7053,
- 0xffff, 0x7067, 0x0000, 0x706b, 0x0000, 0x2061, 0x7920, 0x6003,
- 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013,
- 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0, 0x2061,
- 0x7928, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, 0x0000, 0x600f,
- 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, 0x601f,
- 0x0000, 0x007c, 0x1078, 0x12a0, 0x2011, 0x0000, 0x81ff, 0x0040,
- 0x129f, 0xa186, 0x0001, 0x00c0, 0x128f, 0x705f, 0x8fff, 0x7057,
- 0x8601, 0x7063, 0x0100, 0x705b, 0x8600, 0x0078, 0x129d, 0xa186,
- 0x0002, 0x00c0, 0x1297, 0x2011, 0x0000, 0x0078, 0x129d, 0xa186,
- 0x0005, 0x00c0, 0x129d, 0x2011, 0x0001, 0x1078, 0x12c7, 0x007c,
- 0x2009, 0x0000, 0x2011, 0x0000, 0x1078, 0x12c7, 0x2019, 0xaaaa,
- 0x2061, 0xffff, 0x2362, 0x2c24, 0x2061, 0x7fff, 0x2c04, 0xa406,
- 0x0040, 0x12b5, 0xc18d, 0x0078, 0x12c2, 0xc185, 0x2011, 0x0001,
- 0x1078, 0x12c7, 0x2061, 0xffff, 0x2362, 0x2c04, 0xa306, 0x00c0,
- 0x12c2, 0xc195, 0x2011, 0x0001, 0x1078, 0x12c7, 0x007c, 0x3800,
- 0xa084, 0xfffc, 0xa205, 0x20c0, 0x007c, 0x2091, 0x8000, 0x0068,
- 0x12cf, 0x007e, 0x017e, 0x2079, 0x0000, 0x7818, 0xa084, 0x0000,
- 0x00c0, 0x12d5, 0x017f, 0x792e, 0x007f, 0x782a, 0x007f, 0x7826,
- 0x3900, 0x783a, 0x7823, 0x8002, 0x781b, 0x0001, 0x2091, 0x5000,
- 0x2091, 0x4080, 0x2079, 0x7700, 0x7803, 0x0005, 0x0078, 0x12ee,
- 0x007c, 0x2071, 0x7700, 0x7158, 0x712e, 0x2021, 0x0001, 0xa190,
- 0x002d, 0xa298, 0x002d, 0x0048, 0x1307, 0x705c, 0xa302, 0x00c8,
- 0x1307, 0x220a, 0x2208, 0x2310, 0x8420, 0x0078, 0x12f9, 0x200b,
- 0x0000, 0x749e, 0x74a2, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000,
- 0x2071, 0x7700, 0x70a0, 0xa0ea, 0x0010, 0x00c8, 0x131a, 0xa06e,
- 0x0078, 0x1324, 0x8001, 0x70a2, 0x702c, 0x2068, 0x2d04, 0x702e,
- 0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f, 0x007c, 0x0e7e,
- 0x2071, 0x7700, 0x127e, 0x2091, 0x8000, 0x70a0, 0x8001, 0x00c8,
- 0x1334, 0xa06e, 0x0078, 0x133d, 0x70a2, 0x702c, 0x2068, 0x2d04,
- 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f, 0x007c,
- 0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0x7700, 0x702c, 0x206a,
- 0x2d00, 0x702e, 0x70a0, 0x8000, 0x70a2, 0x127f, 0x0e7f, 0x007c,
- 0x8dff, 0x0040, 0x135c, 0x6804, 0x6807, 0x0000, 0x007e, 0x1078,
- 0x1340, 0x0d7f, 0x0078, 0x1350, 0x007c, 0x0e7e, 0x2071, 0x7700,
- 0x70a0, 0xa08a, 0x0010, 0xa00d, 0x0e7f, 0x007c, 0x0e7e, 0x2071,
- 0x7959, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000, 0x2071,
- 0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x0e7f, 0x007c, 0x0e7e,
- 0x2270, 0x700b, 0x0000, 0x2071, 0x7959, 0x7018, 0xa088, 0x7962,
- 0x220a, 0x8000, 0xa084, 0x0007, 0x701a, 0x7004, 0xa005, 0x00c0,
- 0x138f, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13a0, 0x0f7f, 0x0e7f,
- 0x007c, 0x0e7e, 0x2071, 0x7959, 0x7004, 0xa005, 0x00c0, 0x139e,
- 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13a0, 0x0f7f, 0x0e7f, 0x007c,
- 0x7000, 0x0079, 0x13a3, 0x13a7, 0x1411, 0x142e, 0x142e, 0x7018,
- 0x711c, 0xa106, 0x00c0, 0x13af, 0x7007, 0x0000, 0x007c, 0x0d7e,
- 0xa180, 0x7962, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007,
- 0x711e, 0x7803, 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c,
- 0x783a, 0x6830, 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804,
- 0x0d7f, 0xd084, 0x0040, 0x13d1, 0x7007, 0x0001, 0x1078, 0x13d6,
- 0x007c, 0x7007, 0x0002, 0x1078, 0x13ec, 0x007c, 0x017e, 0x027e,
- 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x13e1, 0x2110,
- 0xa006, 0x700e, 0x7212, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803,
- 0x0041, 0x027f, 0x017f, 0x007c, 0x017e, 0x027e, 0x137e, 0x147e,
- 0x157e, 0x7014, 0x2098, 0x20a1, 0x0014, 0x7803, 0x0026, 0x710c,
- 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x1400, 0x2110, 0xa006,
- 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803,
- 0x0001, 0x3300, 0x7016, 0x157f, 0x147f, 0x137f, 0x027f, 0x017f,
- 0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0x77e5, 0x20a1, 0x0018,
- 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000,
- 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x700b,
- 0x77e0, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x137e, 0x147e,
- 0x157e, 0x2001, 0x7814, 0x209c, 0x20a1, 0x0014, 0x7803, 0x0026,
- 0x2001, 0x7815, 0x20ac, 0x53a6, 0x2099, 0x7816, 0x20a1, 0x0018,
- 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000,
- 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c, 0x7002, 0x700b,
- 0x7811, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x017e, 0x0e7e,
- 0x2071, 0x7959, 0x0f7e, 0x2079, 0x0010, 0x7904, 0x7803, 0x0002,
- 0xd1fc, 0x0040, 0x1471, 0xa18c, 0x0700, 0x0040, 0x146e, 0x7008,
- 0xa080, 0x0002, 0x2003, 0x0200, 0x0078, 0x1471, 0x7004, 0x1079,
- 0x1475, 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x13a0, 0x147d, 0x149f,
- 0x14b9, 0x14e2, 0x147b, 0x0078, 0x147b, 0x137e, 0x147e, 0x157e,
- 0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010, 0x20a8,
- 0x53a5, 0x3400, 0x7016, 0x157f, 0x147f, 0x137f, 0x700c, 0xa005,
- 0x0040, 0x14a6, 0x1078, 0x13d6, 0x007c, 0x7008, 0xa080, 0x0002,
- 0x2003, 0x0100, 0x7007, 0x0000, 0x1078, 0x13a0, 0x007c, 0x700c,
- 0xa005, 0x0040, 0x14a6, 0x1078, 0x13ec, 0x007c, 0x0d7e, 0x7008,
- 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, 0x682e, 0x783c,
- 0x6832, 0x680b, 0x0100, 0x0d7f, 0x7007, 0x0000, 0x1078, 0x13a0,
- 0x007c, 0x137e, 0x147e, 0x157e, 0x2001, 0x77e3, 0x2004, 0xa080,
+ 0x6572, 0x7369, 0x6f6e, 0x2030, 0x312e, 0x3137, 0x2020, 0x2020,
+ 0x2400, 0x2091, 0x2000, 0x20c1, 0x0021, 0x2039, 0xffff, 0x2019,
+ 0xaaaa, 0x2760, 0x2069, 0x7fff, 0x20c1, 0x0020, 0x2c2c, 0x2d34,
+ 0x2762, 0x236a, 0x2c24, 0x2d04, 0x266a, 0x2562, 0xa406, 0x00c0,
+ 0x104e, 0x20c1, 0x0021, 0x2c2c, 0x2362, 0x2c04, 0x2562, 0xa306,
+ 0x0040, 0x104e, 0x20c1, 0x0020, 0x2039, 0x8fff, 0x20a1, 0x8f00,
+ 0x2708, 0x810d, 0x810d, 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001,
+ 0x0008, 0xa112, 0xa00e, 0x21a8, 0x41a4, 0x3400, 0x8211, 0x00c0,
+ 0x105b, 0x2708, 0x3400, 0xa102, 0x0040, 0x106b, 0x0048, 0x106b,
+ 0x20a8, 0xa00e, 0x41a4, 0x20a1, 0x87a0, 0x2009, 0x0000, 0x20a9,
+ 0x0760, 0x41a4, 0x3400, 0x20c9, 0x8cff, 0x2059, 0x0000, 0x2b78,
+ 0x7823, 0x0004, 0x2089, 0x226f, 0x2051, 0x8800, 0x2a70, 0x775e,
+ 0xa786, 0x8fff, 0x0040, 0x108e, 0x705b, 0xa700, 0x7057, 0xa6f5,
+ 0x7063, 0x0200, 0x7067, 0x0200, 0x0078, 0x1096, 0x7057, 0x9b01,
+ 0x7063, 0x0100, 0x7067, 0x0100, 0x705b, 0x9b00, 0x1078, 0x128f,
+ 0x1078, 0x136a, 0x1078, 0x1513, 0x1078, 0x1b00, 0x1078, 0x3d25,
+ 0x1078, 0x68a0, 0x1078, 0x12f5, 0x1078, 0x26b2, 0x1078, 0x4778,
+ 0x1078, 0x42aa, 0x1078, 0x5004, 0x1078, 0x1fc3, 0x1078, 0x5260,
+ 0x1078, 0x4cb7, 0x1078, 0x1ee5, 0x1078, 0x1fa0, 0x2091, 0x3009,
+ 0x7823, 0x0000, 0x0090, 0x10cb, 0x7820, 0xa086, 0x0002, 0x00c0,
+ 0x10cb, 0x7823, 0x4000, 0x0068, 0x10c3, 0x781b, 0x0001, 0x2091,
+ 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000, 0x2001, 0x017f,
+ 0x2003, 0x0000, 0x2a70, 0x7000, 0xa08e, 0x0003, 0x00c0, 0x10eb,
+ 0x1078, 0x31bd, 0x1078, 0x26da, 0x1078, 0x47c8, 0x1078, 0x4469,
+ 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048, 0x10ef, 0x1078,
+ 0x5020, 0x0078, 0x10d2, 0x1079, 0x10f3, 0x0078, 0x10d8, 0x1078,
+ 0x6565, 0x0078, 0x10e7, 0x10fd, 0x10fe, 0x1189, 0x10fb, 0x1208,
+ 0x128c, 0x128d, 0x128e, 0x1078, 0x12d2, 0x007c, 0x127e, 0x0f7e,
+ 0x2091, 0x8000, 0x1078, 0x3541, 0x2079, 0x0100, 0x7844, 0xa005,
+ 0x00c0, 0x117a, 0x2011, 0x3c35, 0x1078, 0x50f2, 0x780f, 0x00ff,
+ 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011, 0x8010, 0x73bc, 0x1078,
+ 0x317a, 0x7238, 0xc284, 0x723a, 0x2001, 0x880c, 0x2014, 0xc2ac,
+ 0x2202, 0x1078, 0x6376, 0x2011, 0x0004, 0x1078, 0x7802, 0x1078,
+ 0x4236, 0x1078, 0x3d0d, 0x0040, 0x1135, 0x7083, 0x0001, 0x70b7,
+ 0x0000, 0x1078, 0x36ef, 0x0078, 0x117a, 0x70cb, 0x0000, 0x70c7,
+ 0x0000, 0x706b, 0x0000, 0x706f, 0x0000, 0x1078, 0x117d, 0x72c0,
+ 0x2079, 0x8851, 0x7804, 0xd0ac, 0x0040, 0x1147, 0xc295, 0x72c2,
+ 0xa296, 0x0004, 0x0040, 0x1168, 0x2011, 0x0001, 0x1078, 0x7802,
+ 0x708f, 0x0000, 0x7093, 0xffff, 0x7003, 0x0002, 0x0f7f, 0x1078,
+ 0x231f, 0x2011, 0x0005, 0x1078, 0x64ae, 0x1078, 0x5888, 0x0c7e,
+ 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f, 0x127f, 0x0078, 0x117c,
+ 0x708f, 0x0000, 0x7093, 0xffff, 0x7003, 0x0002, 0x2011, 0x0005,
+ 0x1078, 0x64ae, 0x1078, 0x5888, 0x0c7e, 0x2061, 0x0100, 0x60e3,
+ 0x0008, 0x0c7f, 0x0f7f, 0x127f, 0x007c, 0x0c7e, 0x20a9, 0x0082,
+ 0x2009, 0x007e, 0x1078, 0x3f76, 0x8108, 0x00f0, 0x1182, 0x0c7f,
+ 0x007c, 0x127e, 0x2091, 0x8000, 0x7090, 0xa086, 0xffff, 0x0040,
+ 0x1197, 0x1078, 0x231f, 0x1078, 0x5888, 0x0078, 0x1206, 0x70c0,
+ 0xd09c, 0x0040, 0x11c3, 0xd084, 0x0040, 0x11c3, 0x0f7e, 0x2079,
+ 0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c, 0x0040, 0x11c3,
+ 0x70c4, 0xa086, 0xffff, 0x0040, 0x11bf, 0x1078, 0x2449, 0x1078,
+ 0x5888, 0x70c0, 0xd094, 0x00c0, 0x1206, 0x2011, 0x0001, 0x2019,
+ 0x0000, 0x1078, 0x2481, 0x1078, 0x5888, 0x0078, 0x1206, 0x70c8,
+ 0xa005, 0x00c0, 0x1206, 0x708c, 0xa005, 0x00c0, 0x1206, 0x2001,
+ 0x8852, 0x2004, 0xd0ac, 0x0040, 0x11e9, 0x157e, 0x0c7e, 0x20a9,
+ 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x3f8e, 0x00c0, 0x11dc,
+ 0x6000, 0xd0ec, 0x00c0, 0x11e4, 0x017f, 0x8108, 0x00f0, 0x11d3,
+ 0x0c7f, 0x157f, 0x0078, 0x11e9, 0x017f, 0x0c7f, 0x157f, 0x0078,
+ 0x1206, 0x7003, 0x0003, 0x7093, 0xffff, 0x2001, 0x0000, 0x1078,
+ 0x21f3, 0x1078, 0x31f8, 0x2001, 0x8aa3, 0x2004, 0xa086, 0x0005,
+ 0x00c0, 0x11fe, 0x2011, 0x0000, 0x1078, 0x64ae, 0x2011, 0x0000,
+ 0x1078, 0x64b8, 0x1078, 0x5888, 0x1078, 0x5948, 0x127f, 0x007c,
+ 0x017e, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, 0x0100, 0x2009,
+ 0x00f7, 0x1078, 0x3cdc, 0x7940, 0xa18c, 0x0010, 0x7942, 0x7924,
+ 0xd1b4, 0x0040, 0x121d, 0x7827, 0x0040, 0xd19c, 0x0040, 0x1222,
+ 0x7827, 0x0008, 0x007e, 0x037e, 0x157e, 0x7900, 0xa18a, 0x0003,
+ 0x0050, 0x1248, 0x7954, 0xd1ac, 0x00c0, 0x1248, 0x2009, 0x00f8,
+ 0x1078, 0x3cdc, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x09c4,
+ 0x7820, 0xd09c, 0x00c0, 0x1240, 0x7824, 0xd0ac, 0x00c0, 0x127c,
+ 0x00f0, 0x1238, 0x2001, 0x0001, 0x1078, 0x21f3, 0x0078, 0x1285,
+ 0x7853, 0x0000, 0x782f, 0x0020, 0x20a9, 0x0050, 0x00e0, 0x124e,
+ 0x2091, 0x6000, 0x00f0, 0x124e, 0x7853, 0x0400, 0x782f, 0x0000,
+ 0x2009, 0x00f8, 0x1078, 0x3cdc, 0x20a9, 0x000e, 0x0005, 0x00f0,
+ 0x125e, 0x7853, 0x1400, 0x7843, 0x0090, 0x7843, 0x0010, 0x2019,
+ 0x61a8, 0x7854, 0x0005, 0x0005, 0xd08c, 0x0040, 0x1273, 0x7824,
+ 0xd0ac, 0x00c0, 0x127c, 0x8319, 0x00c0, 0x1269, 0x2001, 0x0001,
+ 0x1078, 0x21f3, 0x0078, 0x1283, 0x7828, 0xc09d, 0x782a, 0x7827,
+ 0x0008, 0x7827, 0x0040, 0x7853, 0x0400, 0x157f, 0x037f, 0x007f,
+ 0x127f, 0x0f7f, 0x017f, 0x007c, 0x007c, 0x007c, 0x007c, 0x2a70,
+ 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048, 0x129b, 0x704f,
+ 0xffff, 0x0078, 0x129d, 0x704f, 0x0000, 0x7053, 0xffff, 0x706b,
+ 0x0000, 0x706f, 0x0000, 0x2061, 0x8a8c, 0x6003, 0x0909, 0x6007,
+ 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017,
+ 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0, 0x2061, 0x8a94, 0x6003,
+ 0x8000, 0x6007, 0x0000, 0x600b, 0x0000, 0x600f, 0x0200, 0x6013,
+ 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, 0x601f, 0x0000, 0x2061,
+ 0x8a9c, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f,
+ 0x2020, 0x007c, 0x2091, 0x8000, 0x0068, 0x12d4, 0x007e, 0x017e,
+ 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x12da, 0x017f, 0x792e,
+ 0x007f, 0x782a, 0x007f, 0x7826, 0x3900, 0x783a, 0x7823, 0x8002,
+ 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2079, 0x8800,
+ 0x7803, 0x0005, 0x0078, 0x12f2, 0x007c, 0x2071, 0x8800, 0x7158,
+ 0x712e, 0x2021, 0x0001, 0xa190, 0x002d, 0xa298, 0x002d, 0x0048,
+ 0x130b, 0x705c, 0xa302, 0x00c8, 0x130b, 0x220a, 0x2208, 0x2310,
+ 0x8420, 0x0078, 0x12fd, 0x200b, 0x0000, 0x74a2, 0x74a6, 0x007c,
+ 0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0x8800, 0x70a4, 0xa0ea,
+ 0x0010, 0x00c8, 0x131e, 0xa06e, 0x0078, 0x1328, 0x8001, 0x70a6,
+ 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000,
+ 0x127f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0x8800, 0x127e, 0x2091,
+ 0x8000, 0x70a4, 0x8001, 0x00c8, 0x1338, 0xa06e, 0x0078, 0x1341,
+ 0x70a6, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807,
+ 0x0000, 0x127f, 0x0e7f, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000,
+ 0x2071, 0x8800, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70a4, 0x8000,
+ 0x70a6, 0x127f, 0x0e7f, 0x007c, 0x8dff, 0x0040, 0x1360, 0x6804,
+ 0x6807, 0x0000, 0x007e, 0x1078, 0x1344, 0x0d7f, 0x0078, 0x1354,
+ 0x007c, 0x0e7e, 0x2071, 0x8800, 0x70a4, 0xa08a, 0x0010, 0xa00d,
+ 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0x8ac7, 0x7007, 0x0000, 0x701b,
+ 0x0000, 0x701f, 0x0000, 0x2071, 0x0000, 0x7010, 0xa085, 0x8004,
+ 0x7012, 0x0e7f, 0x007c, 0x0e7e, 0x2270, 0x700b, 0x0000, 0x2071,
+ 0x8ac7, 0x7018, 0xa088, 0x8ad0, 0x220a, 0x8000, 0xa084, 0x0007,
+ 0x701a, 0x7004, 0xa005, 0x00c0, 0x1393, 0x0f7e, 0x2079, 0x0010,
+ 0x1078, 0x13a4, 0x0f7f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0x8ac7,
+ 0x7004, 0xa005, 0x00c0, 0x13a2, 0x0f7e, 0x2079, 0x0010, 0x1078,
+ 0x13a4, 0x0f7f, 0x0e7f, 0x007c, 0x7000, 0x0079, 0x13a7, 0x13ab,
+ 0x1415, 0x1432, 0x1432, 0x7018, 0x711c, 0xa106, 0x00c0, 0x13b3,
+ 0x7007, 0x0000, 0x007c, 0x0d7e, 0xa180, 0x8ad0, 0x2004, 0x700a,
+ 0x2068, 0x8108, 0xa18c, 0x0007, 0x711e, 0x7803, 0x0026, 0x6824,
+ 0x7832, 0x6828, 0x7836, 0x682c, 0x783a, 0x6830, 0x783e, 0x6810,
+ 0x700e, 0x680c, 0x7016, 0x6804, 0x0d7f, 0xd084, 0x0040, 0x13d5,
+ 0x7007, 0x0001, 0x1078, 0x13da, 0x007c, 0x7007, 0x0002, 0x1078,
+ 0x13f0, 0x007c, 0x017e, 0x027e, 0x710c, 0x2011, 0x0040, 0xa182,
+ 0x0040, 0x00c8, 0x13e5, 0x2110, 0xa006, 0x700e, 0x7212, 0x8203,
+ 0x7822, 0x7803, 0x0020, 0x7803, 0x0041, 0x027f, 0x017f, 0x007c,
+ 0x017e, 0x027e, 0x137e, 0x147e, 0x157e, 0x7014, 0x2098, 0x20a1,
+ 0x0014, 0x7803, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040,
+ 0x00c8, 0x1404, 0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203,
+ 0x7822, 0x7803, 0x0020, 0x3300, 0x7016, 0x7803, 0x0001, 0x157f,
+ 0x147f, 0x137f, 0x027f, 0x017f, 0x007c, 0x137e, 0x147e, 0x157e,
+ 0x2099, 0x88f9, 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803,
+ 0x0020, 0x127e, 0x2091, 0x8000, 0x7803, 0x0041, 0x7007, 0x0003,
+ 0x7000, 0xc084, 0x7002, 0x700b, 0x88f4, 0x127f, 0x157f, 0x147f,
+ 0x137f, 0x007c, 0x137e, 0x147e, 0x157e, 0x2001, 0x8928, 0x209c,
+ 0x20a1, 0x0014, 0x7803, 0x0026, 0x2001, 0x8929, 0x20ac, 0x53a6,
+ 0x2099, 0x892a, 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803,
+ 0x0020, 0x127e, 0x2091, 0x8000, 0x7803, 0x0001, 0x7007, 0x0004,
+ 0x7000, 0xc08c, 0x7002, 0x700b, 0x8925, 0x127f, 0x157f, 0x147f,
+ 0x137f, 0x007c, 0x017e, 0x0e7e, 0x2071, 0x8ac7, 0x0f7e, 0x2079,
+ 0x0010, 0x7904, 0x7803, 0x0002, 0xd1fc, 0x0040, 0x146c, 0xa18c,
+ 0x0700, 0x7004, 0x1079, 0x1470, 0x0f7f, 0x0e7f, 0x017f, 0x007c,
+ 0x13a4, 0x1478, 0x14a5, 0x14cd, 0x1500, 0x1476, 0x0078, 0x1476,
+ 0xa18c, 0x0700, 0x00c0, 0x149e, 0x137e, 0x147e, 0x157e, 0x7014,
+ 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010, 0x20a8, 0x53a5,
+ 0x3400, 0x7016, 0x157f, 0x147f, 0x137f, 0x700c, 0xa005, 0x0040,
+ 0x14ba, 0x1078, 0x13da, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003,
+ 0x0100, 0x7007, 0x0000, 0x1078, 0x13a4, 0x007c, 0x7008, 0xa080,
+ 0x0002, 0x2003, 0x0200, 0x0078, 0x1499, 0xa18c, 0x0700, 0x00c0,
+ 0x14b0, 0x700c, 0xa005, 0x0040, 0x14ba, 0x1078, 0x13f0, 0x007c,
+ 0x7008, 0xa080, 0x0002, 0x2003, 0x0200, 0x7007, 0x0000, 0x1078,
+ 0x13a4, 0x007c, 0x0d7e, 0x7008, 0x2068, 0x7830, 0x6826, 0x7834,
+ 0x682a, 0x7838, 0x682e, 0x783c, 0x6832, 0x680b, 0x0100, 0x0d7f,
+ 0x7007, 0x0000, 0x1078, 0x13a4, 0x007c, 0xa18c, 0x0700, 0x00c0,
+ 0x14fa, 0x137e, 0x147e, 0x157e, 0x2001, 0x88f7, 0x2004, 0xa080,
0x000d, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020,
- 0x53a5, 0x2001, 0x77e5, 0x2004, 0xd0bc, 0x0040, 0x14d8, 0x2001,
- 0x77ee, 0x2004, 0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, 0x53a5,
- 0x157f, 0x147f, 0x137f, 0x7007, 0x0000, 0x1078, 0x3e67, 0x1078,
- 0x13a0, 0x007c, 0x2001, 0x7813, 0x2003, 0x0100, 0x7007, 0x0000,
- 0x1078, 0x13a0, 0x007c, 0x127e, 0x2091, 0x2100, 0x2079, 0x0030,
- 0x2071, 0x796a, 0x7003, 0x0000, 0x700f, 0x7970, 0x7013, 0x7970,
- 0x780f, 0x0070, 0x127f, 0x007c, 0x6934, 0xa184, 0x0007, 0x0079,
- 0x1501, 0x1509, 0x154f, 0x1509, 0x1509, 0x1509, 0x1534, 0x1518,
- 0x150d, 0xa085, 0x0001, 0x0078, 0x1569, 0x684c, 0xd0bc, 0x0040,
- 0x1509, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, 0x0078, 0x1557,
- 0xa18c, 0x00ff, 0xa186, 0x001e, 0x00c0, 0x1509, 0x684c, 0xd0bc,
- 0x0040, 0x1509, 0x6860, 0x682e, 0x685c, 0x682a, 0x6804, 0x681a,
- 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004,
- 0x6832, 0x6858, 0x0078, 0x155f, 0xa18c, 0x00ff, 0xa186, 0x0015,
- 0x00c0, 0x1509, 0x684c, 0xd0ac, 0x0040, 0x1509, 0x6804, 0x681a,
- 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004,
- 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0078, 0x155f, 0x684c,
- 0xd0ac, 0x0040, 0x1509, 0xa006, 0x682e, 0x682a, 0x6858, 0xa18c,
- 0x000f, 0xa188, 0x1c7e, 0x210c, 0x6932, 0x2d08, 0x691a, 0x6826,
- 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c, 0x6912, 0x6980,
- 0x6916, 0x007c, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, 0x020a,
- 0x2004, 0x82ff, 0x0040, 0x1584, 0xa280, 0x0004, 0x0d7e, 0x206c,
- 0x684c, 0xd0dc, 0x00c0, 0x1580, 0x1078, 0x14fc, 0x10c0, 0x12cd,
- 0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e, 0x037e, 0x027e,
- 0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000, 0xa005, 0x00c0,
- 0x1598, 0x7206, 0x2001, 0x15ac, 0x007e, 0x2260, 0x0078, 0x16c4,
- 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a, 0x8108, 0xa182,
- 0x798b, 0x0048, 0x15a5, 0x2009, 0x7970, 0x710e, 0x7000, 0xa005,
- 0x00c0, 0x15ac, 0x1078, 0x16ad, 0x127f, 0x007c, 0x127e, 0x027e,
- 0x037e, 0x0c7e, 0x007e, 0x2091, 0x2100, 0x007f, 0x047f, 0x037f,
- 0x027f, 0x0d7e, 0x0c7e, 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e,
- 0xa005, 0x0040, 0x1600, 0x6808, 0xa005, 0x0040, 0x1666, 0x7000,
- 0xa005, 0x00c0, 0x15cd, 0x0078, 0x15fa, 0x700c, 0x7110, 0xa106,
- 0x00c0, 0x166a, 0x7004, 0xa406, 0x00c0, 0x15fa, 0x2001, 0x0005,
- 0x2004, 0xd08c, 0x0040, 0x15e3, 0x047e, 0x1078, 0x1785, 0x047f,
- 0x2460, 0x0078, 0x15c3, 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0,
- 0x15d6, 0x7804, 0xa084, 0x6000, 0x0040, 0x15f4, 0xa086, 0x6000,
- 0x0040, 0x15f4, 0x0078, 0x15d6, 0x7803, 0x0004, 0x7003, 0x0000,
- 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x5d41, 0x0078, 0x166a,
- 0x6808, 0xa005, 0x0040, 0x1666, 0x7000, 0xa005, 0x00c0, 0x160a,
- 0x0078, 0x1666, 0x700c, 0x7110, 0xa106, 0x00c0, 0x1613, 0x7004,
- 0xa406, 0x00c0, 0x1666, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0040,
- 0x1620, 0x047e, 0x1078, 0x1785, 0x047f, 0x2460, 0x0078, 0x1600,
- 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0, 0x1613, 0x2001, 0x0005,
- 0x2004, 0xd08c, 0x00c0, 0x1619, 0x7804, 0xa084, 0x6000, 0x0040,
- 0x1637, 0xa086, 0x6000, 0x0040, 0x1637, 0x0078, 0x1613, 0x7007,
- 0x0000, 0xa016, 0x2218, 0x7000, 0xa08e, 0x0001, 0x0040, 0x1658,
- 0xa08e, 0x0002, 0x00c0, 0x1666, 0x0c7e, 0x0e7e, 0x6818, 0x2060,
- 0x1078, 0x1c53, 0x2804, 0xac70, 0x6034, 0xd09c, 0x00c0, 0x1654,
- 0x7308, 0x720c, 0x0078, 0x1656, 0x7310, 0x7214, 0x0e7f, 0x0c7f,
- 0x7820, 0xa318, 0x7824, 0xa211, 0x6810, 0xa300, 0x6812, 0x6814,
- 0xa201, 0x6816, 0x7803, 0x0004, 0x7003, 0x0000, 0x2009, 0x0048,
- 0x1078, 0x5d41, 0x0c7f, 0x0d7f, 0x127f, 0x007c, 0x0f7e, 0x0e7e,
- 0x2071, 0x796a, 0x7000, 0xa086, 0x0000, 0x0040, 0x16aa, 0x7004,
- 0xac06, 0x00c0, 0x169b, 0x2079, 0x0030, 0x7804, 0xd0fc, 0x00c0,
- 0x1697, 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0, 0x167d, 0x7803,
- 0x0004, 0x7804, 0xd0ac, 0x00c0, 0x1689, 0x7803, 0x0002, 0x7803,
- 0x0009, 0x7003, 0x0003, 0x7007, 0x0000, 0x0078, 0x169b, 0x1078,
- 0x1785, 0x0078, 0x1672, 0x157e, 0x20a9, 0x0009, 0x2009, 0x7970,
- 0x2104, 0xac06, 0x00c0, 0x16a5, 0x200a, 0xa188, 0x0003, 0x00f0,
- 0x16a0, 0x157f, 0x0e7f, 0x0f7f, 0x007c, 0x700c, 0x7110, 0xa106,
- 0x00c0, 0x16b5, 0x7003, 0x0000, 0x007c, 0x2104, 0x7006, 0x2060,
- 0x8108, 0x211c, 0x8108, 0x2124, 0x8108, 0xa182, 0x798b, 0x0048,
- 0x16c3, 0x2009, 0x7970, 0x7112, 0x8cff, 0x00c0, 0x16cb, 0x1078,
- 0x1950, 0x0078, 0x16f2, 0x6010, 0x2068, 0x2d58, 0x6828, 0xa406,
- 0x00c0, 0x16d6, 0x682c, 0xa306, 0x0040, 0x16da, 0x1078, 0x1c9e,
- 0x00c0, 0x16c7, 0x684c, 0xd0f4, 0x00c0, 0x16c7, 0x6824, 0x2050,
- 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009,
- 0x0011, 0x1078, 0x16f3, 0x0040, 0x16f1, 0x2009, 0x0001, 0x1078,
- 0x16f3, 0x2d58, 0x007c, 0x8aff, 0x0040, 0x1780, 0xa03e, 0x2730,
- 0x6850, 0xd0fc, 0x00c0, 0x1712, 0x0d7e, 0x2804, 0xac68, 0x2900,
- 0x0079, 0x1702, 0x1762, 0x1722, 0x1722, 0x1762, 0x1762, 0x175a,
- 0x1762, 0x1722, 0x1762, 0x1728, 0x1728, 0x1762, 0x1762, 0x1762,
- 0x1751, 0x1728, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20,
- 0x0d7e, 0xd99c, 0x0040, 0x1765, 0x2804, 0xac68, 0x6f08, 0x6e0c,
- 0x0078, 0x1765, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0078, 0x1765,
- 0x7b0c, 0xd3bc, 0x0040, 0x1749, 0x7004, 0x0e7e, 0x2070, 0x701c,
- 0x0e7f, 0xa086, 0x0008, 0x00c0, 0x1749, 0x7b08, 0xa39c, 0x0fff,
- 0x2d20, 0x0d7f, 0x0d7e, 0x6a14, 0x82ff, 0x00c0, 0x1744, 0x6810,
- 0xa302, 0x0048, 0x1744, 0x6b10, 0x2011, 0x0000, 0x2468, 0x0078,
- 0x174b, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0078,
- 0x1765, 0x0d7f, 0x0d7e, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e,
- 0x00c0, 0x1762, 0x0d7f, 0x1078, 0x1c3a, 0x00c0, 0x16f3, 0xa00e,
- 0x0078, 0x1780, 0x0d7f, 0x1078, 0x12cd, 0x7b22, 0x7a26, 0x7d32,
- 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x0d7f,
- 0x6828, 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x2300, 0x6b10,
- 0xa302, 0x6812, 0x2200, 0x6a14, 0xa203, 0x6816, 0x1078, 0x1c3a,
- 0x007c, 0x1078, 0x12cd, 0x1078, 0x12cd, 0x127e, 0x2091, 0x2100,
- 0x007e, 0x017e, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002,
- 0xa184, 0x0700, 0x00c0, 0x1783, 0xa184, 0x0003, 0xa086, 0x0003,
- 0x0040, 0x1783, 0x7000, 0x0079, 0x179d, 0x17a5, 0x17a7, 0x187f,
- 0x18e7, 0x18fe, 0x17a5, 0x17a5, 0x17a5, 0x1078, 0x12cd, 0x8001,
- 0x7002, 0xa184, 0x0880, 0x00c0, 0x17bc, 0x8aff, 0x0040, 0x181f,
- 0x2009, 0x0001, 0x1078, 0x16f3, 0x0040, 0x1910, 0x2009, 0x0001,
- 0x1078, 0x16f3, 0x0078, 0x1910, 0x7803, 0x0004, 0x7003, 0x0000,
- 0xd1bc, 0x00c0, 0x1807, 0x027e, 0x037e, 0x6b28, 0x6a2c, 0x7820,
- 0x686e, 0xa31a, 0x7824, 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x7820,
- 0x6910, 0xa100, 0x6812, 0x7824, 0x6914, 0xa101, 0x6816, 0x037f,
- 0x027f, 0x7830, 0x681e, 0x7834, 0x6822, 0x1078, 0x1c53, 0x2a00,
- 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000, 0x6850,
- 0xc0fd, 0x6852, 0x6808, 0x8001, 0x680a, 0x00c0, 0x17f9, 0x684c,
- 0xd0e4, 0x0040, 0x17f9, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078,
- 0x5d41, 0x7808, 0xd0ec, 0x00c0, 0x1803, 0x7803, 0x0009, 0x7003,
- 0x0004, 0x0078, 0x1910, 0x1078, 0x16ad, 0x0078, 0x1910, 0x057e,
- 0x7d0c, 0xd5bc, 0x00c0, 0x180e, 0x1078, 0x7692, 0x057f, 0x1078,
- 0x1914, 0x682b, 0xffff, 0x682f, 0xffff, 0x697c, 0x6912, 0x6980,
- 0x6916, 0x7803, 0x0009, 0x7003, 0x0003, 0x0078, 0x1910, 0x684c,
- 0xc0f5, 0x684e, 0x7814, 0xa005, 0x00c0, 0x1837, 0x7003, 0x0000,
- 0x6808, 0x8001, 0x680a, 0x00c0, 0x1833, 0x7004, 0x2060, 0x2009,
- 0x0048, 0x1078, 0x5d41, 0x1078, 0x16ad, 0x0078, 0x1910, 0x7814,
- 0x6910, 0xa102, 0x6812, 0x6914, 0xa183, 0x0000, 0x6816, 0x7814,
- 0x7908, 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214, 0x8214,
- 0xa10a, 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b, 0x810b,
- 0x1078, 0x197b, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803, 0x0001,
- 0x7804, 0xd0fc, 0x0040, 0x1858, 0x7803, 0x0002, 0x7803, 0x0004,
- 0x780f, 0x0070, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048,
- 0x1078, 0x5d41, 0x1078, 0x199e, 0x0040, 0x1833, 0x7908, 0xd1ec,
- 0x00c0, 0x1876, 0x2009, 0x0009, 0x0078, 0x1878, 0x2009, 0x0019,
- 0x7902, 0x7803, 0x0009, 0x7003, 0x0003, 0x0078, 0x1910, 0x8001,
- 0x7002, 0xd194, 0x0040, 0x1891, 0x7804, 0xd0fc, 0x00c0, 0x178d,
- 0x8aff, 0x0040, 0x1910, 0x2009, 0x0001, 0x1078, 0x16f3, 0x0078,
- 0x1910, 0xa184, 0x0880, 0x00c0, 0x189e, 0x8aff, 0x0040, 0x1910,
- 0x2009, 0x0001, 0x1078, 0x16f3, 0x0078, 0x1910, 0x7803, 0x0004,
- 0x7003, 0x0000, 0xd1bc, 0x00c0, 0x18d2, 0x027e, 0x037e, 0x6b28,
- 0x6a2c, 0x1078, 0x1c53, 0x0d7e, 0x0f7e, 0x2d78, 0x2804, 0xac68,
- 0x6034, 0xd09c, 0x00c0, 0x18c2, 0x6808, 0x2008, 0xa31a, 0x680c,
- 0xa213, 0x7810, 0xa100, 0x7812, 0x690c, 0x7814, 0xa101, 0x7816,
- 0x0078, 0x18ce, 0x6810, 0x2008, 0xa31a, 0x6814, 0xa213, 0x7810,
- 0xa100, 0x7812, 0x6914, 0x7814, 0xa101, 0x7816, 0x0f7f, 0x0d7f,
- 0x0078, 0x17c7, 0x057e, 0x7d0c, 0x1078, 0x7692, 0x057f, 0x1078,
- 0x1914, 0x682b, 0xffff, 0x682f, 0xffff, 0x697c, 0x6912, 0x6980,
- 0x6916, 0x7803, 0x0009, 0x7003, 0x0003, 0x0078, 0x1910, 0x7803,
- 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, 0x0040, 0x18fa, 0x6808,
- 0x8001, 0x680a, 0x00c0, 0x18fa, 0x7004, 0x2060, 0x2009, 0x0048,
- 0x1078, 0x5d41, 0x1078, 0x16ad, 0x0078, 0x1910, 0x7803, 0x0004,
- 0x7003, 0x0000, 0x7004, 0x2060, 0x6010, 0xa005, 0x0040, 0x18fa,
- 0x2068, 0x6808, 0x8000, 0x680a, 0x6c28, 0x6b2c, 0x1078, 0x16c4,
- 0x017f, 0x007f, 0x127f, 0x007c, 0x1078, 0x1925, 0x20e1, 0x9028,
- 0x700f, 0x7970, 0x7013, 0x7970, 0x2001, 0x015d, 0x200c, 0x810a,
- 0x2102, 0x2001, 0x0138, 0x2202, 0x007c, 0x2001, 0x0138, 0x2014,
+ 0x53a5, 0x2001, 0x88f9, 0x2004, 0xd0bc, 0x0040, 0x14f0, 0x2001,
+ 0x8902, 0x2004, 0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, 0x53a5,
+ 0x157f, 0x147f, 0x137f, 0x7007, 0x0000, 0x1078, 0x4871, 0x1078,
+ 0x13a4, 0x007c, 0x2011, 0x8003, 0x1078, 0x317a, 0x0078, 0x14fe,
+ 0xa18c, 0x0700, 0x00c0, 0x150d, 0x2001, 0x8927, 0x2003, 0x0100,
+ 0x7007, 0x0000, 0x1078, 0x13a4, 0x007c, 0x2011, 0x8004, 0x1078,
+ 0x317a, 0x0078, 0x1511, 0x127e, 0x2091, 0x2100, 0x2079, 0x0030,
+ 0x2071, 0x8ad8, 0x7803, 0x0004, 0x7003, 0x0000, 0x700f, 0x8ade,
+ 0x7013, 0x8ade, 0x780f, 0x0076, 0x127f, 0x007c, 0x6934, 0xa184,
+ 0x0007, 0x0079, 0x152b, 0x1533, 0x1579, 0x1533, 0x1533, 0x1533,
+ 0x155e, 0x1542, 0x1537, 0xa085, 0x0001, 0x0078, 0x1593, 0x684c,
+ 0xd0bc, 0x0040, 0x1533, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858,
+ 0x0078, 0x1581, 0xa18c, 0x00ff, 0xa186, 0x001e, 0x00c0, 0x1533,
+ 0x684c, 0xd0bc, 0x0040, 0x1533, 0x6860, 0x682e, 0x685c, 0x682a,
+ 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+ 0x1def, 0x2004, 0x6832, 0x6858, 0x0078, 0x1589, 0xa18c, 0x00ff,
+ 0xa186, 0x0015, 0x00c0, 0x1533, 0x684c, 0xd0ac, 0x0040, 0x1533,
+ 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+ 0x1def, 0x2004, 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0078,
+ 0x1589, 0x684c, 0xd0ac, 0x0040, 0x1533, 0xa006, 0x682e, 0x682a,
+ 0x6858, 0xa18c, 0x000f, 0xa188, 0x1def, 0x210c, 0x6932, 0x2d08,
+ 0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c,
+ 0x6912, 0x6980, 0x6916, 0x007c, 0x20e1, 0x0007, 0x20e1, 0x2000,
+ 0x2001, 0x020a, 0x2004, 0x82ff, 0x0040, 0x15ae, 0xa280, 0x0004,
+ 0x0d7e, 0x206c, 0x684c, 0xd0dc, 0x00c0, 0x15aa, 0x1078, 0x1526,
+ 0x10c0, 0x12d2, 0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e,
+ 0x037e, 0x027e, 0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000,
+ 0xa005, 0x00c0, 0x15c2, 0x7206, 0x2001, 0x15e3, 0x007e, 0x2260,
+ 0x0078, 0x1724, 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a,
+ 0x8108, 0xa182, 0x8af9, 0x0048, 0x15cf, 0x2009, 0x8ade, 0x710e,
+ 0x7010, 0xa102, 0xa082, 0x0009, 0x0040, 0x15da, 0xa080, 0x001b,
+ 0x00c0, 0x15dd, 0x2009, 0x0138, 0x200a, 0x7000, 0xa005, 0x00c0,
+ 0x15e3, 0x1078, 0x1705, 0x127f, 0x007c, 0x127e, 0x027e, 0x037e,
+ 0x0c7e, 0x007e, 0x2091, 0x2100, 0x007f, 0x047f, 0x037f, 0x027f,
+ 0x0d7e, 0x0c7e, 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e, 0xa005,
+ 0x0040, 0x163c, 0x6808, 0xa005, 0x0040, 0x16a2, 0x7000, 0xa005,
+ 0x00c0, 0x1604, 0x0078, 0x1631, 0x700c, 0x7110, 0xa106, 0x00c0,
+ 0x16ab, 0x7004, 0xa406, 0x00c0, 0x1631, 0x2001, 0x0005, 0x2004,
+ 0xd08c, 0x0040, 0x161a, 0x047e, 0x1078, 0x1816, 0x047f, 0x2460,
+ 0x0078, 0x15fa, 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0, 0x160d,
+ 0x7804, 0xa084, 0x6000, 0x0040, 0x162b, 0xa086, 0x6000, 0x0040,
+ 0x162b, 0x0078, 0x160d, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004,
+ 0x2060, 0x6100, 0xa18e, 0x0004, 0x00c0, 0x16ab, 0x2009, 0x0048,
+ 0x1078, 0x6939, 0x0078, 0x16ab, 0x6808, 0xa005, 0x0040, 0x16a2,
+ 0x7000, 0xa005, 0x00c0, 0x1646, 0x0078, 0x16a2, 0x700c, 0x7110,
+ 0xa106, 0x00c0, 0x164f, 0x7004, 0xa406, 0x00c0, 0x16a2, 0x2001,
+ 0x0005, 0x2004, 0xd08c, 0x0040, 0x165c, 0x047e, 0x1078, 0x1816,
+ 0x047f, 0x2460, 0x0078, 0x163c, 0x2001, 0x0207, 0x2004, 0xd09c,
+ 0x00c0, 0x164f, 0x2001, 0x0005, 0x2004, 0xd08c, 0x00c0, 0x1655,
+ 0x7804, 0xa084, 0x6000, 0x0040, 0x1673, 0xa086, 0x6000, 0x0040,
+ 0x1673, 0x0078, 0x164f, 0x7007, 0x0000, 0xa016, 0x2218, 0x7000,
+ 0xa08e, 0x0001, 0x0040, 0x1694, 0xa08e, 0x0002, 0x00c0, 0x16a2,
+ 0x0c7e, 0x0e7e, 0x6818, 0x2060, 0x1078, 0x1dc4, 0x2804, 0xac70,
+ 0x6034, 0xd09c, 0x00c0, 0x1690, 0x7308, 0x720c, 0x0078, 0x1692,
+ 0x7310, 0x7214, 0x0e7f, 0x0c7f, 0x7820, 0xa318, 0x7824, 0xa211,
+ 0x6810, 0xa300, 0x6812, 0x6814, 0xa201, 0x6816, 0x7803, 0x0004,
+ 0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x00c0, 0x16ab, 0x2009,
+ 0x0048, 0x1078, 0x6939, 0x0c7f, 0x0d7f, 0x127f, 0x007c, 0x0f7e,
+ 0x0e7e, 0x027e, 0x037e, 0x047e, 0x1078, 0x19e5, 0x027e, 0x2071,
+ 0x8ad8, 0x7000, 0xa086, 0x0000, 0x0040, 0x16f6, 0x7004, 0xac06,
+ 0x00c0, 0x16e7, 0x2079, 0x0030, 0x7000, 0xa086, 0x0003, 0x0040,
+ 0x16e7, 0x7804, 0xd0fc, 0x00c0, 0x16e3, 0x2001, 0x0207, 0x2004,
+ 0xd09c, 0x00c0, 0x16c9, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0,
+ 0x16d5, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003, 0x0003, 0x7007,
+ 0x0000, 0x0078, 0x16e7, 0x1078, 0x1816, 0x0078, 0x16b9, 0x157e,
+ 0x20a9, 0x0009, 0x2009, 0x8ade, 0x2104, 0xac06, 0x00c0, 0x16f1,
+ 0x200a, 0xa188, 0x0003, 0x00f0, 0x16ec, 0x157f, 0x027f, 0x2001,
+ 0x015d, 0x201c, 0x831a, 0x2302, 0x2001, 0x0138, 0x2202, 0x047f,
+ 0x037f, 0x027f, 0x0e7f, 0x0f7f, 0x007c, 0x700c, 0x7110, 0xa106,
+ 0x00c0, 0x170d, 0x7003, 0x0000, 0x007c, 0x2104, 0x7006, 0x2060,
+ 0x8108, 0x211c, 0x8108, 0x2124, 0x8108, 0xa182, 0x8af9, 0x0048,
+ 0x171b, 0x2009, 0x8ade, 0x7112, 0x700c, 0xa106, 0x00c0, 0x1724,
+ 0x2001, 0x0138, 0x2003, 0x0008, 0x8cff, 0x00c0, 0x172b, 0x1078,
+ 0x1a10, 0x0078, 0x1757, 0x6010, 0x2068, 0x2d58, 0x6828, 0xa406,
+ 0x00c0, 0x1736, 0x682c, 0xa306, 0x0040, 0x173f, 0x601c, 0xa086,
+ 0x0008, 0x0040, 0x173f, 0x1078, 0x1e0f, 0x00c0, 0x1727, 0x684c,
+ 0xd0f4, 0x00c0, 0x1727, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830,
+ 0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009, 0x0011, 0x1078, 0x1758,
+ 0x0040, 0x1756, 0x2009, 0x0001, 0x1078, 0x1758, 0x2d58, 0x007c,
+ 0x8aff, 0x0040, 0x17ef, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x00c0,
+ 0x177a, 0xd0f4, 0x00c0, 0x178a, 0x0d7e, 0x2804, 0xac68, 0x2900,
+ 0x0079, 0x176a, 0x17d1, 0x1791, 0x1791, 0x17d1, 0x17d1, 0x17c9,
+ 0x17d1, 0x1791, 0x17d1, 0x1797, 0x1797, 0x17d1, 0x17d1, 0x17d1,
+ 0x17c0, 0x1797, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20,
+ 0x0d7e, 0xd99c, 0x0040, 0x17d4, 0x2804, 0xac68, 0x6f08, 0x6e0c,
+ 0x0078, 0x17d4, 0xc0f4, 0x6852, 0x6b6c, 0x6a70, 0x0d7e, 0x0078,
+ 0x17db, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0078, 0x17d4, 0x7b0c,
+ 0xd3bc, 0x0040, 0x17b8, 0x7004, 0x0e7e, 0x2070, 0x701c, 0x0e7f,
+ 0xa086, 0x0008, 0x00c0, 0x17b8, 0x7b08, 0xa39c, 0x0fff, 0x2d20,
+ 0x0d7f, 0x0d7e, 0x6a14, 0x82ff, 0x00c0, 0x17b3, 0x6810, 0xa302,
+ 0x0048, 0x17b3, 0x6b10, 0x2011, 0x0000, 0x2468, 0x0078, 0x17ba,
+ 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0078, 0x17d4,
+ 0x0d7f, 0x0d7e, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0,
+ 0x17d1, 0x0d7f, 0x1078, 0x1dab, 0x00c0, 0x1758, 0xa00e, 0x0078,
+ 0x17ef, 0x0d7f, 0x1078, 0x12d2, 0x7b22, 0x7a26, 0x7d32, 0x7c36,
+ 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x0d7f, 0x6828,
+ 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x2300, 0x6b10, 0xa302,
+ 0x6812, 0x2200, 0x6a14, 0xa203, 0x6816, 0x1078, 0x1dab, 0x007c,
+ 0x1078, 0x12d2, 0x7803, 0x0004, 0x7004, 0x2060, 0x0d7e, 0x6010,
+ 0x2068, 0x7003, 0x0000, 0x1078, 0x19b4, 0x1078, 0x77ed, 0x0040,
+ 0x180f, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916,
+ 0x682b, 0xffff, 0x682f, 0xffff, 0x6850, 0xc0bd, 0x6852, 0x0d7f,
+ 0x1078, 0x759a, 0x0078, 0x19b0, 0x1078, 0x12d2, 0x127e, 0x2091,
+ 0x2100, 0x007e, 0x017e, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803,
+ 0x0002, 0xa184, 0x0700, 0x00c0, 0x17f2, 0xa184, 0x0003, 0xa086,
+ 0x0003, 0x0040, 0x1814, 0x7000, 0x0079, 0x182e, 0x1836, 0x1838,
+ 0x1914, 0x1987, 0x199e, 0x1836, 0x1836, 0x1836, 0x1078, 0x12d2,
+ 0x8001, 0x7002, 0xa184, 0x0880, 0x00c0, 0x184d, 0x8aff, 0x0040,
+ 0x18b6, 0x2009, 0x0001, 0x1078, 0x1758, 0x0040, 0x19b0, 0x2009,
+ 0x0001, 0x1078, 0x1758, 0x0078, 0x19b0, 0x7803, 0x0004, 0x7003,
+ 0x0000, 0xd1bc, 0x00c0, 0x189f, 0x027e, 0x037e, 0x7808, 0xd0ec,
+ 0x00c0, 0x1860, 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1862,
+ 0x1078, 0x1a80, 0x6b28, 0x6a2c, 0x2400, 0x686e, 0xa31a, 0x2500,
+ 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x2400, 0x6910, 0xa100, 0x6812,
+ 0x2500, 0x6914, 0xa101, 0x6816, 0x037f, 0x027f, 0x2600, 0x681e,
+ 0x2700, 0x6822, 0x1078, 0x1dc4, 0x2a00, 0x6826, 0x2c00, 0x681a,
+ 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852, 0x6808, 0x8001, 0x680a,
+ 0x00c0, 0x1894, 0x684c, 0xd0e4, 0x0040, 0x1894, 0x7004, 0x2060,
+ 0x2009, 0x0048, 0x1078, 0x6939, 0x7000, 0xa086, 0x0004, 0x0040,
+ 0x19b0, 0x7003, 0x0000, 0x1078, 0x1705, 0x0078, 0x19b0, 0x057e,
+ 0x7d0c, 0xd5bc, 0x00c0, 0x18a6, 0x1078, 0x874c, 0x057f, 0x1078,
+ 0x19b4, 0x682b, 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a,
+ 0x697c, 0x6912, 0x6980, 0x6916, 0x0078, 0x19b0, 0x684c, 0xc0f5,
+ 0x684e, 0x7814, 0xa005, 0x00c0, 0x18ce, 0x7003, 0x0000, 0x6808,
+ 0x8001, 0x680a, 0x00c0, 0x18ca, 0x7004, 0x2060, 0x2009, 0x0048,
+ 0x1078, 0x6939, 0x1078, 0x1705, 0x0078, 0x19b0, 0x7814, 0x6910,
+ 0xa102, 0x6812, 0x6914, 0xa183, 0x0000, 0x6816, 0x7814, 0x7908,
+ 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214, 0x8214, 0xa10a,
+ 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b, 0x810b, 0x1078,
+ 0x1a3b, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803, 0x0001, 0x7804,
+ 0xd0fc, 0x0040, 0x18ef, 0x7803, 0x0002, 0x7803, 0x0004, 0x780f,
+ 0x0076, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048, 0x1078,
+ 0x6939, 0x1078, 0x1a5e, 0x0040, 0x18ca, 0x7908, 0xd1ec, 0x00c0,
+ 0x190d, 0x2009, 0x0009, 0x0078, 0x190f, 0x2009, 0x0019, 0x7902,
+ 0x7003, 0x0003, 0x0078, 0x19b0, 0x8001, 0x7002, 0xd194, 0x0040,
+ 0x1926, 0x7804, 0xd0fc, 0x00c0, 0x181e, 0x8aff, 0x0040, 0x19b0,
+ 0x2009, 0x0001, 0x1078, 0x1758, 0x0078, 0x19b0, 0xa184, 0x0880,
+ 0x00c0, 0x1933, 0x8aff, 0x0040, 0x19b0, 0x2009, 0x0001, 0x1078,
+ 0x1758, 0x0078, 0x19b0, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc,
+ 0x00c0, 0x1973, 0x027e, 0x037e, 0x7808, 0xd0ec, 0x00c0, 0x1946,
+ 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1948, 0x1078, 0x1a80,
+ 0x6b28, 0x6a2c, 0x1078, 0x1dc4, 0x0d7e, 0x0f7e, 0x2d78, 0x2804,
+ 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1963, 0x6808, 0x2008, 0xa31a,
+ 0x680c, 0xa213, 0x7810, 0xa100, 0x7812, 0x690c, 0x7814, 0xa101,
+ 0x7816, 0x0078, 0x196f, 0x6810, 0x2008, 0xa31a, 0x6814, 0xa213,
+ 0x7810, 0xa100, 0x7812, 0x6914, 0x7814, 0xa101, 0x7816, 0x0f7f,
+ 0x0d7f, 0x0078, 0x1864, 0x057e, 0x7d0c, 0x1078, 0x874c, 0x057f,
+ 0x1078, 0x19b4, 0x682b, 0xffff, 0x682f, 0xffff, 0x6808, 0x8001,
+ 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x0078, 0x19b0, 0x7803,
+ 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, 0x0040, 0x199a, 0x6808,
+ 0x8001, 0x680a, 0x00c0, 0x199a, 0x7004, 0x2060, 0x2009, 0x0048,
+ 0x1078, 0x6939, 0x1078, 0x1705, 0x0078, 0x19b0, 0x7803, 0x0004,
+ 0x7003, 0x0000, 0x7004, 0x2060, 0x6010, 0xa005, 0x0040, 0x199a,
+ 0x2068, 0x6808, 0x8000, 0x680a, 0x6c28, 0x6b2c, 0x1078, 0x1724,
+ 0x017f, 0x007f, 0x127f, 0x007c, 0x0c7e, 0x1078, 0x19e5, 0x20e1,
+ 0x9028, 0x700c, 0x7110, 0xa106, 0x0040, 0x19db, 0x2104, 0xa005,
+ 0x0040, 0x19c8, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001, 0x600a,
+ 0xa188, 0x0003, 0xa182, 0x8af9, 0x0048, 0x19d0, 0x2009, 0x8ade,
+ 0x7112, 0x700c, 0xa106, 0x00c0, 0x19b9, 0x2001, 0x0138, 0x2003,
+ 0x0008, 0x0078, 0x19b9, 0x2001, 0x015d, 0x200c, 0x810a, 0x2102,
+ 0x2001, 0x0138, 0x2202, 0x0c7f, 0x007c, 0x2001, 0x0138, 0x2014,
0x2003, 0x0000, 0x2021, 0xb015, 0x2001, 0x0141, 0x201c, 0xd3dc,
- 0x00c0, 0x1942, 0x2001, 0x0109, 0x201c, 0xa39c, 0x0048, 0x00c0,
- 0x1942, 0x2001, 0x0111, 0x201c, 0x83ff, 0x00c0, 0x1942, 0x8421,
- 0x00c0, 0x192c, 0x007c, 0x2011, 0x0201, 0x2009, 0x003c, 0x2204,
- 0xa005, 0x00c0, 0x194f, 0x8109, 0x00c0, 0x1947, 0x007c, 0x007c,
- 0x1078, 0x1943, 0x0040, 0x1978, 0x7908, 0xd1ec, 0x00c0, 0x1968,
- 0x1078, 0x199e, 0x0040, 0x1968, 0x7803, 0x0009, 0x7904, 0xd1fc,
- 0x0040, 0x195e, 0x7803, 0x0006, 0x1078, 0x1943, 0x0040, 0x1978,
- 0x780c, 0xd0a4, 0x00c0, 0x1978, 0x7007, 0x0000, 0x1078, 0x199e,
- 0x0040, 0x197a, 0x7803, 0x0019, 0x7003, 0x0003, 0x0078, 0x197a,
- 0x1078, 0x1914, 0x007c, 0x3c00, 0x007e, 0x0e7e, 0x2071, 0x0200,
- 0x7808, 0xa084, 0xf000, 0xa10d, 0x1078, 0x1925, 0x20e1, 0x7000,
+ 0x00c0, 0x1a02, 0x2001, 0x0109, 0x201c, 0xa39c, 0x0048, 0x00c0,
+ 0x1a02, 0x2001, 0x0111, 0x201c, 0x83ff, 0x00c0, 0x1a02, 0x8421,
+ 0x00c0, 0x19ec, 0x007c, 0x2011, 0x0201, 0x2009, 0x003c, 0x2204,
+ 0xa005, 0x00c0, 0x1a0f, 0x8109, 0x00c0, 0x1a07, 0x007c, 0x007c,
+ 0x1078, 0x1a03, 0x0040, 0x1a38, 0x7908, 0xd1ec, 0x00c0, 0x1a28,
+ 0x1078, 0x1a5e, 0x0040, 0x1a28, 0x7803, 0x0009, 0x7904, 0xd1fc,
+ 0x0040, 0x1a1e, 0x7803, 0x0006, 0x1078, 0x1a03, 0x0040, 0x1a38,
+ 0x780c, 0xd0a4, 0x00c0, 0x1a38, 0x7007, 0x0000, 0x1078, 0x1a5e,
+ 0x0040, 0x1a3a, 0x7803, 0x0019, 0x7003, 0x0003, 0x0078, 0x1a3a,
+ 0x1078, 0x19b4, 0x007c, 0x3c00, 0x007e, 0x0e7e, 0x2071, 0x0200,
+ 0x7808, 0xa084, 0xf000, 0xa10d, 0x1078, 0x19e5, 0x20e1, 0x7000,
0x7324, 0x7420, 0x7028, 0x7028, 0x7426, 0x7037, 0x0001, 0x810f,
0x712e, 0x702f, 0x0100, 0x7037, 0x0008, 0x7326, 0x7422, 0x2001,
0x0138, 0x2202, 0x0e7f, 0x007f, 0x20e0, 0x007c, 0x3c00, 0x007e,
- 0x7908, 0xa18c, 0x0fff, 0xa182, 0x0009, 0x0048, 0x19ab, 0xa085,
- 0x0001, 0x0078, 0x19bd, 0x2001, 0x020a, 0x81ff, 0x0040, 0x19b6,
+ 0x7908, 0xa18c, 0x0fff, 0xa182, 0x0009, 0x0048, 0x1a6b, 0xa085,
+ 0x0001, 0x0078, 0x1a7d, 0x2001, 0x020a, 0x81ff, 0x0040, 0x1a76,
0x20e1, 0x6000, 0x200c, 0x200c, 0x200c, 0x200c, 0x20e1, 0x7000,
0x200c, 0x200c, 0x7003, 0x0000, 0xa006, 0x007f, 0x20e0, 0x007c,
- 0x0e7e, 0x2071, 0x798b, 0x7003, 0x0000, 0x0e7f, 0x007c, 0x0d7e,
- 0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc, 0x00c0, 0x1a42, 0x6934,
- 0xa184, 0x0007, 0x0079, 0x19d4, 0x19dc, 0x1a2d, 0x19dc, 0x19dc,
- 0x19dc, 0x1a12, 0x19ef, 0x19de, 0x1078, 0x12cd, 0x684c, 0xd0b4,
- 0x0040, 0x1b46, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812,
- 0x687c, 0x680a, 0x6880, 0x680e, 0x6958, 0x0078, 0x1a35, 0x6834,
- 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x19dc, 0x684c, 0xd0b4,
- 0x0040, 0x1b46, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812,
+ 0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x700c, 0x7110, 0xa106, 0x0040,
+ 0x1aff, 0x7004, 0x017e, 0x210c, 0xa106, 0x017f, 0x0040, 0x1aff,
+ 0x0d7e, 0x0c7e, 0x216c, 0x2d00, 0xa005, 0x0040, 0x1afd, 0x6810,
+ 0x2068, 0x6850, 0xd0fc, 0x0040, 0x1ac9, 0x8108, 0x2104, 0x6b2c,
+ 0xa306, 0x00c0, 0x1afd, 0x8108, 0x2104, 0x6a28, 0xa206, 0x00c0,
+ 0x1afd, 0x6850, 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822, 0x6870,
+ 0x7826, 0x681c, 0x7832, 0x6820, 0x7836, 0x6818, 0x2060, 0x6034,
+ 0xd09c, 0x0040, 0x1ac4, 0x6830, 0x2004, 0xac68, 0x6808, 0x783a,
+ 0x680c, 0x783e, 0x0078, 0x1afb, 0xa006, 0x783a, 0x783e, 0x0078,
+ 0x1afb, 0x8108, 0x2104, 0xa005, 0x00c0, 0x1afd, 0x8108, 0x2104,
+ 0xa005, 0x00c0, 0x1afd, 0x6850, 0xc0f5, 0x6852, 0x6830, 0x2004,
+ 0x6918, 0xa160, 0x6834, 0xd09c, 0x00c0, 0x1aed, 0x6008, 0x7822,
+ 0x686e, 0x600c, 0x7826, 0x6872, 0x6000, 0x7832, 0x6004, 0x7836,
+ 0xa006, 0x783a, 0x783e, 0x0078, 0x1afb, 0x6010, 0x7822, 0x686e,
+ 0x6014, 0x7826, 0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0x6008,
+ 0x783a, 0x600c, 0x783e, 0x7803, 0x0011, 0x0c7f, 0x0d7f, 0x007c,
+ 0x0e7e, 0x2071, 0x8af9, 0x7003, 0x0000, 0x0e7f, 0x007c, 0x0d7e,
+ 0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc, 0x00c0, 0x1b82, 0x6934,
+ 0xa184, 0x0007, 0x0079, 0x1b14, 0x1b1c, 0x1b6d, 0x1b1c, 0x1b1c,
+ 0x1b1c, 0x1b52, 0x1b2f, 0x1b1e, 0x1078, 0x12d2, 0x684c, 0xd0b4,
+ 0x0040, 0x1c90, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812,
+ 0x687c, 0x680a, 0x6880, 0x680e, 0x6958, 0x0078, 0x1b75, 0x6834,
+ 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x1b1c, 0x684c, 0xd0b4,
+ 0x0040, 0x1c90, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812,
0x687c, 0x680a, 0x6880, 0x680e, 0x6804, 0x681a, 0xa080, 0x000d,
- 0x2004, 0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004, 0x6832, 0x6958,
- 0x0078, 0x1a3e, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x00c0, 0x1a42,
- 0x684c, 0xd0b4, 0x0040, 0x1b46, 0x6804, 0x681a, 0xa080, 0x000d,
- 0x2004, 0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004, 0x6832, 0x6958,
- 0xa006, 0x682e, 0x682a, 0x0078, 0x1a3e, 0x684c, 0xd0b4, 0x0040,
- 0x1781, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00, 0x681a, 0x6834,
- 0xa084, 0x000f, 0xa080, 0x1c7e, 0x2004, 0x6832, 0x6926, 0x684c,
+ 0x2004, 0xa084, 0x000f, 0xa080, 0x1def, 0x2004, 0x6832, 0x6958,
+ 0x0078, 0x1b7e, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x00c0, 0x1b82,
+ 0x684c, 0xd0b4, 0x0040, 0x1c90, 0x6804, 0x681a, 0xa080, 0x000d,
+ 0x2004, 0xa084, 0x000f, 0xa080, 0x1def, 0x2004, 0x6832, 0x6958,
+ 0xa006, 0x682e, 0x682a, 0x0078, 0x1b7e, 0x684c, 0xd0b4, 0x0040,
+ 0x17f0, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00, 0x681a, 0x6834,
+ 0xa084, 0x000f, 0xa080, 0x1def, 0x2004, 0x6832, 0x6926, 0x684c,
0xc0dd, 0x684e, 0x0d7f, 0x007c, 0x0f7e, 0x2079, 0x0020, 0x7804,
- 0xd0fc, 0x10c0, 0x1b4a, 0x0e7e, 0x0d7e, 0x2071, 0x798b, 0x7000,
- 0xa005, 0x00c0, 0x1ac0, 0x0c7e, 0x7206, 0xa280, 0x0004, 0x205c,
+ 0xd0fc, 0x10c0, 0x1cb7, 0x0e7e, 0x0d7e, 0x2071, 0x8af9, 0x7000,
+ 0xa005, 0x00c0, 0x1c07, 0x0c7e, 0x7206, 0xa280, 0x0004, 0x205c,
0x7004, 0x2068, 0x7803, 0x0004, 0x6818, 0x0d7e, 0x2068, 0x686c,
0x7812, 0x6890, 0x0f7e, 0x20e1, 0x9040, 0x2079, 0x0200, 0x781a,
0x2079, 0x0100, 0x8004, 0x78d6, 0x0f7f, 0x0d7f, 0x2b68, 0x6824,
0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f,
- 0x6908, 0xa184, 0x0007, 0x0040, 0x1a82, 0x017e, 0x2009, 0x0008,
- 0xa102, 0x017f, 0xa108, 0x791a, 0x7116, 0x701e, 0x680c, 0xa081,
- 0x0000, 0x781e, 0x701a, 0xa006, 0x700e, 0x7012, 0x7004, 0x692c,
- 0x6814, 0xa106, 0x00c0, 0x1a99, 0x6928, 0x6810, 0xa106, 0x0040,
- 0x1aa6, 0x037e, 0x047e, 0x6b14, 0x6c10, 0x1078, 0x1c9e, 0x047f,
- 0x037f, 0x0040, 0x1aa6, 0x0c7f, 0x0078, 0x1ac0, 0x8aff, 0x00c0,
- 0x1aae, 0x0c7f, 0xa085, 0x0001, 0x0078, 0x1ac0, 0x127e, 0x2091,
- 0x8000, 0x2079, 0x0020, 0x2009, 0x0001, 0x1078, 0x1ac4, 0x0040,
- 0x1abd, 0x2009, 0x0001, 0x1078, 0x1ac4, 0x127f, 0x0c7f, 0xa006,
- 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x077e, 0x067e, 0x057e, 0x047e,
- 0x037e, 0x027e, 0x8aff, 0x0040, 0x1b3f, 0x700c, 0x7214, 0xa202,
- 0x7010, 0x7218, 0xa203, 0x0048, 0x1b3e, 0xa03e, 0x2730, 0x6850,
- 0xd0fc, 0x00c0, 0x1af1, 0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079,
- 0x1ae1, 0x1b20, 0x1b01, 0x1b01, 0x1b20, 0x1b20, 0x1b18, 0x1b20,
- 0x1b01, 0x1b20, 0x1b07, 0x1b07, 0x1b20, 0x1b20, 0x1b20, 0x1b0f,
- 0x1b07, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0xd99c,
- 0x0040, 0x1b24, 0x0d7e, 0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078,
- 0x1b23, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0078, 0x1b23, 0x6b10,
- 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0078, 0x1b23, 0x0d7f,
- 0x0d7e, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x1b20,
- 0x0d7f, 0x1078, 0x1c3a, 0x00c0, 0x1aca, 0xa00e, 0x0078, 0x1b3f,
- 0x0d7f, 0x1078, 0x12cd, 0x0d7f, 0x7b22, 0x7a26, 0x7d32, 0x7c36,
- 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300,
- 0x682a, 0x682c, 0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010,
- 0xa201, 0x7012, 0x1078, 0x1c3a, 0x0078, 0x1b3f, 0xa006, 0x027f,
- 0x037f, 0x047f, 0x057f, 0x067f, 0x077f, 0x007c, 0x1078, 0x12cd,
- 0x1078, 0x12cd, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x0f7e,
- 0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020, 0x2071, 0x798b, 0x2b68,
- 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x00c0,
- 0x1b48, 0x7000, 0x0079, 0x1b64, 0x1c0b, 0x1b68, 0x1bd8, 0x1c09,
- 0x8001, 0x7002, 0xd19c, 0x00c0, 0x1b7c, 0x8aff, 0x0040, 0x1b9b,
- 0x2009, 0x0001, 0x1078, 0x1ac4, 0x0040, 0x1c0b, 0x2009, 0x0001,
- 0x1078, 0x1ac4, 0x0078, 0x1c0b, 0x7803, 0x0004, 0xd194, 0x0040,
- 0x1b8c, 0x6850, 0xc0fc, 0x6852, 0x8aff, 0x00c0, 0x1b91, 0x684c,
- 0xc0f5, 0x684e, 0x0078, 0x1b91, 0x1078, 0x1c53, 0x6850, 0xc0fd,
- 0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003,
- 0x0000, 0x0078, 0x1c0b, 0x711c, 0x81ff, 0x0040, 0x1bb1, 0x7918,
- 0x7922, 0x7827, 0x0000, 0x7803, 0x0001, 0x7000, 0x8000, 0x7002,
- 0x700c, 0xa100, 0x700e, 0x7010, 0xa081, 0x0000, 0x7012, 0x0078,
- 0x1c0b, 0x0f7e, 0x027e, 0x781c, 0x007e, 0x7818, 0x007e, 0x2079,
- 0x0100, 0x7a14, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x7820,
- 0xd0bc, 0x00c0, 0x1bbf, 0x79c8, 0x007f, 0xa102, 0x78ca, 0x79c4,
- 0x007f, 0xa102, 0x78c6, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816,
- 0x027f, 0x0f7f, 0x7803, 0x0008, 0x7003, 0x0000, 0x0078, 0x1c0b,
- 0x8001, 0x7002, 0xd194, 0x0040, 0x1bed, 0x7804, 0xd0fc, 0x00c0,
- 0x1b5a, 0xd19c, 0x00c0, 0x1c07, 0x8aff, 0x0040, 0x1c0b, 0x2009,
- 0x0001, 0x1078, 0x1ac4, 0x0078, 0x1c0b, 0x027e, 0x037e, 0x6b28,
- 0x6a2c, 0x1078, 0x1c53, 0x0d7e, 0x2804, 0xac68, 0x6034, 0xd09c,
- 0x00c0, 0x1c00, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0078, 0x1c04,
- 0x6810, 0xa31a, 0x6814, 0xa213, 0x0d7f, 0x0078, 0x1b8c, 0x0078,
- 0x1b8c, 0x1078, 0x12cd, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x017f,
- 0x007f, 0x127f, 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0x798b, 0x7000,
- 0xa086, 0x0000, 0x0040, 0x1c37, 0x2079, 0x0020, 0x20e1, 0x9040,
- 0x7804, 0xd0fc, 0x0040, 0x1c1e, 0x1078, 0x1b4a, 0x7000, 0xa086,
- 0x0000, 0x00c0, 0x1c1e, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0,
- 0x1c2d, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x0e7f,
- 0x0f7f, 0x007c, 0x8840, 0x2804, 0xa005, 0x00c0, 0x1c4e, 0x6004,
- 0xa005, 0x0040, 0x1c50, 0x681a, 0x2060, 0x6034, 0xa084, 0x000f,
- 0xa080, 0x1c7e, 0x2044, 0x88ff, 0x1040, 0x12cd, 0x8a51, 0x007c,
- 0x2051, 0x0000, 0x007c, 0x8a50, 0x8841, 0x2804, 0xa005, 0x00c0,
- 0x1c6d, 0x2c00, 0xad06, 0x0040, 0x1c62, 0x6000, 0xa005, 0x00c0,
- 0x1c62, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080,
- 0x1c8e, 0x2044, 0x88ff, 0x1040, 0x12cd, 0x007c, 0x0000, 0x0011,
- 0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f,
- 0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x1c73,
- 0x1c6f, 0x0000, 0x0000, 0x1c7d, 0x0000, 0x1c73, 0x0000, 0x1c7a,
- 0x1c77, 0x0000, 0x0000, 0x0000, 0x1c7d, 0x1c7a, 0x0000, 0x1c75,
- 0x1c75, 0x0000, 0x0000, 0x1c7d, 0x0000, 0x1c75, 0x0000, 0x1c7b,
- 0x1c7b, 0x0000, 0x0000, 0x0000, 0x1c7d, 0x1c7b, 0x0a7e, 0x097e,
- 0x087e, 0x6858, 0xa055, 0x0040, 0x1d3f, 0x2d60, 0x6034, 0xa0cc,
- 0x000f, 0xa9c0, 0x1c7e, 0xa986, 0x0007, 0x0040, 0x1cb7, 0xa986,
- 0x000e, 0x0040, 0x1cb7, 0xa986, 0x000f, 0x00c0, 0x1cbb, 0x605c,
- 0xa422, 0x6060, 0xa31a, 0x2804, 0xa045, 0x00c0, 0x1cc9, 0x0050,
- 0x1cc3, 0x0078, 0x1d3f, 0x6004, 0xa065, 0x0040, 0x1d3f, 0x0078,
- 0x1ca6, 0x2804, 0xa005, 0x0040, 0x1ce7, 0xac68, 0xd99c, 0x00c0,
- 0x1cd7, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0078, 0x1cdb, 0x6810,
- 0xa422, 0x6814, 0xa31b, 0x0048, 0x1d06, 0x2300, 0xa405, 0x0040,
- 0x1ced, 0x8a51, 0x0040, 0x1d3f, 0x8840, 0x0078, 0x1cc9, 0x6004,
- 0xa065, 0x0040, 0x1d3f, 0x0078, 0x1ca6, 0x8a51, 0x0040, 0x1d3f,
- 0x8840, 0x2804, 0xa005, 0x00c0, 0x1d00, 0x6004, 0xa065, 0x0040,
- 0x1d3f, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x1c7e, 0x2804, 0x2040,
- 0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0078, 0x1d33, 0x8422, 0x8420,
- 0x831a, 0xa399, 0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72, 0x0d7f,
- 0xd99c, 0x00c0, 0x1d21, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300,
- 0xa11b, 0x1048, 0x12cd, 0x6800, 0xa420, 0x6804, 0xa319, 0x0078,
- 0x1d2d, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, 0x1048,
- 0x12cd, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, 0x6b22,
- 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832, 0x2a00,
- 0x6826, 0x007f, 0x007f, 0x007f, 0xa006, 0x0078, 0x1d44, 0x087f,
- 0x097f, 0x0a7f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0005, 0x2004,
- 0xa084, 0x0007, 0x0079, 0x1d4c, 0x1d54, 0x1d55, 0x1d58, 0x1d5b,
- 0x1d60, 0x1d63, 0x1d68, 0x1d6d, 0x007c, 0x1078, 0x1b4a, 0x007c,
- 0x1078, 0x1785, 0x007c, 0x1078, 0x1785, 0x1078, 0x1b4a, 0x007c,
- 0x1078, 0x1456, 0x007c, 0x1078, 0x1b4a, 0x1078, 0x1456, 0x007c,
- 0x1078, 0x1785, 0x1078, 0x1456, 0x007c, 0x1078, 0x1785, 0x1078,
- 0x1b4a, 0x1078, 0x1456, 0x007c, 0x127e, 0x2091, 0x2300, 0x2079,
- 0x0200, 0x2071, 0x7c80, 0x2069, 0x7700, 0x2009, 0x0004, 0x7912,
- 0x7817, 0x0004, 0x1078, 0x2052, 0x781b, 0x0002, 0x20e1, 0x8700,
- 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x781c, 0xa084, 0x0007,
- 0x0079, 0x1d92, 0x1db6, 0x1d9a, 0x1d9e, 0x1da2, 0x1da8, 0x1dac,
- 0x1db0, 0x1db4, 0x1078, 0x4298, 0x0078, 0x1db6, 0x1078, 0x42c7,
- 0x0078, 0x1db6, 0x1078, 0x4298, 0x1078, 0x42c7, 0x0078, 0x1db6,
- 0x1078, 0x1db8, 0x0078, 0x1db6, 0x1078, 0x1db8, 0x0078, 0x1db6,
- 0x1078, 0x1db8, 0x0078, 0x1db6, 0x1078, 0x1db8, 0x127f, 0x007c,
- 0x007e, 0x017e, 0x027e, 0x7930, 0xa184, 0x0003, 0x0040, 0x1dc2,
- 0x1078, 0x12cd, 0xa184, 0x0030, 0x0040, 0x1dd3, 0x6a00, 0xa286,
- 0x0003, 0x00c0, 0x1dcd, 0x1078, 0x12cd, 0x1078, 0x3591, 0x20e1,
- 0x9010, 0x0078, 0x1ddf, 0xa184, 0x00c0, 0x0040, 0x1dd9, 0x1078,
- 0x12cd, 0xa184, 0x0300, 0x0040, 0x1ddf, 0x20e1, 0x9020, 0x7932,
- 0x027f, 0x017f, 0x007f, 0x007c, 0x017e, 0x0e7e, 0x0f7e, 0x2071,
- 0x7700, 0x7128, 0x2001, 0x7923, 0x2102, 0x2001, 0x792b, 0x2102,
- 0xa182, 0x0211, 0x00c8, 0x1df8, 0x2009, 0x0008, 0x0078, 0x1e22,
- 0xa182, 0x0259, 0x00c8, 0x1e00, 0x2009, 0x0007, 0x0078, 0x1e22,
- 0xa182, 0x02c1, 0x00c8, 0x1e08, 0x2009, 0x0006, 0x0078, 0x1e22,
- 0xa182, 0x0349, 0x00c8, 0x1e10, 0x2009, 0x0005, 0x0078, 0x1e22,
- 0xa182, 0x0421, 0x00c8, 0x1e18, 0x2009, 0x0004, 0x0078, 0x1e22,
- 0xa182, 0x0581, 0x00c8, 0x1e20, 0x2009, 0x0003, 0x0078, 0x1e22,
- 0x2009, 0x0002, 0x2079, 0x0200, 0x7912, 0xa182, 0x0005, 0x00c8,
- 0x1e2c, 0x7916, 0x0078, 0x1e2e, 0x7817, 0x0004, 0x1078, 0x2052,
- 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x127e, 0x2091, 0x2200, 0x2061,
- 0x0100, 0x2071, 0x7700, 0x6024, 0x6026, 0x6033, 0x00ef, 0x60e7,
- 0x0000, 0x60eb, 0x00ef, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043,
- 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x0caf, 0x600f,
- 0x00ff, 0x602b, 0x002f, 0x127f, 0x007c, 0x2001, 0x772d, 0x2003,
- 0x0000, 0x2001, 0x772c, 0x2003, 0x0001, 0x007c, 0x127e, 0x2091,
- 0x2200, 0x007e, 0x017e, 0x027e, 0x6124, 0xa184, 0x002c, 0x00c0,
- 0x1e6d, 0xa184, 0x0007, 0x0079, 0x1e73, 0xa195, 0x0004, 0xa284,
- 0x0007, 0x0079, 0x1e73, 0x1e9f, 0x1e7b, 0x1e7f, 0x1e83, 0x1e89,
- 0x1e8d, 0x1e93, 0x1e99, 0x1078, 0x4802, 0x0078, 0x1e9f, 0x1078,
- 0x48f1, 0x0078, 0x1e9f, 0x1078, 0x48f1, 0x1078, 0x4802, 0x0078,
- 0x1e9f, 0x1078, 0x1ea4, 0x0078, 0x1e9f, 0x1078, 0x4802, 0x1078,
- 0x1ea4, 0x0078, 0x1e9f, 0x1078, 0x48f1, 0x1078, 0x1ea4, 0x0078,
- 0x1e9f, 0x1078, 0x48f1, 0x1078, 0x4802, 0x1078, 0x1ea4, 0x027f,
- 0x017f, 0x007f, 0x127f, 0x007c, 0xd1ac, 0x0040, 0x1f58, 0x017e,
- 0x047e, 0x0c7e, 0x644c, 0x74ba, 0xa48c, 0xff00, 0xa196, 0xff00,
- 0x0040, 0x1ed3, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa116, 0x0040,
- 0x1ed3, 0x7130, 0xd18c, 0x00c0, 0x1ed3, 0x2011, 0x7752, 0x2214,
- 0xd2ec, 0x0040, 0x1ec7, 0xc18d, 0x7132, 0x0078, 0x1ed3, 0x6240,
- 0xa294, 0x0010, 0x0040, 0x1f15, 0x6248, 0xa294, 0xff00, 0xa296,
- 0xff00, 0x00c0, 0x1f15, 0x037e, 0x73b8, 0x2011, 0x8013, 0x1078,
- 0x2d59, 0x037f, 0x7130, 0xc185, 0x7132, 0x2011, 0x7752, 0x220c,
- 0xd1a4, 0x0040, 0x1efd, 0x017e, 0x2009, 0x0001, 0x2011, 0x0100,
- 0x1078, 0x47d0, 0x2019, 0x000e, 0x1078, 0x75d9, 0xa484, 0x00ff,
- 0xa080, 0x2329, 0x200c, 0xa18c, 0xff00, 0x810f, 0x8127, 0xa006,
- 0x2009, 0x000e, 0x1078, 0x7641, 0x017f, 0xd1ac, 0x00c0, 0x1f06,
- 0x2019, 0x0004, 0x1078, 0x2293, 0x0078, 0x1f15, 0x157e, 0x20a9,
- 0x007f, 0x2009, 0x0000, 0x1078, 0x384c, 0x00c0, 0x1f11, 0x1078,
- 0x3637, 0x8108, 0x00f0, 0x1f0b, 0x157f, 0x0c7f, 0x047f, 0x6043,
- 0x0000, 0x2009, 0x00f7, 0x1078, 0x35fa, 0x0f7e, 0x2079, 0x7949,
- 0x783c, 0xa086, 0x0000, 0x0040, 0x1f2d, 0x6027, 0x0004, 0x783f,
- 0x0000, 0x2079, 0x0140, 0x7803, 0x0000, 0x0f7f, 0x2011, 0x0003,
- 0x1078, 0x58d8, 0x2011, 0x0002, 0x1078, 0x58e2, 0x1078, 0x57ee,
- 0x1078, 0x4706, 0x037e, 0x2019, 0x0000, 0x1078, 0x5880, 0x037f,
- 0x60e3, 0x0000, 0x017f, 0x2001, 0x7700, 0x2014, 0xa296, 0x0004,
- 0x00c0, 0x1f50, 0xd19c, 0x00c0, 0x1f50, 0x6228, 0xc29d, 0x622a,
- 0x2003, 0x0001, 0x2001, 0x7720, 0x2003, 0x0000, 0x6027, 0x0020,
- 0xd194, 0x0040, 0x1ff9, 0x0f7e, 0x2079, 0x7949, 0x783c, 0xa086,
- 0x0001, 0x00c0, 0x1f7c, 0x017e, 0x6027, 0x0004, 0x783f, 0x0000,
- 0x2079, 0x0140, 0x7803, 0x1000, 0x7803, 0x0000, 0x2079, 0x7936,
- 0x7807, 0x0000, 0x7833, 0x0000, 0x1078, 0x4d96, 0x1078, 0x4e56,
- 0x017f, 0x0f7f, 0x0078, 0x1ff9, 0x0f7f, 0x017e, 0x6220, 0xd2b4,
- 0x0040, 0x1fb1, 0x1078, 0x4706, 0x1078, 0x569c, 0x6027, 0x0004,
- 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0040, 0x1f94,
- 0x6803, 0x1000, 0x6803, 0x0000, 0x0d7f, 0x0c7e, 0x2061, 0x7936,
- 0x6028, 0xa09a, 0x0002, 0x00c8, 0x1fa4, 0x8000, 0x602a, 0x0c7f,
- 0x1078, 0x568e, 0x0078, 0x1ff8, 0x2019, 0x793f, 0x2304, 0xa065,
- 0x0040, 0x1fae, 0x2009, 0x0027, 0x1078, 0x5d41, 0x0c7f, 0x0078,
- 0x1ff8, 0xd2bc, 0x0040, 0x1ff8, 0x1078, 0x4714, 0x6017, 0x0010,
- 0x6027, 0x0004, 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000,
- 0x0040, 0x1fc6, 0x6803, 0x1000, 0x6803, 0x0000, 0x0d7f, 0x0c7e,
- 0x2061, 0x7936, 0x6044, 0xa09a, 0x0002, 0x00c8, 0x1fe7, 0x8000,
- 0x6046, 0x603c, 0x0c7f, 0xa005, 0x0040, 0x1ff8, 0x1078, 0x470b,
- 0xa080, 0x0007, 0x2004, 0xa086, 0x0006, 0x00c0, 0x1fe3, 0x6017,
- 0x0012, 0x0078, 0x1ff8, 0x6017, 0x0016, 0x0078, 0x1ff8, 0x037e,
- 0x2019, 0x0001, 0x1078, 0x5880, 0x037f, 0x2019, 0x7945, 0x2304,
- 0xa065, 0x0040, 0x1ff7, 0x2009, 0x004f, 0x1078, 0x5d41, 0x0c7f,
- 0x017f, 0xd19c, 0x0040, 0x2021, 0x017e, 0x6028, 0xc09c, 0x602a,
- 0x2011, 0x0003, 0x1078, 0x58d8, 0x2011, 0x0002, 0x1078, 0x58e2,
- 0x1078, 0x57ee, 0x1078, 0x4706, 0x037e, 0x2019, 0x0000, 0x1078,
- 0x5880, 0x037f, 0x60e3, 0x0000, 0x1078, 0x76b0, 0x1078, 0x76ce,
- 0x2001, 0x7700, 0x2003, 0x0004, 0x6027, 0x0008, 0x1078, 0x11be,
- 0x017f, 0xa18c, 0xffd0, 0x6126, 0x007c, 0x007e, 0x017e, 0x027e,
- 0x0e7e, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2071, 0x7700, 0x71b0,
- 0x70b2, 0xa116, 0x0040, 0x204b, 0x81ff, 0x0040, 0x203d, 0x2011,
- 0x8011, 0x1078, 0x2d59, 0x0078, 0x204b, 0x2011, 0x8012, 0x1078,
- 0x2d59, 0x037e, 0x0c7e, 0x2061, 0x0100, 0x2019, 0x0028, 0x1078,
- 0x2293, 0x0c7f, 0x037f, 0x127f, 0x0f7f, 0x0e7f, 0x027f, 0x017f,
- 0x007f, 0x007c, 0x0c7e, 0x0f7e, 0x007e, 0x027e, 0x2061, 0x0100,
- 0xa190, 0x206d, 0x2204, 0x60f2, 0xa192, 0x0005, 0x00c8, 0x2064,
- 0xa190, 0x2076, 0x0078, 0x2066, 0x2011, 0x207a, 0x2204, 0x60ee,
- 0x027f, 0x007f, 0x0f7f, 0x0c7f, 0x007c, 0x0840, 0x0840, 0x0840,
- 0x0580, 0x0420, 0x0348, 0x02c0, 0x0258, 0x0210, 0x01a8, 0x01a8,
- 0x01a8, 0x01a8, 0x0140, 0x00f8, 0x00d0, 0x00b0, 0x00a0, 0x2028,
- 0x2130, 0xa094, 0xff00, 0x00c0, 0x2088, 0x81ff, 0x0040, 0x208c,
- 0x1078, 0x444b, 0x0078, 0x2093, 0xa080, 0x2329, 0x200c, 0xa18c,
- 0xff00, 0x810f, 0xa006, 0x007c, 0xa080, 0x2329, 0x200c, 0xa18c,
- 0x00ff, 0x007c, 0x20ba, 0x20be, 0x20c2, 0x20c8, 0x20ce, 0x20d4,
- 0x20da, 0x20e2, 0x20ea, 0x20f0, 0x20f6, 0x20fe, 0x2106, 0x210e,
- 0x2116, 0x2120, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a,
- 0x212a, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a, 0x212a,
- 0x212a, 0x212a, 0x107e, 0x007e, 0x0078, 0x2143, 0x107e, 0x007e,
- 0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1e5e, 0x0078, 0x2143,
- 0x107e, 0x007e, 0x1078, 0x1e5e, 0x0078, 0x2143, 0x107e, 0x007e,
- 0x1078, 0x1d45, 0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1d45,
- 0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1e5e, 0x1078, 0x1d45,
- 0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1e5e, 0x1078, 0x1d45,
- 0x0078, 0x2143, 0x107e, 0x007e, 0x1078, 0x1d8a, 0x0078, 0x2143,
- 0x107e, 0x007e, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e,
- 0x1078, 0x1e5e, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e,
- 0x1078, 0x1e5e, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e,
- 0x1078, 0x1d45, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e,
- 0x1078, 0x1d45, 0x1078, 0x1d8a, 0x0078, 0x2143, 0x107e, 0x007e,
- 0x1078, 0x1e5e, 0x1078, 0x1d45, 0x1078, 0x1d8a, 0x0078, 0x2143,
- 0x107e, 0x007e, 0x1078, 0x1e5e, 0x1078, 0x1d45, 0x1078, 0x1d8a,
- 0x0078, 0x2143, 0x0005, 0x0078, 0x212a, 0xb084, 0x003c, 0x8004,
- 0x8004, 0x0079, 0x2133, 0x2143, 0x20c0, 0x20c4, 0x20ca, 0x20d0,
- 0x20d6, 0x20dc, 0x20e4, 0x20ec, 0x20f2, 0x20f8, 0x2100, 0x2108,
- 0x2110, 0x2118, 0x2122, 0x0008, 0x212d, 0x007f, 0x107f, 0x2091,
- 0x8001, 0x007c, 0x0c7e, 0x027e, 0x2041, 0x007e, 0x70bc, 0xd09c,
- 0x0040, 0x2154, 0x2041, 0x007f, 0x2001, 0x010c, 0x203c, 0x727c,
- 0x82ff, 0x0040, 0x219f, 0x037e, 0x738c, 0xa38e, 0xffff, 0x00c0,
- 0x2163, 0x2019, 0x0001, 0x8314, 0xa2e0, 0x7dc0, 0x2c04, 0xa38c,
- 0x0001, 0x0040, 0x2170, 0xa084, 0xff00, 0x8007, 0x0078, 0x2172,
- 0xa084, 0x00ff, 0xa70e, 0x0040, 0x2194, 0xa08e, 0x00ff, 0x0040,
- 0x219a, 0x2009, 0x0000, 0x1078, 0x207f, 0x1078, 0x3811, 0x00c0,
- 0x2197, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x218e,
- 0x1078, 0x21f1, 0x0040, 0x2197, 0x0078, 0x2194, 0x1078, 0x22f5,
- 0x1078, 0x2218, 0x0040, 0x2197, 0x8318, 0x0078, 0x2163, 0x738e,
- 0x0078, 0x219c, 0x708f, 0xffff, 0x037f, 0x0078, 0x21ee, 0xa780,
- 0x2329, 0x203c, 0xa7bc, 0xff00, 0x873f, 0x708c, 0xa096, 0xffff,
- 0x0040, 0x21b1, 0xa812, 0x00c8, 0x21c1, 0x708f, 0xffff, 0x0078,
- 0x21eb, 0x2009, 0x0000, 0x70bc, 0xd09c, 0x0040, 0x21bc, 0xd094,
- 0x0040, 0x21bc, 0x2009, 0x007e, 0x2100, 0xa802, 0x20a8, 0x0078,
- 0x21c5, 0x2008, 0x2810, 0xa202, 0x20a8, 0x2700, 0x157e, 0x017e,
- 0xa106, 0x0040, 0x21e2, 0x1078, 0x3811, 0x00c0, 0x21eb, 0x6004,
- 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x21dc, 0x1078, 0x21f1,
- 0x0040, 0x21eb, 0x0078, 0x21e2, 0x1078, 0x22f5, 0x1078, 0x2218,
- 0x0040, 0x21eb, 0x017f, 0x8108, 0x157f, 0x00f0, 0x21c5, 0x708f,
- 0xffff, 0x0078, 0x21ee, 0x017f, 0x157f, 0x718e, 0x027f, 0x0c7f,
- 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x1078, 0x5cb4,
- 0x0040, 0x2213, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000,
- 0x1078, 0x37e0, 0x2001, 0x0000, 0x1078, 0x37f4, 0x127e, 0x2091,
- 0x8000, 0x7088, 0x8000, 0x708a, 0x127f, 0x2009, 0x0004, 0x1078,
- 0x5d41, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, 0x007c,
- 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x1078, 0x5cb4, 0x0040,
- 0x223a, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078,
- 0x37e0, 0x2001, 0x0002, 0x1078, 0x37f4, 0x127e, 0x2091, 0x8000,
- 0x7088, 0x8000, 0x708a, 0x127f, 0x2009, 0x0002, 0x1078, 0x5d41,
- 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, 0x007c, 0x0c7e,
- 0x027e, 0x2009, 0x0080, 0x1078, 0x3811, 0x00c0, 0x224d, 0x1078,
- 0x2250, 0x0040, 0x224d, 0x70c3, 0xffff, 0x027f, 0x0c7f, 0x007c,
- 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x1078, 0x5cb4, 0x0040,
- 0x2272, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078,
- 0x37e0, 0x2001, 0x0002, 0x1078, 0x37f4, 0x127e, 0x2091, 0x8000,
- 0x70c4, 0x8000, 0x70c6, 0x127f, 0x2009, 0x0002, 0x1078, 0x5d41,
- 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f, 0x007c, 0x0c7e,
- 0x0d7e, 0x2009, 0x007f, 0x1078, 0x3811, 0x00c0, 0x2290, 0x2c68,
- 0x1078, 0x5cb4, 0x0040, 0x2290, 0x2d00, 0x601a, 0x6312, 0x601f,
- 0x0001, 0x620a, 0x2009, 0x0022, 0x1078, 0x5d41, 0xa085, 0x0001,
- 0x0d7f, 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x067e, 0x037e, 0x027e,
- 0x1078, 0x4a85, 0x1078, 0x4a35, 0x1078, 0x6219, 0x20a9, 0x007f,
- 0x2009, 0x0000, 0x017e, 0x1078, 0x384c, 0x00c0, 0x22ab, 0x1078,
- 0x3a36, 0x1078, 0x3637, 0x017f, 0x8108, 0x00f0, 0x22a2, 0x027f,
- 0x037f, 0x067f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, 0x037e,
- 0x027e, 0x017e, 0x6218, 0x2270, 0x72a0, 0x027e, 0x2019, 0x0029,
- 0x1078, 0x4a7e, 0x1078, 0x49c1, 0x2c08, 0x1078, 0x747b, 0x017f,
- 0x2e60, 0x1078, 0x3a36, 0x6210, 0x6314, 0x1078, 0x3637, 0x6212,
- 0x6316, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e,
- 0x007e, 0x6018, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x00c0, 0x22eb,
- 0x2071, 0x7700, 0x7088, 0xa005, 0x0040, 0x22e8, 0x8001, 0x708a,
- 0x007f, 0x0e7f, 0x007c, 0x2071, 0x7700, 0x70c4, 0xa005, 0x0040,
- 0x22e8, 0x8001, 0x70c6, 0x0078, 0x22e8, 0x6000, 0xc08c, 0x6002,
- 0x007c, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x157e, 0x81ff,
- 0x00c0, 0x2306, 0x20a9, 0x0001, 0x0078, 0x230a, 0x20a9, 0x007f,
- 0x2011, 0x0000, 0x027e, 0xa2e0, 0x7820, 0x2c64, 0x8cff, 0x0040,
- 0x231c, 0x2019, 0x0029, 0x1078, 0x4a7e, 0x1078, 0x49c1, 0x2c08,
- 0x1078, 0x747b, 0x1078, 0x3a36, 0x027f, 0x8210, 0x00f0, 0x230a,
- 0x027e, 0x027f, 0x157f, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f,
- 0x007c, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc,
- 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1,
- 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6,
- 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4,
- 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa,
- 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d,
- 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282,
- 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074,
- 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a,
- 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559,
- 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d,
- 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043,
- 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932,
- 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227,
- 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18,
- 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000,
- 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000,
- 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00,
- 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900,
- 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200,
- 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00,
- 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000,
- 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600,
- 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00,
- 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900,
- 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000,
- 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000,
- 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x6908, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0007, 0x0040, 0x1bc9,
+ 0xa184, 0x0007, 0x0040, 0x1bc9, 0x017e, 0x2009, 0x0008, 0xa102,
+ 0x017f, 0xa108, 0x791a, 0x7116, 0x701e, 0x680c, 0xa081, 0x0000,
+ 0x781e, 0x701a, 0xa006, 0x700e, 0x7012, 0x7004, 0x692c, 0x6814,
+ 0xa106, 0x00c0, 0x1be0, 0x6928, 0x6810, 0xa106, 0x0040, 0x1bed,
+ 0x037e, 0x047e, 0x6b14, 0x6c10, 0x1078, 0x1e0f, 0x047f, 0x037f,
+ 0x0040, 0x1bed, 0x0c7f, 0x0078, 0x1c07, 0x8aff, 0x00c0, 0x1bf5,
+ 0x0c7f, 0xa085, 0x0001, 0x0078, 0x1c07, 0x127e, 0x2091, 0x8000,
+ 0x2079, 0x0020, 0x2009, 0x0001, 0x1078, 0x1c0b, 0x0040, 0x1c04,
+ 0x2009, 0x0001, 0x1078, 0x1c0b, 0x127f, 0x0c7f, 0xa006, 0x0d7f,
+ 0x0e7f, 0x0f7f, 0x007c, 0x077e, 0x067e, 0x057e, 0x047e, 0x037e,
+ 0x027e, 0x8aff, 0x0040, 0x1c89, 0x700c, 0x7214, 0xa23a, 0x7010,
+ 0x7218, 0xa203, 0x0048, 0x1c88, 0xa705, 0x0040, 0x1c88, 0xa03e,
+ 0x2730, 0x6850, 0xd0fc, 0x00c0, 0x1c3b, 0x0d7e, 0x2804, 0xac68,
+ 0x2900, 0x0079, 0x1c2b, 0x1c6a, 0x1c4b, 0x1c4b, 0x1c6a, 0x1c6a,
+ 0x1c62, 0x1c6a, 0x1c4b, 0x1c6a, 0x1c51, 0x1c51, 0x1c6a, 0x1c6a,
+ 0x1c6a, 0x1c59, 0x1c51, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c,
+ 0x6c20, 0xd99c, 0x0040, 0x1c6e, 0x0d7e, 0x2804, 0xac68, 0x6f08,
+ 0x6e0c, 0x0078, 0x1c6d, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0078,
+ 0x1c6d, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0078,
+ 0x1c6d, 0x0d7f, 0x0d7e, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e,
+ 0x00c0, 0x1c6a, 0x0d7f, 0x1078, 0x1dab, 0x00c0, 0x1c11, 0xa00e,
+ 0x0078, 0x1c89, 0x0d7f, 0x1078, 0x12d2, 0x0d7f, 0x7b22, 0x7a26,
+ 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002,
+ 0x6828, 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x700c, 0xa300,
+ 0x700e, 0x7010, 0xa201, 0x7012, 0x1078, 0x1dab, 0x0078, 0x1c89,
+ 0xa006, 0x027f, 0x037f, 0x047f, 0x057f, 0x067f, 0x077f, 0x007c,
+ 0x1078, 0x12d2, 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040,
+ 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x0d7e, 0x6010,
+ 0x2068, 0x1078, 0x77ed, 0x0040, 0x1ca8, 0x6850, 0xc0bd, 0x6852,
+ 0x0d7f, 0x1078, 0x759a, 0x20e1, 0x9040, 0x1078, 0x6753, 0x2011,
+ 0x0000, 0x1078, 0x64b8, 0x1078, 0x5948, 0x0078, 0x1d7c, 0x127e,
+ 0x2091, 0x2200, 0x007e, 0x017e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e,
+ 0x2079, 0x0020, 0x2071, 0x8af9, 0x2b68, 0x6818, 0x2060, 0x7904,
+ 0x7803, 0x0002, 0xa184, 0x0700, 0x00c0, 0x1c92, 0x7000, 0x0079,
+ 0x1cd1, 0x1d7c, 0x1cd5, 0x1d49, 0x1d7a, 0x8001, 0x7002, 0xd19c,
+ 0x00c0, 0x1ce9, 0x8aff, 0x0040, 0x1d08, 0x2009, 0x0001, 0x1078,
+ 0x1c0b, 0x0040, 0x1d7c, 0x2009, 0x0001, 0x1078, 0x1c0b, 0x0078,
+ 0x1d7c, 0x7803, 0x0004, 0xd194, 0x0040, 0x1cf9, 0x6850, 0xc0fc,
+ 0x6852, 0x8aff, 0x00c0, 0x1cfe, 0x684c, 0xc0f5, 0x684e, 0x0078,
+ 0x1cfe, 0x1078, 0x1dc4, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826,
+ 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000, 0x0078, 0x1d7c,
+ 0x711c, 0x81ff, 0x0040, 0x1d1e, 0x7918, 0x7922, 0x7827, 0x0000,
+ 0x7803, 0x0001, 0x7000, 0x8000, 0x7002, 0x700c, 0xa100, 0x700e,
+ 0x7010, 0xa081, 0x0000, 0x7012, 0x0078, 0x1d7c, 0x0f7e, 0x027e,
+ 0x781c, 0x007e, 0x7818, 0x007e, 0x2079, 0x0100, 0x7a14, 0xa284,
+ 0x0004, 0xa085, 0x0012, 0x7816, 0x7820, 0xd0bc, 0x00c0, 0x1d2c,
+ 0x79c8, 0x007f, 0xa102, 0x017f, 0x007e, 0x017e, 0x79c4, 0x007f,
+ 0xa102, 0x78c6, 0x007f, 0x78ca, 0xa284, 0x0004, 0xa085, 0x0012,
+ 0x7816, 0x027f, 0x0f7f, 0x7803, 0x0008, 0x7003, 0x0000, 0x0078,
+ 0x1d7c, 0x8001, 0x7002, 0xd194, 0x0040, 0x1d5e, 0x7804, 0xd0fc,
+ 0x00c0, 0x1cc7, 0xd19c, 0x00c0, 0x1d78, 0x8aff, 0x0040, 0x1d7c,
+ 0x2009, 0x0001, 0x1078, 0x1c0b, 0x0078, 0x1d7c, 0x027e, 0x037e,
+ 0x6b28, 0x6a2c, 0x1078, 0x1dc4, 0x0d7e, 0x2804, 0xac68, 0x6034,
+ 0xd09c, 0x00c0, 0x1d71, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0078,
+ 0x1d75, 0x6810, 0xa31a, 0x6814, 0xa213, 0x0d7f, 0x0078, 0x1cf9,
+ 0x0078, 0x1cf9, 0x1078, 0x12d2, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
+ 0x017f, 0x007f, 0x127f, 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0x8af9,
+ 0x7000, 0xa086, 0x0000, 0x0040, 0x1da8, 0x2079, 0x0020, 0x20e1,
+ 0x9040, 0x7804, 0xd0fc, 0x0040, 0x1d8f, 0x1078, 0x1cb7, 0x7000,
+ 0xa086, 0x0000, 0x00c0, 0x1d8f, 0x7803, 0x0004, 0x7804, 0xd0ac,
+ 0x00c0, 0x1d9e, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000,
+ 0x0e7f, 0x0f7f, 0x007c, 0x8840, 0x2804, 0xa005, 0x00c0, 0x1dbf,
+ 0x6004, 0xa005, 0x0040, 0x1dc1, 0x681a, 0x2060, 0x6034, 0xa084,
+ 0x000f, 0xa080, 0x1def, 0x2044, 0x88ff, 0x1040, 0x12d2, 0x8a51,
+ 0x007c, 0x2051, 0x0000, 0x007c, 0x8a50, 0x8841, 0x2804, 0xa005,
+ 0x00c0, 0x1dde, 0x2c00, 0xad06, 0x0040, 0x1dd3, 0x6000, 0xa005,
+ 0x00c0, 0x1dd3, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f,
+ 0xa080, 0x1dff, 0x2044, 0x88ff, 0x1040, 0x12d2, 0x007c, 0x0000,
+ 0x0011, 0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000,
+ 0x000f, 0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000,
+ 0x1de4, 0x1de0, 0x0000, 0x0000, 0x1dee, 0x0000, 0x1de4, 0x0000,
+ 0x1deb, 0x1de8, 0x0000, 0x0000, 0x0000, 0x1dee, 0x1deb, 0x0000,
+ 0x1de6, 0x1de6, 0x0000, 0x0000, 0x1dee, 0x0000, 0x1de6, 0x0000,
+ 0x1dec, 0x1dec, 0x0000, 0x0000, 0x0000, 0x1dee, 0x1dec, 0x0a7e,
+ 0x097e, 0x087e, 0x6858, 0xa055, 0x0040, 0x1eb0, 0x2d60, 0x6034,
+ 0xa0cc, 0x000f, 0xa9c0, 0x1def, 0xa986, 0x0007, 0x0040, 0x1e28,
+ 0xa986, 0x000e, 0x0040, 0x1e28, 0xa986, 0x000f, 0x00c0, 0x1e2c,
+ 0x605c, 0xa422, 0x6060, 0xa31a, 0x2804, 0xa045, 0x00c0, 0x1e3a,
+ 0x0050, 0x1e34, 0x0078, 0x1eb0, 0x6004, 0xa065, 0x0040, 0x1eb0,
+ 0x0078, 0x1e17, 0x2804, 0xa005, 0x0040, 0x1e58, 0xac68, 0xd99c,
+ 0x00c0, 0x1e48, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0078, 0x1e4c,
+ 0x6810, 0xa422, 0x6814, 0xa31b, 0x0048, 0x1e77, 0x2300, 0xa405,
+ 0x0040, 0x1e5e, 0x8a51, 0x0040, 0x1eb0, 0x8840, 0x0078, 0x1e3a,
+ 0x6004, 0xa065, 0x0040, 0x1eb0, 0x0078, 0x1e17, 0x8a51, 0x0040,
+ 0x1eb0, 0x8840, 0x2804, 0xa005, 0x00c0, 0x1e71, 0x6004, 0xa065,
+ 0x0040, 0x1eb0, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x1def, 0x2804,
+ 0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0078, 0x1ea4, 0x8422,
+ 0x8420, 0x831a, 0xa399, 0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72,
+ 0x0d7f, 0xd99c, 0x00c0, 0x1e92, 0x6908, 0x2400, 0xa122, 0x690c,
+ 0x2300, 0xa11b, 0x1048, 0x12d2, 0x6800, 0xa420, 0x6804, 0xa319,
+ 0x0078, 0x1e9e, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b,
+ 0x1048, 0x12d2, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e,
+ 0x6b22, 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832,
+ 0x2a00, 0x6826, 0x007f, 0x007f, 0x007f, 0xa006, 0x0078, 0x1eb5,
+ 0x087f, 0x097f, 0x0a7f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0005,
+ 0x2004, 0xa084, 0x0007, 0x0079, 0x1ebd, 0x1ec5, 0x1ec6, 0x1ec9,
+ 0x1ecc, 0x1ed1, 0x1ed4, 0x1ed9, 0x1ede, 0x007c, 0x1078, 0x1cb7,
+ 0x007c, 0x1078, 0x1816, 0x007c, 0x1078, 0x1816, 0x1078, 0x1cb7,
+ 0x007c, 0x1078, 0x145a, 0x007c, 0x1078, 0x1cb7, 0x1078, 0x145a,
+ 0x007c, 0x1078, 0x1816, 0x1078, 0x145a, 0x007c, 0x1078, 0x1816,
+ 0x1078, 0x1cb7, 0x1078, 0x145a, 0x007c, 0x127e, 0x2091, 0x2300,
+ 0x2079, 0x0200, 0x2071, 0x8d80, 0x2069, 0x8800, 0x2009, 0x0004,
+ 0x7912, 0x7817, 0x0004, 0x1078, 0x2220, 0x781b, 0x0002, 0x20e1,
+ 0x8700, 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x781c, 0xa084,
+ 0x0007, 0x0079, 0x1f03, 0x1f27, 0x1f0b, 0x1f0f, 0x1f13, 0x1f19,
+ 0x1f1d, 0x1f21, 0x1f25, 0x1078, 0x4cc0, 0x0078, 0x1f27, 0x1078,
+ 0x4cef, 0x0078, 0x1f27, 0x1078, 0x4cc0, 0x1078, 0x4cef, 0x0078,
+ 0x1f27, 0x1078, 0x1f29, 0x0078, 0x1f27, 0x1078, 0x1f29, 0x0078,
+ 0x1f27, 0x1078, 0x1f29, 0x0078, 0x1f27, 0x1078, 0x1f29, 0x127f,
+ 0x007c, 0x007e, 0x017e, 0x027e, 0x7930, 0xa184, 0x0003, 0x0040,
+ 0x1f35, 0x20e1, 0x9040, 0x0078, 0x1f52, 0xa184, 0x0030, 0x0040,
+ 0x1f46, 0x6a00, 0xa286, 0x0003, 0x00c0, 0x1f40, 0x0078, 0x1f42,
+ 0x1078, 0x3c73, 0x20e1, 0x9010, 0x0078, 0x1f52, 0xa184, 0x00c0,
+ 0x0040, 0x1f4c, 0x1078, 0x12d2, 0xa184, 0x0300, 0x0040, 0x1f52,
+ 0x20e1, 0x9020, 0x7932, 0x027f, 0x017f, 0x007f, 0x007c, 0x017e,
+ 0x0e7e, 0x0f7e, 0x2071, 0x8800, 0x7128, 0x2001, 0x8a8f, 0x2102,
+ 0x2001, 0x8a97, 0x2102, 0xa182, 0x0211, 0x00c8, 0x1f6b, 0x2009,
+ 0x0008, 0x0078, 0x1f95, 0xa182, 0x0259, 0x00c8, 0x1f73, 0x2009,
+ 0x0007, 0x0078, 0x1f95, 0xa182, 0x02c1, 0x00c8, 0x1f7b, 0x2009,
+ 0x0006, 0x0078, 0x1f95, 0xa182, 0x0349, 0x00c8, 0x1f83, 0x2009,
+ 0x0005, 0x0078, 0x1f95, 0xa182, 0x0421, 0x00c8, 0x1f8b, 0x2009,
+ 0x0004, 0x0078, 0x1f95, 0xa182, 0x0581, 0x00c8, 0x1f93, 0x2009,
+ 0x0003, 0x0078, 0x1f95, 0x2009, 0x0002, 0x2079, 0x0200, 0x7912,
+ 0x7817, 0x0004, 0x1078, 0x2220, 0x0f7f, 0x0e7f, 0x017f, 0x007c,
+ 0x127e, 0x2091, 0x2200, 0x2061, 0x0100, 0x2071, 0x8800, 0x6024,
+ 0x6026, 0x6053, 0x0030, 0x6033, 0x00ef, 0x60e7, 0x0000, 0x60eb,
+ 0x00ef, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f,
+ 0x0080, 0x602f, 0x0000, 0x6007, 0x0eaf, 0x600f, 0x00ff, 0x602b,
+ 0x002f, 0x127f, 0x007c, 0x2001, 0x882e, 0x2003, 0x0000, 0x2001,
+ 0x882d, 0x2003, 0x0001, 0x007c, 0x127e, 0x2091, 0x2200, 0x007e,
+ 0x017e, 0x027e, 0x6124, 0xa184, 0x002c, 0x00c0, 0x1fdb, 0xa184,
+ 0x0007, 0x0079, 0x1fe1, 0xa195, 0x0004, 0xa284, 0x0007, 0x0079,
+ 0x1fe1, 0x200d, 0x1fe9, 0x1fed, 0x1ff1, 0x1ff7, 0x1ffb, 0x2001,
+ 0x2007, 0x1078, 0x5273, 0x0078, 0x200d, 0x1078, 0x5362, 0x0078,
+ 0x200d, 0x1078, 0x5362, 0x1078, 0x5273, 0x0078, 0x200d, 0x1078,
+ 0x2012, 0x0078, 0x200d, 0x1078, 0x5273, 0x1078, 0x2012, 0x0078,
+ 0x200d, 0x1078, 0x5362, 0x1078, 0x2012, 0x0078, 0x200d, 0x1078,
+ 0x5362, 0x1078, 0x5273, 0x1078, 0x2012, 0x027f, 0x017f, 0x007f,
+ 0x127f, 0x007c, 0xd1ac, 0x0040, 0x20ec, 0x017e, 0x047e, 0x0c7e,
+ 0x644c, 0xa486, 0xf0f0, 0x00c0, 0x2024, 0x2061, 0x0100, 0x644a,
+ 0x6043, 0x0090, 0x6043, 0x0010, 0x74be, 0xa48c, 0xff00, 0x7034,
+ 0xd084, 0x0040, 0x203c, 0xa186, 0xf800, 0x00c0, 0x203c, 0x7038,
+ 0xd084, 0x00c0, 0x203c, 0xc085, 0x703a, 0x037e, 0x2418, 0x2011,
+ 0x8016, 0x1078, 0x317a, 0x037f, 0xa196, 0xff00, 0x0040, 0x2061,
+ 0x6030, 0xa084, 0x00ff, 0x810f, 0xa116, 0x0040, 0x2061, 0x7130,
+ 0xd18c, 0x00c0, 0x2061, 0x2011, 0x8852, 0x2214, 0xd2ec, 0x0040,
+ 0x2055, 0xc18d, 0x7132, 0x0078, 0x2061, 0x6240, 0xa294, 0x0010,
+ 0x0040, 0x20af, 0x6248, 0xa294, 0xff00, 0xa296, 0xff00, 0x00c0,
+ 0x20af, 0x7034, 0xd08c, 0x00c0, 0x206d, 0x2001, 0x880c, 0x200c,
+ 0xd1ac, 0x00c0, 0x20af, 0xc1ad, 0x2102, 0x037e, 0x73bc, 0x2011,
+ 0x8013, 0x1078, 0x317a, 0x037f, 0x7130, 0xc185, 0x7132, 0x2011,
+ 0x8852, 0x220c, 0xd1a4, 0x0040, 0x2097, 0x017e, 0x2009, 0x0001,
+ 0x2011, 0x0100, 0x1078, 0x5243, 0x2019, 0x000e, 0x1078, 0x8683,
+ 0xa484, 0x00ff, 0xa080, 0x25b2, 0x200c, 0xa18c, 0xff00, 0x810f,
+ 0x8127, 0xa006, 0x2009, 0x000e, 0x1078, 0x86f5, 0x017f, 0xd1ac,
+ 0x00c0, 0x20a0, 0x2019, 0x0004, 0x1078, 0x249d, 0x0078, 0x20af,
+ 0x157e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x1078, 0x3f8e, 0x00c0,
+ 0x20ab, 0x1078, 0x3d31, 0x8108, 0x00f0, 0x20a5, 0x157f, 0x0c7f,
+ 0x047f, 0x0f7e, 0x2079, 0x8ab5, 0x783c, 0xa086, 0x0000, 0x0040,
+ 0x20c1, 0x6027, 0x0004, 0x783f, 0x0000, 0x2079, 0x0140, 0x7803,
+ 0x0000, 0x0f7f, 0x2011, 0x0003, 0x1078, 0x64ae, 0x2011, 0x0002,
+ 0x1078, 0x64b8, 0x1078, 0x639b, 0x1078, 0x516f, 0x037e, 0x2019,
+ 0x0000, 0x1078, 0x642d, 0x037f, 0x60e3, 0x0000, 0x017f, 0x2001,
+ 0x8800, 0x2014, 0xa296, 0x0004, 0x00c0, 0x20e4, 0xd19c, 0x00c0,
+ 0x20e4, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0x8821,
+ 0x2003, 0x0000, 0x6027, 0x0020, 0xd194, 0x0040, 0x21c7, 0x0f7e,
+ 0x2079, 0x8ab5, 0x783c, 0xa086, 0x0001, 0x00c0, 0x2110, 0x017e,
+ 0x6027, 0x0004, 0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x1000,
+ 0x7803, 0x0000, 0x2079, 0x8aa2, 0x7807, 0x0000, 0x7833, 0x0000,
+ 0x1078, 0x5888, 0x1078, 0x5948, 0x017f, 0x0f7f, 0x0078, 0x21c7,
+ 0x0f7f, 0x017e, 0x6220, 0xd2b4, 0x0040, 0x217d, 0x1078, 0x516f,
+ 0x1078, 0x6232, 0x6027, 0x0004, 0x0f7e, 0x2019, 0x8aab, 0x2304,
+ 0xa07d, 0x0040, 0x2153, 0x7804, 0xa086, 0x0032, 0x00c0, 0x2153,
+ 0x0d7e, 0x0c7e, 0x0e7e, 0x2069, 0x0140, 0x618c, 0x6288, 0x7818,
+ 0x608e, 0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001,
+ 0x00c0, 0x2137, 0x6043, 0x0000, 0x6803, 0x1000, 0x6803, 0x0000,
+ 0x618e, 0x628a, 0x1078, 0x578f, 0x1078, 0x5888, 0x7810, 0x2070,
+ 0x7037, 0x0103, 0x2f60, 0x1078, 0x690e, 0x0e7f, 0x0c7f, 0x0d7f,
+ 0x0f7f, 0x017f, 0x007c, 0x0f7f, 0x0d7e, 0x2069, 0x0140, 0x6804,
+ 0xa084, 0x4000, 0x0040, 0x2160, 0x6803, 0x1000, 0x6803, 0x0000,
+ 0x0d7f, 0x0c7e, 0x2061, 0x8aa2, 0x6028, 0xa09a, 0x0002, 0x00c8,
+ 0x2170, 0x8000, 0x602a, 0x0c7f, 0x1078, 0x6224, 0x0078, 0x21c6,
+ 0x2019, 0x8aab, 0x2304, 0xa065, 0x0040, 0x217a, 0x2009, 0x0027,
+ 0x1078, 0x6939, 0x0c7f, 0x0078, 0x21c6, 0xd2bc, 0x0040, 0x21c6,
+ 0x1078, 0x517c, 0x6017, 0x0010, 0x6027, 0x0004, 0x0d7e, 0x2069,
+ 0x0140, 0x6804, 0xa084, 0x4000, 0x0040, 0x2192, 0x6803, 0x1000,
+ 0x6803, 0x0000, 0x0d7f, 0x0c7e, 0x2061, 0x8aa2, 0x6044, 0xa09a,
+ 0x0002, 0x00c8, 0x21b5, 0x8000, 0x6046, 0x603c, 0x0c7f, 0xa005,
+ 0x0040, 0x21c6, 0x2009, 0x07d0, 0x1078, 0x5174, 0xa080, 0x0007,
+ 0x2004, 0xa086, 0x0006, 0x00c0, 0x21b1, 0x6017, 0x0012, 0x0078,
+ 0x21c6, 0x6017, 0x0016, 0x0078, 0x21c6, 0x037e, 0x2019, 0x0001,
+ 0x1078, 0x642d, 0x037f, 0x2019, 0x8ab1, 0x2304, 0xa065, 0x0040,
+ 0x21c5, 0x2009, 0x004f, 0x1078, 0x6939, 0x0c7f, 0x017f, 0xd19c,
+ 0x0040, 0x21ef, 0x017e, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003,
+ 0x1078, 0x64ae, 0x2011, 0x0002, 0x1078, 0x64b8, 0x1078, 0x639b,
+ 0x1078, 0x516f, 0x037e, 0x2019, 0x0000, 0x1078, 0x642d, 0x037f,
+ 0x60e3, 0x0000, 0x1078, 0x876a, 0x1078, 0x8788, 0x2001, 0x8800,
+ 0x2003, 0x0004, 0x6027, 0x0008, 0x1078, 0x1208, 0x017f, 0xa18c,
+ 0xffd0, 0x6126, 0x007c, 0x007e, 0x017e, 0x027e, 0x0e7e, 0x0f7e,
+ 0x127e, 0x2091, 0x8000, 0x2071, 0x8800, 0x71b4, 0x70b6, 0xa116,
+ 0x0040, 0x2219, 0x81ff, 0x0040, 0x220b, 0x2011, 0x8011, 0x1078,
+ 0x317a, 0x0078, 0x2219, 0x2011, 0x8012, 0x1078, 0x317a, 0x037e,
+ 0x0c7e, 0x2061, 0x0100, 0x2019, 0x0028, 0x1078, 0x249d, 0x0c7f,
+ 0x037f, 0x127f, 0x0f7f, 0x0e7f, 0x027f, 0x017f, 0x007f, 0x007c,
+ 0x0c7e, 0x0f7e, 0x007e, 0x027e, 0x2061, 0x0100, 0xa190, 0x2233,
+ 0x2204, 0x60f2, 0x2011, 0x2240, 0x2204, 0x60ee, 0x027f, 0x007f,
+ 0x0f7f, 0x0c7f, 0x007c, 0x0840, 0x0840, 0x0840, 0x0580, 0x0420,
+ 0x0348, 0x02c0, 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8,
+ 0x0140, 0x00f8, 0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff,
+ 0x2130, 0xa094, 0xff00, 0x00c0, 0x2250, 0x81ff, 0x0040, 0x2254,
+ 0x1078, 0x4e98, 0x0078, 0x225b, 0xa080, 0x25b2, 0x200c, 0xa18c,
+ 0xff00, 0x810f, 0xa006, 0x007c, 0xa080, 0x25b2, 0x200c, 0xa18c,
+ 0x00ff, 0x007c, 0x0c7e, 0x2061, 0x8800, 0x6030, 0x0040, 0x226b,
+ 0xc09d, 0x0078, 0x226c, 0xc09c, 0x6032, 0x0c7f, 0x007c, 0x228f,
+ 0x2293, 0x2297, 0x229d, 0x22a3, 0x22a9, 0x22af, 0x22b7, 0x22bf,
+ 0x22c5, 0x22cb, 0x22d3, 0x22db, 0x22e3, 0x22eb, 0x22f5, 0x22ff,
+ 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x22ff,
+ 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x22ff, 0x107e,
+ 0x007e, 0x0078, 0x2318, 0x107e, 0x007e, 0x0078, 0x2318, 0x107e,
+ 0x007e, 0x1078, 0x1fcc, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078,
+ 0x1fcc, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, 0x1eb6, 0x0078,
+ 0x2318, 0x107e, 0x007e, 0x1078, 0x1eb6, 0x0078, 0x2318, 0x107e,
+ 0x007e, 0x1078, 0x1fcc, 0x1078, 0x1eb6, 0x0078, 0x2318, 0x107e,
+ 0x007e, 0x1078, 0x1fcc, 0x1078, 0x1eb6, 0x0078, 0x2318, 0x107e,
+ 0x007e, 0x1078, 0x1efb, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078,
+ 0x1efb, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, 0x1fcc, 0x1078,
+ 0x1efb, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, 0x1fcc, 0x1078,
+ 0x1efb, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, 0x1eb6, 0x1078,
+ 0x1efb, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, 0x1eb6, 0x1078,
+ 0x1efb, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078, 0x1fcc, 0x1078,
+ 0x1eb6, 0x1078, 0x1efb, 0x0078, 0x2318, 0x107e, 0x007e, 0x1078,
+ 0x1fcc, 0x1078, 0x1eb6, 0x1078, 0x1efb, 0x0078, 0x2318, 0x0005,
+ 0x0078, 0x22ff, 0xb084, 0x003c, 0x8004, 0x8004, 0x0079, 0x2308,
+ 0x2318, 0x2295, 0x2299, 0x229f, 0x22a5, 0x22ab, 0x22b1, 0x22b9,
+ 0x22c1, 0x22c7, 0x22cd, 0x22d5, 0x22dd, 0x22e5, 0x22ed, 0x22f7,
+ 0x0008, 0x2302, 0x007f, 0x107f, 0x2091, 0x8001, 0x007c, 0x0c7e,
+ 0x027e, 0x2041, 0x007e, 0x70c0, 0xd09c, 0x0040, 0x2329, 0x2041,
+ 0x007f, 0xd094, 0x2001, 0x010c, 0x203c, 0x00c0, 0x2388, 0x7280,
+ 0xd284, 0x0040, 0x2388, 0xd28c, 0x00c0, 0x2388, 0x037e, 0x7390,
+ 0xa38e, 0xffff, 0x00c0, 0x233e, 0x2019, 0x0001, 0x8314, 0xa2e0,
+ 0x8ec0, 0x2c04, 0xa38c, 0x0001, 0x0040, 0x234b, 0xa084, 0xff00,
+ 0x8007, 0x0078, 0x234d, 0xa084, 0x00ff, 0xa70e, 0x0040, 0x237d,
+ 0xa08e, 0x00ff, 0x00c0, 0x2362, 0x2011, 0x8852, 0x2214, 0xd2ec,
+ 0x00c0, 0x2383, 0x7280, 0xc28d, 0x7282, 0x7093, 0xffff, 0x037f,
+ 0x0078, 0x2388, 0x2009, 0x0000, 0x1078, 0x2245, 0x1078, 0x3f53,
+ 0x00c0, 0x2380, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0,
+ 0x2377, 0x1078, 0x23ef, 0x0040, 0x2380, 0x0078, 0x237d, 0x1078,
+ 0x2503, 0x1078, 0x241c, 0x0040, 0x2380, 0x8318, 0x0078, 0x233e,
+ 0x7392, 0x0078, 0x2385, 0x7093, 0xffff, 0x037f, 0x0078, 0x23ec,
+ 0xa780, 0x25b2, 0x203c, 0xa7bc, 0xff00, 0x873f, 0x7090, 0xa096,
+ 0xffff, 0x0040, 0x239a, 0xa812, 0x00c8, 0x23aa, 0x7093, 0xffff,
+ 0x0078, 0x23e9, 0x2009, 0x0000, 0x70c0, 0xd09c, 0x0040, 0x23a5,
+ 0xd094, 0x0040, 0x23a5, 0x2009, 0x007e, 0x2100, 0xa802, 0x20a8,
+ 0x0078, 0x23ae, 0x2008, 0x2810, 0xa202, 0x20a8, 0x2700, 0x157e,
+ 0x017e, 0xa106, 0x0040, 0x23e0, 0x1078, 0x3f53, 0x00c0, 0x23e9,
+ 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x23c5, 0x1078,
+ 0x257d, 0x0040, 0x23e0, 0x0078, 0x23d4, 0x7280, 0xd28c, 0x0040,
+ 0x23da, 0x6004, 0xa084, 0x00ff, 0xa082, 0x0006, 0x0048, 0x23e0,
+ 0x1078, 0x3f76, 0x0078, 0x23e0, 0x1078, 0x23ef, 0x0040, 0x23e9,
+ 0x0078, 0x23e0, 0x1078, 0x2503, 0x1078, 0x241c, 0x0040, 0x23e9,
+ 0x017f, 0x8108, 0x157f, 0x00f0, 0x23ae, 0x7093, 0xffff, 0x0078,
+ 0x23ec, 0x017f, 0x157f, 0x7192, 0x027f, 0x0c7f, 0x007c, 0x017e,
+ 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x2001, 0x8856, 0x2004, 0xa084,
+ 0x00ff, 0x6842, 0x1078, 0x68a8, 0x0040, 0x2417, 0x2d00, 0x601a,
+ 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x3ef1, 0x2001, 0x0000,
+ 0x1078, 0x3f05, 0x127e, 0x2091, 0x8000, 0x708c, 0x8000, 0x708e,
+ 0x127f, 0x2009, 0x0004, 0x1078, 0x6939, 0xa085, 0x0001, 0x0c7f,
+ 0x0d7f, 0x077f, 0x017f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e,
+ 0x2c68, 0x2001, 0x8856, 0x2004, 0xa084, 0x00ff, 0x6842, 0x1078,
+ 0x68a8, 0x0040, 0x2444, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001,
+ 0x0000, 0x1078, 0x3ef1, 0x2001, 0x0002, 0x1078, 0x3f05, 0x127e,
+ 0x2091, 0x8000, 0x708c, 0x8000, 0x708e, 0x127f, 0x2009, 0x0002,
+ 0x1078, 0x6939, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f,
+ 0x007c, 0x0c7e, 0x027e, 0x2009, 0x0080, 0x1078, 0x3f53, 0x00c0,
+ 0x2457, 0x1078, 0x245a, 0x0040, 0x2457, 0x70c7, 0xffff, 0x027f,
+ 0x0c7f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x1078,
+ 0x68a8, 0x0040, 0x247c, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001,
+ 0x0000, 0x1078, 0x3ef1, 0x2001, 0x0002, 0x1078, 0x3f05, 0x127e,
+ 0x2091, 0x8000, 0x70c8, 0x8000, 0x70ca, 0x127f, 0x2009, 0x0002,
+ 0x1078, 0x6939, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f,
+ 0x007c, 0x0c7e, 0x0d7e, 0x2009, 0x007f, 0x1078, 0x3f53, 0x00c0,
+ 0x249a, 0x2c68, 0x1078, 0x68a8, 0x0040, 0x249a, 0x2d00, 0x601a,
+ 0x6312, 0x601f, 0x0001, 0x620a, 0x2009, 0x0022, 0x1078, 0x6939,
+ 0xa085, 0x0001, 0x0d7f, 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x067e,
+ 0x037e, 0x027e, 0x1078, 0x54fd, 0x1078, 0x549f, 0x1078, 0x6ea5,
+ 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x3f8e, 0x00c0,
+ 0x24b5, 0x1078, 0x418b, 0x1078, 0x3d31, 0x017f, 0x8108, 0x00f0,
+ 0x24ac, 0x027f, 0x037f, 0x067f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e,
+ 0x0c7e, 0x037e, 0x027e, 0x017e, 0x6218, 0x2270, 0x72a0, 0x027e,
+ 0x2019, 0x0029, 0x1078, 0x54f0, 0x087e, 0x2041, 0x0000, 0x1078,
+ 0x5419, 0x2c08, 0x1078, 0x84d2, 0x087f, 0x017f, 0x2e60, 0x1078,
+ 0x418b, 0x6210, 0x6314, 0x1078, 0x3d31, 0x6212, 0x6316, 0x017f,
+ 0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x007e, 0x6018,
+ 0xa080, 0x0028, 0x2004, 0xd0bc, 0x00c0, 0x24f9, 0x2071, 0x8800,
+ 0x708c, 0xa005, 0x0040, 0x24f6, 0x8001, 0x708e, 0x007f, 0x0e7f,
+ 0x007c, 0x2071, 0x8800, 0x70c8, 0xa005, 0x0040, 0x24f6, 0x8001,
+ 0x70ca, 0x0078, 0x24f6, 0x6000, 0xc08c, 0x6002, 0x007c, 0x0f7e,
+ 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x157e, 0x2178, 0x81ff,
+ 0x00c0, 0x2516, 0x20a9, 0x0001, 0x0078, 0x2531, 0x2001, 0x8852,
+ 0x2004, 0xd0c4, 0x0040, 0x252d, 0xd0a4, 0x0040, 0x252d, 0x047e,
+ 0x6018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0xa006,
+ 0x2009, 0x002d, 0x1078, 0x86f5, 0x047f, 0x20a9, 0x00ff, 0x2011,
+ 0x0000, 0x027e, 0xa288, 0x8934, 0x210c, 0x81ff, 0x0040, 0x255a,
+ 0x8fff, 0x1040, 0x2566, 0x2019, 0x0029, 0x1078, 0x54f0, 0x087e,
+ 0x2041, 0x0000, 0x1078, 0x5419, 0x0c7e, 0x027e, 0x2160, 0x6204,
+ 0xa294, 0x00ff, 0x2001, 0x0004, 0x8007, 0xa215, 0x6206, 0x027f,
+ 0x0c7f, 0x017e, 0x2c08, 0x1078, 0x84d2, 0x017f, 0x087f, 0x2160,
+ 0x1078, 0x418b, 0x027f, 0x8210, 0x00f0, 0x2531, 0x157f, 0x017f,
+ 0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x047e, 0x027e,
+ 0x017e, 0x2001, 0x8852, 0x2004, 0xd0c4, 0x0040, 0x2579, 0xd0a4,
+ 0x0040, 0x2579, 0xa006, 0x2220, 0x8427, 0x2009, 0x0029, 0x1078,
+ 0x86f5, 0x017f, 0x027f, 0x047f, 0x007c, 0x017e, 0x027e, 0x037e,
+ 0x0c7e, 0x7280, 0x82ff, 0x0040, 0x25ab, 0xa290, 0x8852, 0x2214,
+ 0xd2ac, 0x00c0, 0x25ab, 0x2100, 0x1078, 0x225c, 0x81ff, 0x0040,
+ 0x25ad, 0x2019, 0x0001, 0x8314, 0xa2e0, 0x8ec0, 0x2c04, 0xd384,
+ 0x0040, 0x259f, 0xa084, 0xff00, 0x8007, 0x0078, 0x25a1, 0xa084,
+ 0x00ff, 0xa116, 0x0040, 0x25ad, 0xa096, 0x00ff, 0x0040, 0x25ab,
+ 0x8318, 0x0078, 0x2593, 0xa085, 0x0001, 0x0c7f, 0x037f, 0x027f,
+ 0x017f, 0x007c, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0,
+ 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2,
+ 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7,
+ 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5,
+ 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab,
+ 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e,
+ 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384,
+ 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075,
+ 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b,
+ 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a,
+ 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e,
+ 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045,
+ 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33,
+ 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329,
+ 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b,
+ 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001,
+ 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000,
+ 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00,
+ 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00,
+ 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300,
+ 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00,
+ 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700,
+ 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000,
+ 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00,
+ 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000,
+ 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000,
+ 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x8000, 0x2071, 0x776d, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016,
- 0x703a, 0x703e, 0x7033, 0x777d, 0x7037, 0x777d, 0x7007, 0x0001,
- 0x2061, 0x77bd, 0x6003, 0x0002, 0x007c, 0x0090, 0x2450, 0x0068,
- 0x2450, 0x2071, 0x776d, 0x2b78, 0x7818, 0xd084, 0x00c0, 0x2450,
- 0x2a60, 0x7820, 0xa08e, 0x0069, 0x00c0, 0x2537, 0x0079, 0x24d4,
- 0x007c, 0x2071, 0x776d, 0x7004, 0x0079, 0x2456, 0x245a, 0x245b,
- 0x2465, 0x2477, 0x007c, 0x0090, 0x2464, 0x0068, 0x2464, 0x2b78,
- 0x7818, 0xd084, 0x0040, 0x2483, 0x007c, 0x2b78, 0x2061, 0x77bd,
- 0x6008, 0xa08e, 0x0100, 0x0040, 0x2472, 0xa086, 0x0200, 0x0040,
- 0x252f, 0x007c, 0x7014, 0x2068, 0x2a60, 0x7018, 0x007a, 0x7010,
- 0x2068, 0x6834, 0xa086, 0x0103, 0x0040, 0x247f, 0x007c, 0x2a60,
- 0x2b78, 0x7018, 0x007a, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x00c8,
- 0x248c, 0x61b0, 0x0079, 0x2494, 0x2100, 0xa08a, 0x0036, 0x00c8,
- 0x252b, 0x61b0, 0x0079, 0x24d4, 0x250d, 0x253f, 0x2547, 0x254b,
- 0x2553, 0x2559, 0x255d, 0x2566, 0x256a, 0x2572, 0x2576, 0x252b,
- 0x252b, 0x252b, 0x257a, 0x252b, 0x258a, 0x25a1, 0x25b8, 0x2634,
- 0x2639, 0x2666, 0x26c0, 0x26d1, 0x26ef, 0x2722, 0x272c, 0x2739,
- 0x274c, 0x2766, 0x276f, 0x27ac, 0x27b2, 0x252b, 0x27c2, 0x252b,
- 0x252b, 0x252b, 0x252b, 0x252b, 0x27c6, 0x27cc, 0x252b, 0x252b,
- 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x27d4, 0x252b,
- 0x252b, 0x252b, 0x252b, 0x252b, 0x27e1, 0x27e7, 0x252b, 0x252b,
- 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b,
- 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b,
- 0x252b, 0x252b, 0x252b, 0x252b, 0x2572, 0x2576, 0x252b, 0x252b,
- 0x27f9, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b, 0x252b,
- 0x252b, 0x252b, 0x252b, 0x252b, 0x2846, 0x2913, 0x2927, 0x292e,
- 0x2991, 0x29e2, 0x29ed, 0x2a2c, 0x2a3b, 0x2a4a, 0x2a4d, 0x27fd,
- 0x2a76, 0x2abd, 0x2aca, 0x2bc5, 0x2cb3, 0x2cda, 0x2de4, 0x2df2,
- 0x2dff, 0x2e39, 0x713c, 0x0078, 0x250d, 0x2021, 0x4000, 0x1078,
- 0x2d33, 0x127e, 0x2091, 0x8000, 0x0068, 0x251a, 0x7818, 0xd084,
- 0x0040, 0x251d, 0x127f, 0x0078, 0x2511, 0x781b, 0x0001, 0x7c22,
- 0x7926, 0x7a2a, 0x7b2e, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091,
- 0x5000, 0x127f, 0x007c, 0x2021, 0x4001, 0x0078, 0x250f, 0x2021,
- 0x4002, 0x0078, 0x250f, 0x2021, 0x4003, 0x0078, 0x250f, 0x2021,
- 0x4005, 0x0078, 0x250f, 0x2021, 0x4006, 0x0078, 0x250f, 0xa02e,
- 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0078, 0x2d42, 0x7823,
- 0x0004, 0x7824, 0x007a, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824,
- 0x7930, 0x0078, 0x2d46, 0x7924, 0x7828, 0x2114, 0x200a, 0x0078,
- 0x250d, 0x7924, 0x2114, 0x0078, 0x250d, 0x2099, 0x0009, 0x20a1,
- 0x0009, 0x20a9, 0x0007, 0x53a3, 0x0078, 0x250d, 0x7824, 0x2060,
- 0x0078, 0x257c, 0x2009, 0x0001, 0x2011, 0x000f, 0x2019, 0x0025,
- 0x0078, 0x250d, 0x7d38, 0x7c3c, 0x0078, 0x2541, 0x7d38, 0x7c3c,
- 0x0078, 0x254d, 0x2061, 0x1000, 0x610c, 0xa006, 0x2c14, 0xa200,
- 0x8c60, 0x8109, 0x00c0, 0x257e, 0x2010, 0xa005, 0x0040, 0x250d,
- 0x0078, 0x2533, 0x2061, 0x7751, 0x7824, 0x7930, 0xa11a, 0x00c8,
- 0x253b, 0x8019, 0x0040, 0x253b, 0x604a, 0x6142, 0x782c, 0x6052,
- 0x7828, 0x6056, 0xa006, 0x605a, 0x605e, 0x1078, 0x3d89, 0x0078,
- 0x250d, 0x2061, 0x7751, 0x7824, 0x7930, 0xa11a, 0x00c8, 0x253b,
- 0x8019, 0x0040, 0x253b, 0x604e, 0x6146, 0x782c, 0x6062, 0x7828,
- 0x6066, 0xa006, 0x606a, 0x606e, 0x1078, 0x3b5f, 0x0078, 0x250d,
- 0xa02e, 0x2520, 0x81ff, 0x00c0, 0x2537, 0x7924, 0x7b28, 0x7a2c,
- 0x20a9, 0x0005, 0x20a1, 0x7774, 0x41a1, 0x1078, 0x2cf8, 0x0040,
- 0x2537, 0x2009, 0x0020, 0x1078, 0x2d42, 0x701b, 0x25d0, 0x007c,
- 0x6834, 0x2008, 0xa084, 0x00ff, 0xa096, 0x0011, 0x0040, 0x25dc,
- 0xa096, 0x0019, 0x00c0, 0x2537, 0x810f, 0xa18c, 0x00ff, 0x0040,
- 0x2537, 0x710e, 0x700c, 0x8001, 0x0040, 0x260d, 0x700e, 0x1078,
- 0x2cf8, 0x0040, 0x2537, 0x2009, 0x0020, 0x2061, 0x77bd, 0x6224,
- 0x6328, 0x642c, 0x6530, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1,
- 0x0000, 0xa5a9, 0x0000, 0x1078, 0x2d42, 0x701b, 0x2600, 0x007c,
- 0x6834, 0xa084, 0x00ff, 0xa096, 0x0002, 0x0040, 0x260b, 0xa096,
- 0x000a, 0x00c0, 0x2537, 0x0078, 0x25e2, 0x7010, 0x2068, 0x6838,
- 0xc0fd, 0x683a, 0x1078, 0x3744, 0x00c0, 0x261b, 0x7007, 0x0003,
- 0x701b, 0x261d, 0x007c, 0x1078, 0x3c22, 0x127e, 0x2091, 0x8000,
- 0x20a9, 0x0005, 0x2099, 0x7774, 0x530a, 0x2100, 0xa210, 0xa399,
- 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0xad80, 0x000d, 0x2009,
- 0x0020, 0x127f, 0x0078, 0x2d46, 0x6198, 0x7824, 0x609a, 0x0078,
- 0x250d, 0x2091, 0x8000, 0x7823, 0x4000, 0x7827, 0x4953, 0x782b,
- 0x5020, 0x782f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7832, 0x3f00,
- 0x7836, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007,
- 0xa205, 0x783a, 0x2009, 0x04fd, 0x2104, 0x783e, 0x781b, 0x0001,
- 0x2091, 0x5000, 0x2091, 0x4080, 0x2071, 0x0010, 0x20c1, 0x00f0,
- 0xa08a, 0x0003, 0x00c8, 0x0427, 0x0078, 0x0423, 0x81ff, 0x00c0,
- 0x2537, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x384c, 0x00c0,
- 0x253b, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, 0x267a,
- 0x0078, 0x253b, 0x7c28, 0x7d2c, 0x1078, 0x39fd, 0xd28c, 0x00c0,
- 0x2685, 0x1078, 0x3991, 0x0078, 0x2687, 0x1078, 0x39cb, 0x00c0,
- 0x26b1, 0x2061, 0x7e00, 0x127e, 0x2091, 0x8000, 0x6000, 0xa086,
- 0x0000, 0x0040, 0x269f, 0x6010, 0xa06d, 0x0040, 0x269f, 0x683c,
- 0xa406, 0x00c0, 0x269f, 0x6840, 0xa506, 0x0040, 0x26aa, 0x127f,
- 0xace0, 0x0008, 0x2001, 0x7715, 0x2004, 0xac02, 0x00c8, 0x2537,
- 0x0078, 0x268b, 0x1078, 0x6852, 0x127f, 0x0040, 0x2537, 0x0078,
- 0x250d, 0xa00e, 0x2001, 0x0005, 0x1078, 0x3c22, 0x127e, 0x2091,
- 0x8000, 0x1078, 0x6c5c, 0x1078, 0x3b92, 0x127f, 0x0078, 0x250d,
- 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d10, 0x0040, 0x253b, 0x1078,
- 0x38d5, 0x0040, 0x2537, 0x1078, 0x3a0a, 0x0040, 0x2537, 0x0078,
- 0x250d, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d22, 0x0040, 0x253b,
- 0x1078, 0x3a71, 0x0040, 0x2537, 0x2019, 0x0005, 0x1078, 0x3a2b,
- 0x0040, 0x2537, 0x7828, 0xa08a, 0x1000, 0x00c8, 0x253b, 0x8003,
- 0x800b, 0x810b, 0xa108, 0x1078, 0x4696, 0x0078, 0x250d, 0x127e,
- 0x2091, 0x8000, 0x81ff, 0x00c0, 0x271c, 0x2029, 0x00ff, 0x644c,
- 0x2400, 0xa506, 0x0040, 0x2716, 0x2508, 0x1078, 0x384c, 0x00c0,
- 0x2716, 0x1078, 0x3a71, 0x0040, 0x271c, 0x2019, 0x0004, 0x1078,
- 0x3a2b, 0x0040, 0x271c, 0x7824, 0xa08a, 0x1000, 0x00c8, 0x271f,
- 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x4696, 0x8529, 0x00c8,
- 0x26f8, 0x127f, 0x0078, 0x250d, 0x127f, 0x0078, 0x2537, 0x127f,
- 0x0078, 0x253b, 0x1078, 0x2d10, 0x0040, 0x253b, 0x1078, 0x3942,
- 0x1078, 0x39fd, 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x1078,
- 0x2d10, 0x0040, 0x253b, 0x1078, 0x3931, 0x1078, 0x39fd, 0x0078,
- 0x250d, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d10, 0x0040, 0x253b,
- 0x1078, 0x39ce, 0x0040, 0x2537, 0x1078, 0x378d, 0x1078, 0x398a,
- 0x1078, 0x39fd, 0x0078, 0x250d, 0x1078, 0x2d10, 0x0040, 0x253b,
- 0x1078, 0x38d5, 0x0040, 0x2537, 0x62a0, 0x2019, 0x0005, 0x0c7e,
- 0x1078, 0x3a36, 0x0c7f, 0x1078, 0x4a7e, 0x1078, 0x49c1, 0x2c08,
- 0x1078, 0x747b, 0x1078, 0x39fd, 0x0078, 0x250d, 0x1078, 0x2d10,
- 0x0040, 0x253b, 0x1078, 0x39fd, 0x2208, 0x0078, 0x250d, 0x157e,
- 0x0d7e, 0x0e7e, 0x2069, 0x77ff, 0x6810, 0x6914, 0xa10a, 0x00c8,
- 0x277b, 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019, 0x0000,
- 0x20a9, 0x007e, 0x2069, 0x7820, 0x2d04, 0xa075, 0x0040, 0x2790,
- 0x704c, 0x1078, 0x279a, 0xa210, 0x7080, 0x1078, 0x279a, 0xa318,
- 0x8d68, 0x00f0, 0x2784, 0x2300, 0xa218, 0x0e7f, 0x0d7f, 0x157f,
- 0x0078, 0x250d, 0x0f7e, 0x017e, 0xa07d, 0x0040, 0x27a9, 0x2001,
- 0x0000, 0x8000, 0x2f0c, 0x81ff, 0x0040, 0x27a9, 0x2178, 0x0078,
- 0x27a1, 0x017f, 0x0f7f, 0x007c, 0x2069, 0x77ff, 0x6910, 0x629c,
- 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x614c, 0xa190, 0x2329,
- 0x2214, 0xa294, 0x00ff, 0x6068, 0xa084, 0xff00, 0xa215, 0x6364,
- 0x0078, 0x250d, 0x613c, 0x6240, 0x0078, 0x250d, 0x1078, 0x2d22,
- 0x0040, 0x253b, 0x0078, 0x250d, 0x1078, 0x2d22, 0x0040, 0x253b,
- 0x6244, 0x6338, 0x0078, 0x250d, 0x613c, 0x6240, 0x7824, 0x603e,
- 0x7b28, 0x6342, 0x2069, 0x7751, 0x831f, 0xa305, 0x6816, 0x0078,
- 0x250d, 0x1078, 0x2d22, 0x0040, 0x253b, 0x0078, 0x250d, 0x1078,
- 0x2d22, 0x0040, 0x253b, 0x7828, 0xa00d, 0x0040, 0x253b, 0x782c,
- 0xa005, 0x0040, 0x253b, 0x6244, 0x6146, 0x6338, 0x603a, 0x0078,
- 0x250d, 0x7d38, 0x7c3c, 0x0078, 0x25ba, 0x7824, 0xa09c, 0x00ff,
- 0xa39a, 0x0003, 0x00c8, 0x2537, 0x624c, 0xa084, 0xff00, 0x8007,
- 0xa206, 0x00c0, 0x2815, 0x2001, 0x7740, 0x2009, 0x000c, 0x7a2c,
- 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2d46, 0x81ff, 0x00c0, 0x2537,
- 0x1078, 0x2d22, 0x0040, 0x253b, 0x6004, 0xa084, 0x00ff, 0xa086,
- 0x0006, 0x00c0, 0x2537, 0x0c7e, 0x1078, 0x2cf8, 0x0c7f, 0x0040,
- 0x2537, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x6b56,
- 0x0040, 0x2537, 0x7007, 0x0003, 0x701b, 0x2837, 0x007c, 0x6830,
- 0xa086, 0x0100, 0x0040, 0x2537, 0xad80, 0x000e, 0x2009, 0x000c,
- 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2d46, 0x1078, 0x2cf8,
- 0x0040, 0x2537, 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
- 0x1078, 0x2d42, 0x701b, 0x2855, 0x007c, 0xade8, 0x000d, 0x6800,
- 0xa005, 0x0040, 0x253b, 0x6804, 0xd0ac, 0x0040, 0x2862, 0xd0a4,
- 0x0040, 0x253b, 0xd094, 0x0040, 0x286d, 0x0c7e, 0x2061, 0x0100,
- 0x6104, 0xa18c, 0xffdf, 0x6106, 0x0c7f, 0xd08c, 0x0040, 0x2878,
- 0x0c7e, 0x2061, 0x0100, 0x6104, 0xa18d, 0x0010, 0x6106, 0x0c7f,
- 0x2009, 0x0100, 0x210c, 0xa18a, 0x0002, 0x0048, 0x288d, 0xd084,
- 0x0040, 0x288d, 0x6a28, 0xa28a, 0x007f, 0x00c8, 0x253b, 0xa288,
- 0x2329, 0x210c, 0xa18c, 0x00ff, 0x6152, 0xd0dc, 0x0040, 0x2896,
- 0x6828, 0xa08a, 0x007f, 0x00c8, 0x253b, 0x604e, 0x6808, 0xa08a,
- 0x0100, 0x0048, 0x253b, 0xa08a, 0x0841, 0x00c8, 0x253b, 0xa084,
- 0x0007, 0x00c0, 0x253b, 0x680c, 0xa005, 0x0040, 0x253b, 0x6810,
- 0xa005, 0x0040, 0x253b, 0x6848, 0x6940, 0xa10a, 0x00c8, 0x253b,
- 0x8001, 0x0040, 0x253b, 0x684c, 0x6944, 0xa10a, 0x00c8, 0x253b,
- 0x8001, 0x0040, 0x253b, 0x20a9, 0x001c, 0x2d98, 0x2069, 0x7751,
- 0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084,
- 0x00ff, 0x6042, 0x1078, 0x3d89, 0x1078, 0x3b5f, 0x6000, 0xa086,
- 0x0000, 0x00c0, 0x2911, 0x6808, 0x602a, 0x1078, 0x1de4, 0x6818,
- 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016,
- 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0040, 0x28f1, 0x6830,
- 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0078,
- 0x28f3, 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x1078,
- 0x4722, 0x0c7e, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000,
- 0x0c7f, 0x60b4, 0xa005, 0x0040, 0x290d, 0x6003, 0x0001, 0x2091,
- 0x301d, 0x1078, 0x3591, 0x0078, 0x2911, 0x6003, 0x0004, 0x2091,
- 0x301d, 0x0078, 0x250d, 0x6000, 0xa086, 0x0000, 0x0040, 0x2537,
- 0x2069, 0x7751, 0x7830, 0x6842, 0x7834, 0x6846, 0x2d00, 0x2009,
- 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x2d46, 0x81ff,
- 0x00c0, 0x2537, 0x1078, 0x3591, 0x0078, 0x250d, 0x81ff, 0x00c0,
- 0x2537, 0x617c, 0x81ff, 0x0040, 0x2948, 0x703f, 0x0000, 0x2001,
- 0x7dc0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x127e,
- 0x2091, 0x8000, 0x1078, 0x2d46, 0x701b, 0x250a, 0x127f, 0x007c,
- 0x703f, 0x0001, 0x0d7e, 0x2069, 0x7dc0, 0x20a9, 0x0040, 0x20a1,
- 0x7dc0, 0x2019, 0xffff, 0x43a4, 0x654c, 0xa588, 0x2329, 0x210c,
- 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100, 0xa506,
- 0x0040, 0x297a, 0x1078, 0x384c, 0x00c0, 0x297a, 0x6014, 0x821c,
- 0x0048, 0x2972, 0xa398, 0x7dc0, 0xa085, 0xff00, 0x8007, 0x201a,
- 0x0078, 0x2979, 0xa398, 0x7dc0, 0x2324, 0xa4a4, 0xff00, 0xa405,
- 0x201a, 0x8210, 0x8108, 0xa182, 0x0080, 0x00c8, 0x2981, 0x0078,
- 0x295e, 0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a, 0x0d7f, 0x20a9,
- 0x0040, 0x20a1, 0x7dc0, 0x2099, 0x7dc0, 0x1078, 0x35da, 0x0078,
- 0x2937, 0x1078, 0x2d22, 0x0040, 0x253b, 0x0c7e, 0x1078, 0x2cf8,
- 0x0c7f, 0x0040, 0x2537, 0x2001, 0x7752, 0x2004, 0xd0b4, 0x0040,
- 0x29be, 0x6000, 0xd08c, 0x00c0, 0x29be, 0x6004, 0xa084, 0x00ff,
- 0xa086, 0x0006, 0x00c0, 0x29be, 0x6837, 0x0000, 0x6838, 0xc0fd,
- 0x683a, 0x1078, 0x6b8e, 0x0040, 0x2537, 0x7007, 0x0003, 0x701b,
- 0x29ba, 0x007c, 0x1078, 0x2d22, 0x0040, 0x253b, 0x20a9, 0x002b,
- 0x2c98, 0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80,
- 0x0006, 0x2098, 0xad80, 0x0006, 0x20a0, 0x1078, 0x35da, 0x20a9,
- 0x0004, 0xac80, 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x1078,
- 0x35da, 0x2d00, 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
- 0x0078, 0x2d46, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d10, 0x0040,
- 0x253b, 0x1078, 0x3a15, 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537,
- 0x7828, 0xa08a, 0x1000, 0x00c8, 0x253b, 0x1078, 0x2d22, 0x0040,
- 0x253b, 0x1078, 0x3a71, 0x0040, 0x2537, 0x2019, 0x0004, 0x1078,
- 0x3a2b, 0x7924, 0x810f, 0x7a28, 0x1078, 0x2a08, 0x0078, 0x250d,
- 0xa186, 0x00ff, 0x0040, 0x2a10, 0x1078, 0x2a20, 0x0078, 0x2a1f,
- 0x2029, 0x007e, 0x2061, 0x7700, 0x644c, 0x2400, 0xa506, 0x0040,
- 0x2a1c, 0x2508, 0x1078, 0x2a20, 0x8529, 0x00c8, 0x2a15, 0x007c,
- 0x1078, 0x384c, 0x00c0, 0x2a2b, 0x2200, 0x8003, 0x800b, 0x810b,
- 0xa108, 0x1078, 0x4696, 0x007c, 0x81ff, 0x00c0, 0x2537, 0x1078,
- 0x2d10, 0x0040, 0x253b, 0x1078, 0x38d5, 0x0040, 0x2537, 0x1078,
- 0x3a20, 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2d10,
- 0x0040, 0x253b, 0x1078, 0x38d5, 0x0040, 0x2537, 0x1078, 0x3a0a,
- 0x0078, 0x250d, 0x6100, 0x0078, 0x250d, 0x1078, 0x2d22, 0x0040,
- 0x253b, 0x6004, 0xa086, 0x0707, 0x0040, 0x253b, 0x2001, 0x7700,
- 0x2004, 0xa086, 0x0003, 0x00c0, 0x2537, 0x0d7e, 0xace8, 0x000a,
- 0x7924, 0xd184, 0x0040, 0x2a66, 0xace8, 0x0006, 0x680c, 0x8007,
- 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f, 0x6a00, 0x8217,
- 0x0d7f, 0x6100, 0xa18c, 0x0200, 0x0078, 0x250d, 0x7824, 0xa084,
- 0x00ff, 0xa086, 0x00ff, 0x0040, 0x2a80, 0x81ff, 0x00c0, 0x2537,
- 0x7828, 0xa08a, 0x1000, 0x00c8, 0x253b, 0x7924, 0xa18c, 0xff00,
- 0x810f, 0xa186, 0x00ff, 0x0040, 0x2a94, 0xa182, 0x007f, 0x00c8,
- 0x253b, 0x2100, 0x1078, 0x2094, 0x027e, 0x0c7e, 0x127e, 0x2091,
- 0x8000, 0x2061, 0x7949, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061,
+ 0x8000, 0x8000, 0x2071, 0x8881, 0x7003, 0x0002, 0xa006, 0x7012,
+ 0x7016, 0x703a, 0x703e, 0x7033, 0x8891, 0x7037, 0x8891, 0x7007,
+ 0x0001, 0x2061, 0x88d1, 0x6003, 0x0002, 0x007c, 0x0090, 0x26d9,
+ 0x0068, 0x26d9, 0x2071, 0x8881, 0x2b78, 0x7818, 0xd084, 0x00c0,
+ 0x26d9, 0x2a60, 0x7820, 0xa08e, 0x0069, 0x00c0, 0x27c9, 0x0079,
+ 0x275d, 0x007c, 0x2071, 0x8881, 0x7004, 0x0079, 0x26df, 0x26e3,
+ 0x26e4, 0x26ee, 0x2700, 0x007c, 0x0090, 0x26ed, 0x0068, 0x26ed,
+ 0x2b78, 0x7818, 0xd084, 0x0040, 0x270c, 0x007c, 0x2b78, 0x2061,
+ 0x88d1, 0x6008, 0xa08e, 0x0100, 0x0040, 0x26fb, 0xa086, 0x0200,
+ 0x0040, 0x27c1, 0x007c, 0x7014, 0x2068, 0x2a60, 0x7018, 0x007a,
+ 0x7010, 0x2068, 0x6834, 0xa086, 0x0103, 0x0040, 0x2708, 0x007c,
+ 0x2a60, 0x2b78, 0x7018, 0x007a, 0x2a60, 0x7820, 0xa08a, 0x0040,
+ 0x00c8, 0x2715, 0x61b4, 0x0079, 0x271d, 0x2100, 0xa08a, 0x003f,
+ 0x00c8, 0x27bd, 0x61b4, 0x0079, 0x275d, 0x279f, 0x27d1, 0x27d9,
+ 0x27dd, 0x27e5, 0x27eb, 0x27ef, 0x27f8, 0x27fc, 0x2804, 0x2808,
+ 0x27bd, 0x27bd, 0x27bd, 0x280c, 0x27bd, 0x281c, 0x2833, 0x284a,
+ 0x28c6, 0x28cb, 0x28f8, 0x2952, 0x2963, 0x2981, 0x29c2, 0x29cc,
+ 0x29d9, 0x29ec, 0x2a0a, 0x2a13, 0x2a50, 0x2a56, 0x27bd, 0x2a66,
+ 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x2a6a, 0x2a74, 0x27bd,
+ 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x2a7c,
+ 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x2a89, 0x2a91, 0x27bd,
+ 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x2aa3, 0x2af4, 0x2b45,
+ 0x2b56, 0x27bd, 0x27bd, 0x27bd, 0x34bd, 0x27bd, 0x27bd, 0x27bd,
+ 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x2804, 0x2808, 0x27bd,
+ 0x27bd, 0x2b6d, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd,
+ 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x27bd, 0x2bba, 0x2ce1, 0x2cf5,
+ 0x2d01, 0x2d64, 0x2dbd, 0x2dc8, 0x2e07, 0x2e16, 0x2e25, 0x2e28,
+ 0x2b71, 0x2e51, 0x2e9d, 0x2eaa, 0x2fb9, 0x30d1, 0x30f8, 0x3205,
+ 0x3214, 0x3221, 0x325b, 0x32f8, 0x27bd, 0x27bd, 0x27bd, 0x27bd,
+ 0x3360, 0x337c, 0x33f6, 0x34ae, 0x713c, 0x0078, 0x279f, 0x2021,
+ 0x4000, 0x1078, 0x3154, 0x127e, 0x2091, 0x8000, 0x0068, 0x27ac,
+ 0x7818, 0xd084, 0x0040, 0x27af, 0x127f, 0x0078, 0x27a3, 0x7c22,
+ 0x7926, 0x7a2a, 0x7b2e, 0x781b, 0x0001, 0x2091, 0x4080, 0x7007,
+ 0x0001, 0x2091, 0x5000, 0x127f, 0x007c, 0x2021, 0x4001, 0x0078,
+ 0x27a1, 0x2021, 0x4002, 0x0078, 0x27a1, 0x2021, 0x4003, 0x0078,
+ 0x27a1, 0x2021, 0x4005, 0x0078, 0x27a1, 0x2021, 0x4006, 0x0078,
+ 0x27a1, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0078,
+ 0x3163, 0x7823, 0x0004, 0x7824, 0x007a, 0xa02e, 0x2520, 0x7b28,
+ 0x7a2c, 0x7824, 0x7930, 0x0078, 0x3167, 0x7924, 0x7828, 0x2114,
+ 0x200a, 0x0078, 0x279f, 0x7924, 0x2114, 0x0078, 0x279f, 0x2099,
+ 0x0009, 0x20a1, 0x0009, 0x20a9, 0x0007, 0x53a3, 0x0078, 0x279f,
+ 0x7824, 0x2060, 0x0078, 0x280e, 0x2009, 0x0001, 0x2011, 0x0011,
+ 0x2019, 0x001e, 0x0078, 0x279f, 0x7d38, 0x7c3c, 0x0078, 0x27d3,
+ 0x7d38, 0x7c3c, 0x0078, 0x27df, 0x2061, 0x1000, 0x610c, 0xa006,
+ 0x2c14, 0xa200, 0x8c60, 0x8109, 0x00c0, 0x2810, 0x2010, 0xa005,
+ 0x0040, 0x279f, 0x0078, 0x27c5, 0x2069, 0x8851, 0x7824, 0x7930,
+ 0xa11a, 0x00c8, 0x27cd, 0x8019, 0x0040, 0x27cd, 0x684a, 0x6942,
+ 0x782c, 0x6852, 0x7828, 0x6856, 0xa006, 0x685a, 0x685e, 0x1078,
+ 0x4793, 0x0078, 0x279f, 0x2069, 0x8851, 0x7824, 0x7934, 0xa11a,
+ 0x00c8, 0x27cd, 0x8019, 0x0040, 0x27cd, 0x684e, 0x6946, 0x782c,
+ 0x6862, 0x7828, 0x6866, 0xa006, 0x686a, 0x686e, 0x1078, 0x4343,
+ 0x0078, 0x279f, 0xa02e, 0x2520, 0x81ff, 0x00c0, 0x27c9, 0x7924,
+ 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1, 0x8888, 0x41a1, 0x1078,
+ 0x3119, 0x0040, 0x27c9, 0x2009, 0x0020, 0x1078, 0x3163, 0x701b,
+ 0x2862, 0x007c, 0x6834, 0x2008, 0xa084, 0x00ff, 0xa096, 0x0011,
+ 0x0040, 0x286e, 0xa096, 0x0019, 0x00c0, 0x27c9, 0x810f, 0xa18c,
+ 0x00ff, 0x0040, 0x27c9, 0x710e, 0x700c, 0x8001, 0x0040, 0x289f,
+ 0x700e, 0x1078, 0x3119, 0x0040, 0x27c9, 0x2009, 0x0020, 0x2061,
+ 0x88d1, 0x6224, 0x6328, 0x642c, 0x6530, 0xa290, 0x0040, 0xa399,
+ 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x1078, 0x3163, 0x701b,
+ 0x2892, 0x007c, 0x6834, 0xa084, 0x00ff, 0xa096, 0x0002, 0x0040,
+ 0x289d, 0xa096, 0x000a, 0x00c0, 0x27c9, 0x0078, 0x2874, 0x7010,
+ 0x2068, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x3e3e, 0x00c0, 0x28ad,
+ 0x7007, 0x0003, 0x701b, 0x28af, 0x007c, 0x1078, 0x4454, 0x127e,
+ 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0x8888, 0x530a, 0x2100,
+ 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0xad80,
+ 0x000d, 0x2009, 0x0020, 0x127f, 0x0078, 0x3167, 0x619c, 0x7824,
+ 0x609e, 0x0078, 0x279f, 0x2091, 0x8000, 0x7823, 0x4000, 0x7827,
+ 0x4953, 0x782b, 0x5020, 0x782f, 0x2020, 0x2009, 0x017f, 0x2104,
+ 0x7832, 0x3f00, 0x7836, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200,
+ 0x603c, 0x8007, 0xa205, 0x783a, 0x2009, 0x04fd, 0x2104, 0x783e,
+ 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2071, 0x0010,
+ 0x20c1, 0x00f0, 0xa08a, 0x0003, 0x00c8, 0x0427, 0x0078, 0x0423,
+ 0x81ff, 0x00c0, 0x27c9, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078,
+ 0x3f8e, 0x00c0, 0x27cd, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000,
+ 0x0048, 0x290c, 0x0078, 0x27cd, 0x7c28, 0x7d2c, 0x1078, 0x4146,
+ 0xd28c, 0x00c0, 0x2917, 0x1078, 0x40da, 0x0078, 0x2919, 0x1078,
+ 0x4114, 0x00c0, 0x2943, 0x2061, 0x8f00, 0x127e, 0x2091, 0x8000,
+ 0x6000, 0xa086, 0x0000, 0x0040, 0x2931, 0x6010, 0xa06d, 0x0040,
+ 0x2931, 0x683c, 0xa406, 0x00c0, 0x2931, 0x6840, 0xa506, 0x0040,
+ 0x293c, 0x127f, 0xace0, 0x000c, 0x2001, 0x8815, 0x2004, 0xac02,
+ 0x00c8, 0x27c9, 0x0078, 0x291d, 0x1078, 0x759a, 0x127f, 0x0040,
+ 0x27c9, 0x0078, 0x279f, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4454,
+ 0x127e, 0x2091, 0x8000, 0x1078, 0x7a4e, 0x1078, 0x4376, 0x127f,
+ 0x0078, 0x279f, 0x81ff, 0x00c0, 0x27c9, 0x1078, 0x3131, 0x0040,
+ 0x27cd, 0x1078, 0x4017, 0x0040, 0x27c9, 0x1078, 0x4154, 0x0040,
+ 0x27c9, 0x0078, 0x279f, 0x81ff, 0x00c0, 0x27c9, 0x1078, 0x3143,
+ 0x0040, 0x27cd, 0x1078, 0x41c7, 0x0040, 0x27c9, 0x2019, 0x0005,
+ 0x1078, 0x4175, 0x0040, 0x27c9, 0x7828, 0xa08a, 0x1000, 0x00c8,
+ 0x27cd, 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x50ff, 0x0078,
+ 0x279f, 0x127e, 0x2091, 0x8000, 0x81ff, 0x0040, 0x298b, 0x2009,
+ 0x0001, 0x0078, 0x29bc, 0x2029, 0x00ff, 0x644c, 0x2400, 0xa506,
+ 0x0040, 0x29b6, 0x2508, 0x1078, 0x3f8e, 0x00c0, 0x29b6, 0x1078,
+ 0x41c7, 0x00c0, 0x29a1, 0x2009, 0x0002, 0x62a4, 0x2518, 0x0078,
+ 0x29bc, 0x2019, 0x0004, 0x1078, 0x4175, 0x00c0, 0x29ab, 0x2009,
+ 0x0006, 0x0078, 0x29bc, 0x7824, 0xa08a, 0x1000, 0x00c8, 0x29bf,
+ 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x50ff, 0x8529, 0x00c8,
+ 0x298e, 0x127f, 0x0078, 0x279f, 0x127f, 0x0078, 0x27c9, 0x127f,
+ 0x0078, 0x27cd, 0x1078, 0x3131, 0x0040, 0x27cd, 0x1078, 0x408b,
+ 0x1078, 0x4146, 0x0078, 0x279f, 0x81ff, 0x00c0, 0x27c9, 0x1078,
+ 0x3131, 0x0040, 0x27cd, 0x1078, 0x407a, 0x1078, 0x4146, 0x0078,
+ 0x279f, 0x81ff, 0x00c0, 0x27c9, 0x1078, 0x3131, 0x0040, 0x27cd,
+ 0x1078, 0x4117, 0x0040, 0x27c9, 0x1078, 0x3e87, 0x1078, 0x40d3,
+ 0x1078, 0x4146, 0x0078, 0x279f, 0x1078, 0x3131, 0x0040, 0x27cd,
+ 0x1078, 0x4017, 0x0040, 0x27c9, 0x62a0, 0x2019, 0x0005, 0x0c7e,
+ 0x1078, 0x418b, 0x0c7f, 0x1078, 0x54f0, 0x087e, 0x2041, 0x0000,
+ 0x1078, 0x5419, 0x2c08, 0x1078, 0x84d2, 0x087f, 0x1078, 0x4146,
+ 0x0078, 0x279f, 0x1078, 0x3131, 0x0040, 0x27cd, 0x1078, 0x4146,
+ 0x2208, 0x0078, 0x279f, 0x157e, 0x0d7e, 0x0e7e, 0x2069, 0x8913,
+ 0x6810, 0x6914, 0xa10a, 0x00c8, 0x2a1f, 0x2009, 0x0000, 0x6816,
+ 0x2011, 0x0000, 0x2019, 0x0000, 0x20a9, 0x00ff, 0x2069, 0x8934,
+ 0x2d04, 0xa075, 0x0040, 0x2a34, 0x704c, 0x1078, 0x2a3e, 0xa210,
+ 0x7080, 0x1078, 0x2a3e, 0xa318, 0x8d68, 0x00f0, 0x2a28, 0x2300,
+ 0xa218, 0x0e7f, 0x0d7f, 0x157f, 0x0078, 0x279f, 0x0f7e, 0x017e,
+ 0xa07d, 0x0040, 0x2a4d, 0x2001, 0x0000, 0x8000, 0x2f0c, 0x81ff,
+ 0x0040, 0x2a4d, 0x2178, 0x0078, 0x2a45, 0x017f, 0x0f7f, 0x007c,
+ 0x2069, 0x8913, 0x6910, 0x62a0, 0x0078, 0x279f, 0x81ff, 0x00c0,
+ 0x27c9, 0x614c, 0xa190, 0x25b2, 0x2214, 0xa294, 0x00ff, 0x606c,
+ 0xa084, 0xff00, 0xa215, 0x6368, 0x0078, 0x279f, 0x613c, 0x6240,
+ 0x0078, 0x279f, 0x127e, 0x2091, 0x8000, 0x6134, 0xa006, 0x2010,
+ 0x2018, 0x127f, 0x0078, 0x279f, 0x1078, 0x3143, 0x0040, 0x27cd,
+ 0x6244, 0x6338, 0x0078, 0x279f, 0x613c, 0x6240, 0x7824, 0x603e,
+ 0x7b28, 0x6342, 0x2069, 0x8851, 0x831f, 0xa305, 0x6816, 0x0078,
+ 0x279f, 0x127e, 0x2091, 0x8000, 0x7824, 0x6036, 0x127f, 0x0078,
+ 0x279f, 0x1078, 0x3143, 0x0040, 0x27cd, 0x7828, 0xa00d, 0x0040,
+ 0x27cd, 0x782c, 0xa005, 0x0040, 0x27cd, 0x6244, 0x6146, 0x6338,
+ 0x603a, 0x0078, 0x279f, 0x2001, 0x8800, 0x2004, 0xa086, 0x0003,
+ 0x00c0, 0x27c9, 0x0c7e, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c,
+ 0x00ff, 0xa196, 0x00ff, 0x00c0, 0x2aba, 0x6030, 0xa085, 0xff00,
+ 0x0078, 0x2ac9, 0xa182, 0x007f, 0x00c8, 0x2aed, 0xa188, 0x25b2,
+ 0x210c, 0xa18c, 0x00ff, 0x6030, 0xa116, 0x0040, 0x2aed, 0x810f,
+ 0xa105, 0x127e, 0x2091, 0x8000, 0x007e, 0x1078, 0x68a8, 0x007f,
+ 0x0040, 0x2aea, 0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x1078,
+ 0x3119, 0x0040, 0x2af0, 0x6837, 0x0000, 0x7007, 0x0003, 0x701b,
+ 0x279f, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078, 0x6939, 0x127f,
+ 0x0c7f, 0x007c, 0x0c7f, 0x0078, 0x27c9, 0x0c7f, 0x0078, 0x27cd,
+ 0x1078, 0x690e, 0x0078, 0x2aea, 0x2001, 0x8800, 0x2004, 0xa086,
+ 0x0003, 0x00c0, 0x27c9, 0x0c7e, 0x2061, 0x0100, 0x7924, 0x810f,
+ 0xa18c, 0x00ff, 0xa196, 0x00ff, 0x00c0, 0x2b0b, 0x6030, 0xa085,
+ 0xff00, 0x0078, 0x2b1a, 0xa182, 0x007f, 0x00c8, 0x2b3e, 0xa188,
+ 0x25b2, 0x210c, 0xa18c, 0x00ff, 0x6030, 0xa116, 0x0040, 0x2b3e,
+ 0x810f, 0xa105, 0x127e, 0x2091, 0x8000, 0x007e, 0x1078, 0x68a8,
+ 0x007f, 0x0040, 0x2b3b, 0x601a, 0x600b, 0xbc05, 0x601f, 0x0001,
+ 0x1078, 0x3119, 0x0040, 0x2b41, 0x6837, 0x0000, 0x7007, 0x0003,
+ 0x701b, 0x279f, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078, 0x6939,
+ 0x127f, 0x0c7f, 0x007c, 0x0c7f, 0x0078, 0x27c9, 0x0c7f, 0x0078,
+ 0x27cd, 0x1078, 0x690e, 0x0078, 0x2b3b, 0x2061, 0x8b24, 0x127e,
+ 0x2091, 0x8000, 0x6000, 0xd084, 0x0040, 0x2b53, 0x6104, 0x6208,
+ 0x127f, 0x0078, 0x279f, 0x127f, 0x0078, 0x27cd, 0x81ff, 0x00c0,
+ 0x27c9, 0x127e, 0x2091, 0x8000, 0x6244, 0x6060, 0xa202, 0x0048,
+ 0x2b6a, 0xa085, 0x0001, 0x1078, 0x2262, 0x1078, 0x36ef, 0x127f,
+ 0x0078, 0x279f, 0x127f, 0x0078, 0x27cd, 0x7d38, 0x7c3c, 0x0078,
+ 0x284c, 0x7824, 0xa09c, 0x00ff, 0xa39a, 0x0003, 0x00c8, 0x27c9,
+ 0x624c, 0xa084, 0xff00, 0x8007, 0xa206, 0x00c0, 0x2b89, 0x2001,
+ 0x8840, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078,
+ 0x3167, 0x81ff, 0x00c0, 0x27c9, 0x1078, 0x3143, 0x0040, 0x27cd,
+ 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x27c9, 0x0c7e,
+ 0x1078, 0x3119, 0x0c7f, 0x0040, 0x27c9, 0x6837, 0x0000, 0x6838,
+ 0xc0fd, 0x683a, 0x1078, 0x792c, 0x0040, 0x27c9, 0x7007, 0x0003,
+ 0x701b, 0x2bab, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x27c9,
+ 0xad80, 0x000e, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+ 0x0078, 0x3167, 0x1078, 0x3119, 0x0040, 0x27c9, 0x1078, 0x3d16,
+ 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3163,
+ 0x701b, 0x2bcb, 0x007c, 0xade8, 0x000d, 0x6800, 0xa005, 0x0040,
+ 0x27cd, 0x6804, 0xd0ac, 0x0040, 0x2bd8, 0xd0a4, 0x0040, 0x27cd,
+ 0xd094, 0x0040, 0x2be3, 0x0c7e, 0x2061, 0x0100, 0x6104, 0xa18c,
+ 0xffdf, 0x6106, 0x0c7f, 0xd08c, 0x0040, 0x2bee, 0x0c7e, 0x2061,
+ 0x0100, 0x6104, 0xa18d, 0x0010, 0x6106, 0x0c7f, 0x2009, 0x0100,
+ 0x210c, 0xa18a, 0x0002, 0x0048, 0x2c03, 0xd084, 0x0040, 0x2c03,
+ 0x6a28, 0xa28a, 0x007f, 0x00c8, 0x27cd, 0xa288, 0x25b2, 0x210c,
+ 0xa18c, 0x00ff, 0x6152, 0xd0dc, 0x0040, 0x2c0c, 0x6828, 0xa08a,
+ 0x007f, 0x00c8, 0x27cd, 0x604e, 0x6808, 0xa08a, 0x0100, 0x0048,
+ 0x27cd, 0xa08a, 0x0841, 0x00c8, 0x27cd, 0xa084, 0x0007, 0x00c0,
+ 0x27cd, 0x680c, 0xa005, 0x0040, 0x27cd, 0x6810, 0xa005, 0x0040,
+ 0x27cd, 0x6848, 0x6940, 0xa10a, 0x00c8, 0x27cd, 0x8001, 0x0040,
+ 0x27cd, 0x684c, 0x6944, 0xa10a, 0x00c8, 0x27cd, 0x8001, 0x0040,
+ 0x27cd, 0x6804, 0xd0fc, 0x0040, 0x2c54, 0x1078, 0x3119, 0x0040,
+ 0x27c9, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0xa290,
+ 0x0038, 0xa399, 0x0000, 0x1078, 0x3163, 0x701b, 0x2c48, 0x007c,
+ 0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069, 0x886d, 0x2da0,
+ 0x53a3, 0x7010, 0xa0e8, 0x000d, 0x20a9, 0x001c, 0x2d98, 0x2069,
+ 0x8851, 0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, 0x8007,
+ 0xa084, 0x00ff, 0x6042, 0x1078, 0x4793, 0x1078, 0x42d3, 0x1078,
+ 0x4343, 0x6000, 0xa086, 0x0000, 0x00c0, 0x2cdf, 0x6808, 0x602a,
+ 0x1078, 0x1f57, 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f,
+ 0x8217, 0x831f, 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4,
+ 0x0040, 0x2c8c, 0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f,
+ 0x8217, 0x831f, 0x0078, 0x2c8e, 0xa084, 0xf0ff, 0x6006, 0x610a,
+ 0x620e, 0x6312, 0x1078, 0x518a, 0x6904, 0xd1fc, 0x0040, 0x2cc1,
+ 0x0c7e, 0x2009, 0x0000, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x0040,
+ 0x2cbe, 0x0078, 0x2ca8, 0x839d, 0x00c8, 0x2cbe, 0x3508, 0x8109,
+ 0x1078, 0x4cb2, 0x6878, 0x6016, 0x6874, 0x2008, 0xa084, 0xff00,
+ 0x8007, 0x600a, 0xa184, 0x00ff, 0x6006, 0x8108, 0x00c0, 0x2cbc,
+ 0x6003, 0x0003, 0x0078, 0x2cbe, 0x6003, 0x0001, 0x00f0, 0x2ca3,
+ 0x0c7f, 0x0c7e, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000,
+ 0x0c7f, 0x1078, 0x3352, 0x0040, 0x2ccf, 0x1078, 0x2262, 0x60b8,
+ 0xa005, 0x0040, 0x2cdb, 0x6003, 0x0001, 0x2091, 0x301d, 0x1078,
+ 0x3c73, 0x0078, 0x2cdf, 0x6003, 0x0004, 0x2091, 0x301d, 0x0078,
+ 0x279f, 0x6000, 0xa086, 0x0000, 0x0040, 0x27c9, 0x2069, 0x8851,
+ 0x7830, 0x6842, 0x7834, 0x6846, 0x2d00, 0x2009, 0x001c, 0x7a2c,
+ 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x3167, 0x81ff, 0x00c0, 0x27c9,
+ 0xa006, 0x1078, 0x2262, 0x1078, 0x3d16, 0x1078, 0x3c73, 0x0078,
+ 0x279f, 0x81ff, 0x00c0, 0x27c9, 0x6180, 0x81ff, 0x0040, 0x2d1b,
+ 0x703f, 0x0000, 0x2001, 0x8ec0, 0x2009, 0x0040, 0x7a2c, 0x7b28,
+ 0x7c3c, 0x7d38, 0x127e, 0x2091, 0x8000, 0x1078, 0x3167, 0x701b,
+ 0x279c, 0x127f, 0x007c, 0x703f, 0x0001, 0x0d7e, 0x2069, 0x8ec0,
+ 0x20a9, 0x0040, 0x20a1, 0x8ec0, 0x2019, 0xffff, 0x43a4, 0x654c,
+ 0xa588, 0x25b2, 0x210c, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011,
+ 0x0002, 0x2100, 0xa506, 0x0040, 0x2d4d, 0x1078, 0x3f8e, 0x00c0,
+ 0x2d4d, 0x6014, 0x821c, 0x0048, 0x2d45, 0xa398, 0x8ec0, 0xa085,
+ 0xff00, 0x8007, 0x201a, 0x0078, 0x2d4c, 0xa398, 0x8ec0, 0x2324,
+ 0xa4a4, 0xff00, 0xa405, 0x201a, 0x8210, 0x8108, 0xa182, 0x0080,
+ 0x00c8, 0x2d54, 0x0078, 0x2d31, 0x8201, 0x8007, 0x2d0c, 0xa105,
+ 0x206a, 0x0d7f, 0x20a9, 0x0040, 0x20a1, 0x8ec0, 0x2099, 0x8ec0,
+ 0x1078, 0x3cbc, 0x0078, 0x2d0a, 0x1078, 0x3143, 0x0040, 0x27cd,
+ 0x0c7e, 0x1078, 0x3119, 0x0c7f, 0x00c0, 0x2d72, 0x2009, 0x0002,
+ 0x0078, 0x27c9, 0x2001, 0x8852, 0x2004, 0xd0b4, 0x0040, 0x2d99,
+ 0x6000, 0xd08c, 0x00c0, 0x2d99, 0x6004, 0xa084, 0x00ff, 0xa086,
+ 0x0006, 0x00c0, 0x2d99, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a,
+ 0x1078, 0x7980, 0x00c0, 0x2d90, 0x2009, 0x0003, 0x0078, 0x27c9,
+ 0x7007, 0x0003, 0x701b, 0x2d95, 0x007c, 0x1078, 0x3143, 0x0040,
+ 0x27cd, 0x20a9, 0x002b, 0x2c98, 0xade8, 0x0002, 0x2da0, 0x53a3,
+ 0x20a9, 0x0004, 0xac80, 0x0006, 0x2098, 0xad80, 0x0006, 0x20a0,
+ 0x1078, 0x3cbc, 0x20a9, 0x0004, 0xac80, 0x000a, 0x2098, 0xad80,
+ 0x000a, 0x20a0, 0x1078, 0x3cbc, 0x2d00, 0x2009, 0x002b, 0x7a2c,
+ 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x3167, 0x81ff, 0x00c0, 0x27c9,
+ 0x1078, 0x3131, 0x0040, 0x27cd, 0x1078, 0x415f, 0x0078, 0x279f,
+ 0x81ff, 0x00c0, 0x27c9, 0x7828, 0xa08a, 0x1000, 0x00c8, 0x27cd,
+ 0x1078, 0x3143, 0x0040, 0x27cd, 0x1078, 0x41c7, 0x0040, 0x27c9,
+ 0x2019, 0x0004, 0x1078, 0x4175, 0x7924, 0x810f, 0x7a28, 0x1078,
+ 0x2de3, 0x0078, 0x279f, 0xa186, 0x00ff, 0x0040, 0x2deb, 0x1078,
+ 0x2dfb, 0x0078, 0x2dfa, 0x2029, 0x007e, 0x2061, 0x8800, 0x644c,
+ 0x2400, 0xa506, 0x0040, 0x2df7, 0x2508, 0x1078, 0x2dfb, 0x8529,
+ 0x00c8, 0x2df0, 0x007c, 0x1078, 0x3f8e, 0x00c0, 0x2e06, 0x2200,
+ 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x50ff, 0x007c, 0x81ff,
+ 0x00c0, 0x27c9, 0x1078, 0x3131, 0x0040, 0x27cd, 0x1078, 0x4017,
+ 0x0040, 0x27c9, 0x1078, 0x416a, 0x0078, 0x279f, 0x81ff, 0x00c0,
+ 0x27c9, 0x1078, 0x3131, 0x0040, 0x27cd, 0x1078, 0x4017, 0x0040,
+ 0x27c9, 0x1078, 0x4154, 0x0078, 0x279f, 0x6100, 0x0078, 0x279f,
+ 0x1078, 0x3143, 0x0040, 0x27cd, 0x6004, 0xa086, 0x0707, 0x0040,
+ 0x27cd, 0x2001, 0x8800, 0x2004, 0xa086, 0x0003, 0x00c0, 0x27c9,
+ 0x0d7e, 0xace8, 0x000a, 0x7924, 0xd184, 0x0040, 0x2e41, 0xace8,
+ 0x0006, 0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04,
+ 0x831f, 0x6a00, 0x8217, 0x0d7f, 0x6100, 0xa18c, 0x0200, 0x0078,
+ 0x279f, 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff, 0x0040, 0x2e5b,
+ 0x81ff, 0x00c0, 0x27c9, 0xa006, 0x1078, 0x2262, 0x1078, 0x3d16,
+ 0x7828, 0xa08a, 0x1000, 0x00c8, 0x27cd, 0x7924, 0xa18c, 0xff00,
+ 0x810f, 0xa186, 0x00ff, 0x0040, 0x2e74, 0xa182, 0x007f, 0x00c8,
+ 0x27cd, 0x2100, 0x1078, 0x225c, 0x027e, 0x0c7e, 0x127e, 0x2091,
+ 0x8000, 0x2061, 0x8ab5, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061,
0x0100, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043,
- 0x0090, 0x6043, 0x0010, 0x2009, 0x001e, 0x2011, 0x35b6, 0x1078,
- 0x4719, 0x7924, 0xa18c, 0xff00, 0x810f, 0x7a28, 0x1078, 0x2a08,
- 0x127f, 0x0c7f, 0x027f, 0x0078, 0x250d, 0x7924, 0xa18c, 0xff00,
- 0x810f, 0x0c7e, 0x1078, 0x3811, 0x2c08, 0x0c7f, 0x00c0, 0x253b,
- 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x60bc, 0xd09c, 0x0040,
- 0x2537, 0x1078, 0x2cf8, 0x0040, 0x2537, 0x6823, 0x0000, 0x7924,
- 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x2d42, 0x701b, 0x2ae1,
- 0x007c, 0x2009, 0x0080, 0x1078, 0x384c, 0x00c0, 0x2aee, 0x6004,
- 0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x2af2, 0x2021, 0x400a,
- 0x0078, 0x250f, 0x0d7e, 0xade8, 0x000d, 0x6900, 0x6a08, 0x6b0c,
- 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0040, 0x2b65,
- 0xa0be, 0x0112, 0x0040, 0x2b65, 0xa0be, 0x0113, 0x0040, 0x2b65,
- 0xa0be, 0x0114, 0x0040, 0x2b65, 0xa0be, 0x0117, 0x0040, 0x2b65,
- 0xa0be, 0x011a, 0x0040, 0x2b65, 0xa0be, 0x0121, 0x0040, 0x2b5b,
- 0xa0be, 0x0131, 0x0040, 0x2b5b, 0xa0be, 0x0171, 0x0040, 0x2b65,
- 0xa0be, 0x0173, 0x0040, 0x2b65, 0xa0be, 0x01a1, 0x00c0, 0x2b2d,
- 0x6830, 0x8007, 0x6832, 0x0078, 0x2b6b, 0xa0be, 0x0212, 0x0040,
- 0x2b61, 0xa0be, 0x0213, 0x0040, 0x2b61, 0xa0be, 0x0214, 0x0040,
- 0x2b53, 0xa0be, 0x0217, 0x0040, 0x2b4d, 0xa0be, 0x021a, 0x00c0,
- 0x2b46, 0x6838, 0x8007, 0x683a, 0x0078, 0x2b65, 0xa0be, 0x0300,
- 0x0040, 0x2b65, 0x0d7f, 0x0078, 0x253b, 0xad80, 0x0010, 0x20a9,
- 0x0007, 0x1078, 0x2ba1, 0xad80, 0x000e, 0x20a9, 0x0001, 0x1078,
- 0x2ba1, 0x0078, 0x2b65, 0xad80, 0x000c, 0x1078, 0x2baf, 0x0078,
- 0x2b6b, 0xad80, 0x000e, 0x1078, 0x2baf, 0xad80, 0x000c, 0x20a9,
- 0x0001, 0x1078, 0x2ba1, 0x0c7e, 0x1078, 0x2cf8, 0x0040, 0x2b96,
- 0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, 0x684f, 0x0020, 0x685b,
- 0x0001, 0x810b, 0x697e, 0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e,
- 0x6d92, 0x6996, 0x689b, 0x0000, 0x0c7f, 0x0d7f, 0x6837, 0x0000,
- 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x1078, 0x6b72, 0x0040,
- 0x2537, 0x7007, 0x0003, 0x701b, 0x2b9a, 0x007c, 0x0c7f, 0x0d7f,
- 0x0078, 0x2537, 0x6820, 0xa086, 0x8001, 0x0040, 0x2537, 0x0078,
- 0x250d, 0x017e, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a,
- 0x8108, 0x280a, 0x8108, 0x00f0, 0x2ba3, 0x017f, 0x007c, 0x017e,
- 0x0a7e, 0x0b7e, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x2054,
- 0x8000, 0x205c, 0x2b0a, 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108,
- 0x280a, 0x0b7f, 0x0a7f, 0x017f, 0x007c, 0x81ff, 0x00c0, 0x2537,
+ 0x0090, 0x6043, 0x0010, 0x2009, 0x001e, 0x2011, 0x3c98, 0x1078,
+ 0x5181, 0x7924, 0xa18c, 0xff00, 0x810f, 0x7a28, 0x1078, 0x2de3,
+ 0x127f, 0x0c7f, 0x027f, 0x0078, 0x279f, 0x7924, 0xa18c, 0xff00,
+ 0x810f, 0x0c7e, 0x1078, 0x3f53, 0x2c08, 0x0c7f, 0x00c0, 0x27cd,
+ 0x0078, 0x279f, 0x81ff, 0x0040, 0x2eb1, 0x2009, 0x0001, 0x0078,
+ 0x27c9, 0x60c0, 0xd09c, 0x00c0, 0x2eb9, 0x2009, 0x0005, 0x0078,
+ 0x27c9, 0x1078, 0x3119, 0x00c0, 0x2ec1, 0x2009, 0x0002, 0x0078,
+ 0x27c9, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3163,
+ 0x701b, 0x2ecb, 0x007c, 0x2009, 0x0080, 0x1078, 0x3f8e, 0x00c0,
+ 0x2ed8, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x2edc,
+ 0x2021, 0x400a, 0x0078, 0x27a1, 0x0d7e, 0xade8, 0x000d, 0x6900,
+ 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100,
+ 0x0040, 0x2f4f, 0xa0be, 0x0112, 0x0040, 0x2f4f, 0xa0be, 0x0113,
+ 0x0040, 0x2f4f, 0xa0be, 0x0114, 0x0040, 0x2f4f, 0xa0be, 0x0117,
+ 0x0040, 0x2f4f, 0xa0be, 0x011a, 0x0040, 0x2f4f, 0xa0be, 0x0121,
+ 0x0040, 0x2f45, 0xa0be, 0x0131, 0x0040, 0x2f45, 0xa0be, 0x0171,
+ 0x0040, 0x2f4f, 0xa0be, 0x0173, 0x0040, 0x2f4f, 0xa0be, 0x01a1,
+ 0x00c0, 0x2f17, 0x6830, 0x8007, 0x6832, 0x0078, 0x2f55, 0xa0be,
+ 0x0212, 0x0040, 0x2f4b, 0xa0be, 0x0213, 0x0040, 0x2f4b, 0xa0be,
+ 0x0214, 0x0040, 0x2f3d, 0xa0be, 0x0217, 0x0040, 0x2f37, 0xa0be,
+ 0x021a, 0x00c0, 0x2f30, 0x6838, 0x8007, 0x683a, 0x0078, 0x2f4f,
+ 0xa0be, 0x0300, 0x0040, 0x2f4f, 0x0d7f, 0x0078, 0x27cd, 0xad80,
+ 0x0010, 0x20a9, 0x0007, 0x1078, 0x2f95, 0xad80, 0x000e, 0x20a9,
+ 0x0001, 0x1078, 0x2f95, 0x0078, 0x2f4f, 0xad80, 0x000c, 0x1078,
+ 0x2fa3, 0x0078, 0x2f55, 0xad80, 0x000e, 0x1078, 0x2fa3, 0xad80,
+ 0x000c, 0x20a9, 0x0001, 0x1078, 0x2f95, 0x0c7e, 0x1078, 0x3119,
+ 0x0040, 0x2f86, 0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, 0x6853,
+ 0x0000, 0x684f, 0x0020, 0x685b, 0x0001, 0x810b, 0x697e, 0x6883,
+ 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996, 0x689b, 0x0000,
+ 0x0c7f, 0x0d7f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823,
+ 0x0000, 0x1078, 0x7948, 0x00c0, 0x2f81, 0x2009, 0x0003, 0x0078,
+ 0x27c9, 0x7007, 0x0003, 0x701b, 0x2f8c, 0x007c, 0x0c7f, 0x0d7f,
+ 0x2009, 0x0002, 0x0078, 0x27c9, 0x6820, 0xa086, 0x8001, 0x00c0,
+ 0x279f, 0x2009, 0x0004, 0x0078, 0x27c9, 0x017e, 0x2008, 0x2044,
+ 0x8000, 0x204c, 0x8000, 0x290a, 0x8108, 0x280a, 0x8108, 0x00f0,
+ 0x2f97, 0x017f, 0x007c, 0x017e, 0x0a7e, 0x0b7e, 0x2008, 0x2044,
+ 0x8000, 0x204c, 0x8000, 0x2054, 0x8000, 0x205c, 0x2b0a, 0x8108,
+ 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a, 0x0b7f, 0x0a7f, 0x017f,
+ 0x007c, 0x81ff, 0x0040, 0x2fc0, 0x2009, 0x0001, 0x0078, 0x27c9,
0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080, 0x0048,
- 0x253b, 0xa182, 0x00ff, 0x00c8, 0x253b, 0x7a2c, 0x7b28, 0x6064,
- 0xa306, 0x00c0, 0x2be3, 0x6068, 0xa24e, 0x0040, 0x253b, 0xa9cc,
- 0xff00, 0x0040, 0x253b, 0x0c7e, 0x1078, 0x2c57, 0x2c68, 0x0c7f,
- 0x0040, 0x2c0a, 0xa0c6, 0x4000, 0x00c0, 0x2bf0, 0x0078, 0x2c07,
- 0xa0c6, 0x4007, 0x00c0, 0x2bf7, 0x2408, 0x0078, 0x2c07, 0xa0c6,
- 0x4008, 0x00c0, 0x2bff, 0x2708, 0x2610, 0x0078, 0x2c07, 0xa0c6,
- 0x4009, 0x00c0, 0x2c05, 0x0078, 0x2c07, 0x2001, 0x4006, 0x2020,
- 0x0078, 0x250f, 0x017e, 0x0b7e, 0x0c7e, 0x0e7e, 0x2c70, 0x1078,
- 0x5cb4, 0x0040, 0x2c45, 0x2d00, 0x601a, 0x2e58, 0x0e7f, 0x0e7e,
- 0x0c7e, 0x1078, 0x2cf8, 0x0c7f, 0x2b70, 0x0040, 0x2537, 0x6837,
- 0x0000, 0x2d00, 0x6012, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a,
- 0x127e, 0x2091, 0x8000, 0x1078, 0x22b5, 0x127f, 0x601f, 0x0001,
- 0x2001, 0x0000, 0x1078, 0x37e0, 0x2001, 0x0002, 0x1078, 0x37f4,
- 0x127e, 0x2091, 0x8000, 0x7088, 0x8000, 0x708a, 0x127f, 0x2009,
- 0x0002, 0x1078, 0x5d41, 0xa085, 0x0001, 0x0e7f, 0x0c7f, 0x0b7f,
- 0x017f, 0x0040, 0x2537, 0x7007, 0x0003, 0x701b, 0x2c50, 0x007c,
- 0x6830, 0xa086, 0x0100, 0x00c0, 0x250d, 0x0078, 0x2537, 0x0e7e,
- 0x0d7e, 0x2029, 0x0000, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071,
- 0x78a0, 0x2e04, 0xa005, 0x00c0, 0x2c6b, 0x2100, 0xa406, 0x0040,
- 0x2ca8, 0x0078, 0x2c9c, 0x2068, 0x6f10, 0x2700, 0xa306, 0x00c0,
- 0x2c8d, 0x6e14, 0x2600, 0xa206, 0x00c0, 0x2c8d, 0x2400, 0xa106,
- 0x00c0, 0x2c89, 0x2d60, 0xd884, 0x0040, 0x2cae, 0x6004, 0xa084,
- 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2cae, 0x2001, 0x4000, 0x0078,
- 0x2caf, 0x2001, 0x4007, 0x0078, 0x2caf, 0x2400, 0xa106, 0x00c0,
- 0x2c9c, 0x6e14, 0x87ff, 0x00c0, 0x2c98, 0x86ff, 0x0040, 0x2ca8,
- 0x2001, 0x4008, 0x0078, 0x2caf, 0x8420, 0x8e70, 0x00f0, 0x2c61,
- 0x2001, 0x4009, 0x0078, 0x2caf, 0x2001, 0x0001, 0x0078, 0x2caf,
- 0x1078, 0x3811, 0x00c0, 0x2ca4, 0x6312, 0x6216, 0xa006, 0xa005,
- 0x0d7f, 0x0e7f, 0x007c, 0x81ff, 0x00c0, 0x2537, 0x1078, 0x2cf8,
- 0x0040, 0x2537, 0x6837, 0x0000, 0x7824, 0xa005, 0x0040, 0x253b,
- 0xa096, 0x00ff, 0x0040, 0x2cc8, 0xa092, 0x0004, 0x00c8, 0x253b,
- 0x2010, 0x2d18, 0x1078, 0x2277, 0x0040, 0x2537, 0x7007, 0x0003,
- 0x701b, 0x2cd3, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2537,
- 0x0078, 0x250d, 0x81ff, 0x00c0, 0x2537, 0x7924, 0xa18c, 0xff00,
- 0x810f, 0xa182, 0x0080, 0x0048, 0x253b, 0xa182, 0x00ff, 0x00c8,
- 0x253b, 0x127e, 0x2091, 0x8000, 0x1078, 0x6a99, 0x00c0, 0x2cf5,
- 0x1078, 0x3834, 0x127f, 0x0078, 0x250d, 0x127f, 0x0078, 0x2537,
- 0x1078, 0x1327, 0x0040, 0x2d0f, 0xa006, 0x6802, 0x7010, 0xa005,
- 0x00c0, 0x2d07, 0x2d00, 0x7012, 0x7016, 0x0078, 0x2d0d, 0x7014,
- 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d, 0x007c,
- 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x384c, 0x00c0, 0x2d1f,
- 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, 0x2d20, 0xa066,
- 0x8cff, 0x007c, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x1078, 0x384c,
- 0x00c0, 0x2d30, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0048, 0x2d31,
- 0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff, 0x0040, 0x2d3e,
- 0x2168, 0x6904, 0x1078, 0x1340, 0x0078, 0x2d35, 0x7112, 0x7116,
- 0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x2d48, 0x2031, 0x0000,
- 0x2061, 0x77bd, 0x6606, 0x6112, 0x600e, 0x6226, 0x632a, 0x642e,
- 0x6532, 0x2c10, 0x1078, 0x1377, 0x7007, 0x0002, 0x701b, 0x250d,
- 0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001,
- 0x777b, 0x2004, 0xa005, 0x00c0, 0x2d74, 0x0068, 0x2d74, 0x7818,
- 0xd084, 0x00c0, 0x2d74, 0x781b, 0x0001, 0x7a22, 0x7b26, 0x7c2a,
- 0x2091, 0x4080, 0x0078, 0x2d99, 0x017e, 0x0c7e, 0x0e7e, 0x2071,
- 0x776d, 0x7138, 0xa182, 0x0008, 0x0048, 0x2d82, 0x7030, 0x2060,
- 0x0078, 0x2d93, 0x7030, 0xa0e0, 0x0008, 0xac82, 0x77bd, 0x0048,
- 0x2d8b, 0x2061, 0x777d, 0x2c00, 0x7032, 0x81ff, 0x00c0, 0x2d91,
- 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, 0x0e7f, 0x0c7f,
- 0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071, 0x776d, 0x7038,
- 0xa005, 0x0040, 0x2dd5, 0x127e, 0x2091, 0x8000, 0x0068, 0x2dd4,
- 0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x2dd3, 0x0c7e,
- 0x781b, 0x0001, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826,
- 0x6008, 0x782a, 0x2091, 0x4080, 0x7038, 0x8001, 0x703a, 0xa005,
- 0x00c0, 0x2dc9, 0x7033, 0x777d, 0x7037, 0x777d, 0x0c7f, 0x0078,
- 0x2dd3, 0xac80, 0x0008, 0xa0fa, 0x77bd, 0x0048, 0x2dd1, 0x2001,
- 0x777d, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f, 0x007c, 0x027e,
- 0x2001, 0x7752, 0x2004, 0xd0c4, 0x0040, 0x2de2, 0x2011, 0x8014,
- 0x1078, 0x2d59, 0x027f, 0x007c, 0x81ff, 0x00c0, 0x2537, 0x127e,
- 0x2091, 0x8000, 0x6030, 0xc08d, 0x6032, 0x1078, 0x3591, 0x127f,
- 0x0078, 0x250d, 0x7824, 0x2008, 0xa18c, 0xfffd, 0x00c0, 0x2dfd,
- 0x61c8, 0xa10d, 0x61ca, 0x0078, 0x250d, 0x0078, 0x253b, 0x81ff,
- 0x00c0, 0x2537, 0x6000, 0xa086, 0x0003, 0x00c0, 0x2537, 0x2001,
- 0x7752, 0x2004, 0xd0a4, 0x00c0, 0x2537, 0x1078, 0x2d22, 0x0040,
- 0x253b, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2e1c,
- 0x7828, 0xa005, 0x0040, 0x250d, 0x0c7e, 0x1078, 0x2cf8, 0x0c7f,
- 0x0040, 0x2537, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd,
- 0x683a, 0x1078, 0x6bfb, 0x0040, 0x2537, 0x7007, 0x0003, 0x701b,
- 0x2e32, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2537, 0x0078,
- 0x250d, 0x2001, 0x7700, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2537,
- 0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x2cf8, 0x0040,
- 0x2537, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f,
- 0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x1078, 0x384c, 0x00c0,
- 0x2e7f, 0x6004, 0xa0c6, 0x0707, 0x0040, 0x2e7f, 0xa084, 0x00ff,
- 0xa0c6, 0x0006, 0x00c0, 0x2e7f, 0x87ff, 0x0040, 0x2e72, 0xac80,
- 0x0006, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078, 0x2baf,
- 0x0078, 0x2e7b, 0xac80, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004,
- 0x53a3, 0x1078, 0x2baf, 0x21a2, 0x94a0, 0xa6b0, 0x0005, 0x8108,
- 0xa186, 0x007e, 0x0040, 0x2e8a, 0xa686, 0x0028, 0x0040, 0x2e93,
- 0x0078, 0x2e55, 0x86ff, 0x00c0, 0x2e91, 0x7120, 0x810b, 0x0078,
- 0x250d, 0x702f, 0x0001, 0x711e, 0x7020, 0xa600, 0x7022, 0x772a,
- 0x2061, 0x77bd, 0x6007, 0x0000, 0x6612, 0x7024, 0x600e, 0x6226,
- 0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x1377, 0x7007, 0x0002,
- 0x701b, 0x2eab, 0x007c, 0x702c, 0xa005, 0x00c0, 0x2ebd, 0x711c,
- 0x7024, 0x20a0, 0x7728, 0x2031, 0x0000, 0x2061, 0x77bd, 0x6224,
- 0x6328, 0x642c, 0x6530, 0x0078, 0x2e55, 0x7120, 0x810b, 0x0078,
- 0x250d, 0x127e, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0x7700,
- 0x6044, 0xd0a4, 0x00c0, 0x2eea, 0xd084, 0x0040, 0x2ed3, 0x1078,
- 0x3015, 0x0078, 0x2ee6, 0xd08c, 0x0040, 0x2eda, 0x1078, 0x2f2c,
- 0x0078, 0x2ee6, 0xd094, 0x0040, 0x2ee1, 0x1078, 0x2f0f, 0x0078,
- 0x2ee6, 0xd09c, 0x0040, 0x2ee6, 0x1078, 0x2ef4, 0x0e7f, 0x0c7f,
- 0x127f, 0x007c, 0x017e, 0x6128, 0xd19c, 0x00c0, 0x2ef1, 0xc19d,
- 0x612a, 0x017f, 0x0078, 0x2ee6, 0x6043, 0x0040, 0x6043, 0x0000,
- 0x706f, 0x0000, 0x7087, 0x0001, 0x70a7, 0x0000, 0x70bf, 0x0000,
- 0x2009, 0x7dc0, 0x200b, 0x0000, 0x707f, 0x0000, 0x7073, 0x000f,
- 0x2009, 0x000f, 0x2011, 0x3551, 0x1078, 0x4719, 0x007c, 0x7070,
- 0xa005, 0x00c0, 0x2f2b, 0x2011, 0x3551, 0x1078, 0x4689, 0x6043,
- 0x0020, 0x6043, 0x0000, 0x6044, 0xd08c, 0x00c0, 0x2f27, 0x7083,
- 0x0000, 0x6043, 0x0090, 0x6043, 0x0010, 0x0078, 0x2f2b, 0x7077,
- 0x0000, 0x0078, 0x2f2b, 0x007c, 0x7074, 0xa08a, 0x0003, 0x00c8,
- 0x2f35, 0x1079, 0x2f38, 0x0078, 0x2f37, 0x1078, 0x12cd, 0x007c,
- 0x2f3b, 0x2f8a, 0x3014, 0x0f7e, 0x7077, 0x0001, 0x20e1, 0xa000,
- 0x20e1, 0x8700, 0x1078, 0x1de4, 0x20e1, 0x9080, 0x20e1, 0x4000,
- 0x2079, 0x7c00, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000,
- 0x780f, 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, 0x0000,
- 0x781f, 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, 0x0000,
- 0x782f, 0x0000, 0x2079, 0x7c0c, 0x207b, 0x1101, 0x7807, 0x0000,
- 0x2099, 0x7705, 0x20a1, 0x7c0e, 0x20a9, 0x0004, 0x53a3, 0x2079,
- 0x7c12, 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0x7c00, 0x20a1,
- 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000,
- 0x1078, 0x3578, 0x0f7f, 0x707b, 0x0000, 0x6043, 0x0008, 0x6043,
- 0x0000, 0x007c, 0x0d7e, 0x7078, 0x707b, 0x0000, 0xa025, 0x0040,
- 0x2ffe, 0x6020, 0xd0b4, 0x00c0, 0x2ffc, 0x7184, 0x81ff, 0x0040,
- 0x2fe5, 0xa486, 0x000c, 0x00c0, 0x2ff0, 0xa480, 0x0018, 0x8004,
- 0x20a8, 0x2011, 0x7c80, 0x2019, 0x7c00, 0x220c, 0x2304, 0xa106,
- 0x00c0, 0x2fbc, 0x8210, 0x8318, 0x00f0, 0x2fa5, 0x6043, 0x0004,
- 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x7077, 0x0002,
- 0x7083, 0x0002, 0x0078, 0x2ffc, 0x2069, 0x7c80, 0x6930, 0xa18e,
- 0x1101, 0x00c0, 0x2ff0, 0x6834, 0xa005, 0x00c0, 0x2ff0, 0x6900,
- 0xa18c, 0x00ff, 0x00c0, 0x2fd0, 0x6804, 0xa005, 0x0040, 0x2fe5,
- 0x2011, 0x7c8e, 0x2019, 0x7705, 0x20a9, 0x0004, 0x220c, 0x2304,
- 0xa102, 0x0048, 0x2fe3, 0x00c0, 0x2ff0, 0x8210, 0x8318, 0x00f0,
- 0x2fd6, 0x0078, 0x2ff0, 0x7087, 0x0000, 0x20e1, 0x9080, 0x20e1,
- 0x4000, 0x2099, 0x7c80, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6,
- 0x6043, 0x0008, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x2ffc,
- 0x60c3, 0x000c, 0x1078, 0x3578, 0x0d7f, 0x007c, 0x6020, 0xd0b4,
- 0x00c0, 0x2ffc, 0x60c3, 0x000c, 0x2011, 0x7940, 0x2013, 0x0000,
- 0x707b, 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575,
- 0x1078, 0x5693, 0x0078, 0x2ffc, 0x007c, 0x7080, 0xa08a, 0x001d,
- 0x00c8, 0x301e, 0x1079, 0x3021, 0x0078, 0x3020, 0x1078, 0x12cd,
- 0x007c, 0x3045, 0x3054, 0x3085, 0x309a, 0x30ca, 0x30f2, 0x3122,
- 0x314c, 0x317c, 0x31a2, 0x31eb, 0x320d, 0x3231, 0x3247, 0x326f,
- 0x3282, 0x328b, 0x32a4, 0x32d2, 0x32fa, 0x3328, 0x3352, 0x339a,
- 0x33cb, 0x33ed, 0x342b, 0x3451, 0x346a, 0x3477, 0x7003, 0x0007,
- 0x6004, 0xa084, 0xfff9, 0x6006, 0x007c, 0x608b, 0xbc94, 0x608f,
- 0xf0f0, 0x6043, 0x0002, 0x7083, 0x0001, 0x2009, 0x07d0, 0x2011,
- 0x3558, 0x1078, 0x467c, 0x007c, 0x0f7e, 0x7078, 0xa086, 0x0014,
- 0x00c0, 0x3083, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x3083,
- 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x3081, 0x7834,
- 0xa005, 0x00c0, 0x3081, 0x7a38, 0xd2fc, 0x0040, 0x3077, 0x70a4,
- 0xa005, 0x00c0, 0x3077, 0x1078, 0x3611, 0x70a7, 0x0001, 0x2011,
- 0x3558, 0x1078, 0x4689, 0x7083, 0x0010, 0x1078, 0x328b, 0x0078,
- 0x3083, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0003, 0x6043,
- 0x0004, 0x1078, 0x35e2, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9,
- 0x000a, 0x20a3, 0x0000, 0x00f0, 0x3091, 0x60c3, 0x0014, 0x1078,
- 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x30c8, 0x2011,
- 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x30c4, 0x2079,
- 0x7c80, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x30c4, 0x7834, 0xa005,
- 0x00c0, 0x30c4, 0x7a38, 0xd2fc, 0x0040, 0x30be, 0x70a4, 0xa005,
- 0x00c0, 0x30be, 0x1078, 0x3611, 0x70a7, 0x0001, 0x7083, 0x0004,
- 0x1078, 0x30ca, 0x0078, 0x30c8, 0x7083, 0x0002, 0x707b, 0x0000,
- 0x0f7f, 0x007c, 0x7083, 0x0005, 0x1078, 0x35e2, 0x20a3, 0x1103,
- 0x20a3, 0x0000, 0x3430, 0x2011, 0x7c8e, 0x706c, 0xa005, 0x00c0,
- 0x30e4, 0x714c, 0xa186, 0xffff, 0x0040, 0x30e4, 0x1078, 0x351c,
- 0x0040, 0x30e4, 0x1078, 0x3611, 0x20a9, 0x0008, 0x2298, 0x26a0,
- 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078,
- 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x3120, 0x2011,
- 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x311c, 0x2079,
- 0x7c80, 0x7a30, 0xa296, 0x1103, 0x00c0, 0x311c, 0x7834, 0xa005,
- 0x00c0, 0x311c, 0x7a38, 0xd2fc, 0x0040, 0x3116, 0x70a4, 0xa005,
- 0x00c0, 0x3116, 0x1078, 0x3611, 0x70a7, 0x0001, 0x7083, 0x0006,
- 0x1078, 0x3122, 0x0078, 0x3120, 0x7083, 0x0002, 0x707b, 0x0000,
- 0x0f7f, 0x007c, 0x7083, 0x0007, 0x1078, 0x35e2, 0x20a3, 0x1104,
- 0x20a3, 0x0000, 0x3430, 0x2011, 0x7c8e, 0x706c, 0xa005, 0x00c0,
- 0x313e, 0x7150, 0xa186, 0xffff, 0x0040, 0x313e, 0xa180, 0x2329,
- 0x200c, 0xa18c, 0xff00, 0x810f, 0x1078, 0x351c, 0x20a9, 0x0008,
- 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
- 0x0014, 0x1078, 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040,
- 0x317a, 0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0,
- 0x3176, 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3176,
- 0x7834, 0xa005, 0x00c0, 0x3176, 0x7a38, 0xd2fc, 0x0040, 0x3170,
- 0x70a4, 0xa005, 0x00c0, 0x3170, 0x1078, 0x3611, 0x70a7, 0x0001,
- 0x7083, 0x0008, 0x1078, 0x317c, 0x0078, 0x317a, 0x7083, 0x0002,
- 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0009, 0x1078, 0x35e2,
- 0x20a3, 0x1105, 0x20a3, 0x0100, 0x3430, 0x706c, 0xa005, 0x00c0,
- 0x318f, 0x1078, 0x3486, 0x0040, 0x319f, 0x0078, 0x3199, 0x20a9,
- 0x0008, 0x2099, 0x7c8e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3,
- 0x0000, 0x60c3, 0x0014, 0x1078, 0x3578, 0x0078, 0x31a1, 0x1078,
- 0x303e, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x31e9, 0x2011,
- 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x31e5, 0x2079,
- 0x7c80, 0x7a30, 0xa296, 0x1105, 0x00c0, 0x31e5, 0x7834, 0x2011,
- 0x0100, 0xa21e, 0x00c0, 0x31ce, 0x7a38, 0xd2fc, 0x0040, 0x31c8,
- 0x70a4, 0xa005, 0x00c0, 0x31c8, 0x1078, 0x3611, 0x70a7, 0x0001,
- 0x7083, 0x000a, 0x1078, 0x31eb, 0x0078, 0x31e9, 0xa005, 0x00c0,
- 0x31e5, 0x7a38, 0xd2fc, 0x0040, 0x31dd, 0x70a4, 0xa005, 0x00c0,
- 0x31dd, 0x1078, 0x3611, 0x70a7, 0x0001, 0x707f, 0x0000, 0x7083,
- 0x000e, 0x1078, 0x326f, 0x0078, 0x31e9, 0x7083, 0x0002, 0x707b,
- 0x0000, 0x0f7f, 0x007c, 0x7083, 0x000b, 0x2011, 0x7c0e, 0x22a0,
- 0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009,
- 0x0000, 0x41a4, 0x1078, 0x35e2, 0x20a3, 0x1106, 0x20a3, 0x0000,
- 0x6030, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6,
- 0x60c3, 0x0084, 0x1078, 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005,
- 0x0040, 0x322f, 0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0084,
- 0x00c0, 0x322b, 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1106, 0x00c0,
- 0x322b, 0x7834, 0xa005, 0x00c0, 0x322b, 0x7083, 0x000c, 0x1078,
- 0x3231, 0x0078, 0x322f, 0x7083, 0x0002, 0x707b, 0x0000, 0x0f7f,
- 0x007c, 0x7083, 0x000d, 0x1078, 0x35e2, 0x20a3, 0x1107, 0x20a3,
- 0x0000, 0x2099, 0x7c8e, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000,
- 0x20a3, 0x0000, 0x60c3, 0x0084, 0x1078, 0x3578, 0x007c, 0x0f7e,
- 0x7078, 0xa005, 0x0040, 0x326d, 0x2011, 0x3558, 0x1078, 0x4689,
- 0xa086, 0x0084, 0x00c0, 0x3269, 0x2079, 0x7c80, 0x7a30, 0xa296,
- 0x1107, 0x00c0, 0x3269, 0x7834, 0xa005, 0x00c0, 0x3269, 0x707f,
- 0x0001, 0x1078, 0x35d4, 0x7083, 0x000e, 0x1078, 0x326f, 0x0078,
- 0x326d, 0x7083, 0x0002, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083,
- 0x000f, 0x707b, 0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5, 0x6043,
- 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x3558, 0x1078,
- 0x467c, 0x007c, 0x7078, 0xa005, 0x0040, 0x328a, 0x2011, 0x3558,
- 0x1078, 0x4689, 0x007c, 0x7083, 0x0011, 0x20e1, 0x9080, 0x20e1,
- 0x4000, 0x2099, 0x7c80, 0x20a1, 0x020b, 0x7478, 0xa480, 0x0018,
- 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3,
- 0x0014, 0x1078, 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040,
- 0x32d0, 0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0,
- 0x32ce, 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1103, 0x00c0, 0x32ce,
- 0x7834, 0xa005, 0x00c0, 0x32ce, 0x7a38, 0xd2fc, 0x0040, 0x32c8,
- 0x70a4, 0xa005, 0x00c0, 0x32c8, 0x1078, 0x3611, 0x70a7, 0x0001,
- 0x7083, 0x0012, 0x1078, 0x32d2, 0x0078, 0x32d0, 0x707b, 0x0000,
- 0x0f7f, 0x007c, 0x7083, 0x0013, 0x1078, 0x35ee, 0x20a3, 0x1103,
- 0x20a3, 0x0000, 0x3430, 0x2011, 0x7c8e, 0x706c, 0xa005, 0x00c0,
- 0x32ec, 0x714c, 0xa186, 0xffff, 0x0040, 0x32ec, 0x1078, 0x351c,
- 0x0040, 0x32ec, 0x1078, 0x3611, 0x20a9, 0x0008, 0x2298, 0x26a0,
- 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078,
- 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x3326, 0x2011,
- 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x3324, 0x2079,
- 0x7c80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3324, 0x7834, 0xa005,
- 0x00c0, 0x3324, 0x7a38, 0xd2fc, 0x0040, 0x331e, 0x70a4, 0xa005,
- 0x00c0, 0x331e, 0x1078, 0x3611, 0x70a7, 0x0001, 0x7083, 0x0014,
- 0x1078, 0x3328, 0x0078, 0x3326, 0x707b, 0x0000, 0x0f7f, 0x007c,
- 0x7083, 0x0015, 0x1078, 0x35ee, 0x20a3, 0x1104, 0x20a3, 0x0000,
- 0x3430, 0x2011, 0x7c8e, 0x706c, 0xa006, 0x00c0, 0x3344, 0x7150,
- 0xa186, 0xffff, 0x0040, 0x3344, 0xa180, 0x2329, 0x200c, 0xa18c,
- 0xff00, 0x810f, 0x1078, 0x351c, 0x20a9, 0x0008, 0x2298, 0x26a0,
+ 0x27cd, 0xa182, 0x00ff, 0x00c8, 0x27cd, 0x7a2c, 0x7b28, 0x6068,
+ 0xa306, 0x00c0, 0x2fdb, 0x606c, 0xa24e, 0x0040, 0x27cd, 0xa9cc,
+ 0xff00, 0x0040, 0x27cd, 0x0c7e, 0x1078, 0x3071, 0x2c68, 0x0c7f,
+ 0x0040, 0x3002, 0xa0c6, 0x4000, 0x00c0, 0x2fe8, 0x0078, 0x2fff,
+ 0xa0c6, 0x4007, 0x00c0, 0x2fef, 0x2408, 0x0078, 0x2fff, 0xa0c6,
+ 0x4008, 0x00c0, 0x2ff7, 0x2708, 0x2610, 0x0078, 0x2fff, 0xa0c6,
+ 0x4009, 0x00c0, 0x2ffd, 0x0078, 0x2fff, 0x2001, 0x4006, 0x2020,
+ 0x0078, 0x27a1, 0x2d00, 0x7022, 0x017e, 0x0b7e, 0x0c7e, 0x0e7e,
+ 0x2c70, 0x1078, 0x68a8, 0x0040, 0x304f, 0x2d00, 0x601a, 0x2001,
+ 0x8856, 0x2004, 0xa084, 0x00ff, 0x6842, 0x2e58, 0x0e7f, 0x0e7e,
+ 0x0c7e, 0x1078, 0x3119, 0x0c7f, 0x2b70, 0x00c0, 0x3029, 0x1078,
+ 0x690e, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, 0x2009, 0x0002, 0x0078,
+ 0x27c9, 0x6837, 0x0000, 0x2d00, 0x6012, 0x6833, 0x0000, 0x6838,
+ 0xc0fd, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x24bf, 0x127f,
+ 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x3ef1, 0x2001, 0x0002,
+ 0x1078, 0x3f05, 0x127e, 0x2091, 0x8000, 0x708c, 0x8000, 0x708e,
+ 0x127f, 0x2009, 0x0002, 0x1078, 0x6939, 0xa085, 0x0001, 0x0e7f,
+ 0x0c7f, 0x0b7f, 0x017f, 0x00c0, 0x3059, 0x2009, 0x0003, 0x0078,
+ 0x27c9, 0x7007, 0x0003, 0x701b, 0x305e, 0x007c, 0x6830, 0xa086,
+ 0x0100, 0x2009, 0x0004, 0x0040, 0x27c9, 0x7020, 0x2060, 0x2009,
+ 0x0000, 0x1078, 0x4233, 0x00c0, 0x306f, 0x2009, 0x0001, 0x0078,
+ 0x279f, 0x0e7e, 0x0d7e, 0x2029, 0x0000, 0x2021, 0x0080, 0x20a9,
+ 0x007f, 0x2071, 0x89b4, 0x2e04, 0xa005, 0x00c0, 0x3086, 0x2100,
+ 0xa406, 0x00c0, 0x30b7, 0x2428, 0x0078, 0x30b7, 0x2068, 0x6f10,
+ 0x2700, 0xa306, 0x00c0, 0x30a8, 0x6e14, 0x2600, 0xa206, 0x00c0,
+ 0x30a8, 0x2400, 0xa106, 0x00c0, 0x30a4, 0x2d60, 0xd884, 0x0040,
+ 0x30cc, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x30cc,
+ 0x2001, 0x4000, 0x0078, 0x30cd, 0x2001, 0x4007, 0x0078, 0x30cd,
+ 0x2400, 0xa106, 0x00c0, 0x30b7, 0x6e14, 0x87ff, 0x00c0, 0x30b3,
+ 0x86ff, 0x0040, 0x3083, 0x2001, 0x4008, 0x0078, 0x30cd, 0x8420,
+ 0x8e70, 0x00f0, 0x307b, 0x85ff, 0x00c0, 0x30c6, 0x2001, 0x4009,
+ 0x0078, 0x30cd, 0x2001, 0x0001, 0x0078, 0x30cd, 0x1078, 0x3f53,
+ 0x00c0, 0x30c2, 0x6312, 0x6216, 0xa006, 0xa005, 0x0d7f, 0x0e7f,
+ 0x007c, 0x81ff, 0x00c0, 0x27c9, 0x1078, 0x3119, 0x0040, 0x27c9,
+ 0x6837, 0x0000, 0x7824, 0xa005, 0x0040, 0x27cd, 0xa096, 0x00ff,
+ 0x0040, 0x30e6, 0xa092, 0x0004, 0x00c8, 0x27cd, 0x2010, 0x2d18,
+ 0x1078, 0x2481, 0x0040, 0x27c9, 0x7007, 0x0003, 0x701b, 0x30f1,
+ 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x27c9, 0x0078, 0x279f,
+ 0x7924, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080, 0x0048, 0x27cd,
+ 0xa182, 0x00ff, 0x00c8, 0x27cd, 0x127e, 0x2091, 0x8000, 0x1078,
+ 0x782e, 0x00c0, 0x3116, 0xa190, 0x8934, 0x2204, 0xa065, 0x0040,
+ 0x3116, 0x1078, 0x3d31, 0x127f, 0x0078, 0x279f, 0x127f, 0x0078,
+ 0x27c9, 0x1078, 0x132b, 0x0040, 0x3130, 0xa006, 0x6802, 0x7010,
+ 0xa005, 0x00c0, 0x3128, 0x2d00, 0x7012, 0x7016, 0x0078, 0x312e,
+ 0x7014, 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d,
+ 0x007c, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x3f8e, 0x00c0,
+ 0x3140, 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, 0x3141,
+ 0xa066, 0x8cff, 0x007c, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x1078,
+ 0x3f8e, 0x00c0, 0x3151, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0048,
+ 0x3152, 0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff, 0x0040,
+ 0x315f, 0x2168, 0x6904, 0x1078, 0x1344, 0x0078, 0x3156, 0x7112,
+ 0x7116, 0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x3169, 0x2031,
+ 0x0000, 0x2061, 0x88d1, 0x6606, 0x6112, 0x600e, 0x6226, 0x632a,
+ 0x642e, 0x6532, 0x2c10, 0x1078, 0x137b, 0x7007, 0x0002, 0x701b,
+ 0x279f, 0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, 0x0000,
+ 0x2001, 0x888f, 0x2004, 0xa005, 0x00c0, 0x3195, 0x0068, 0x3195,
+ 0x7818, 0xd084, 0x00c0, 0x3195, 0x7a22, 0x7b26, 0x7c2a, 0x781b,
+ 0x0001, 0x2091, 0x4080, 0x0078, 0x31ba, 0x017e, 0x0c7e, 0x0e7e,
+ 0x2071, 0x8881, 0x7138, 0xa182, 0x0008, 0x0048, 0x31a3, 0x7030,
+ 0x2060, 0x0078, 0x31b4, 0x7030, 0xa0e0, 0x0008, 0xac82, 0x88d1,
+ 0x0048, 0x31ac, 0x2061, 0x8891, 0x2c00, 0x7032, 0x81ff, 0x00c0,
+ 0x31b2, 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, 0x0e7f,
+ 0x0c7f, 0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071, 0x8881,
+ 0x7038, 0xa005, 0x0040, 0x31f6, 0x127e, 0x2091, 0x8000, 0x0068,
+ 0x31f5, 0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x31f4,
+ 0x0c7e, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826, 0x6008,
+ 0x782a, 0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001, 0x703a,
+ 0xa005, 0x00c0, 0x31ea, 0x7033, 0x8891, 0x7037, 0x8891, 0x0c7f,
+ 0x0078, 0x31f4, 0xac80, 0x0008, 0xa0fa, 0x88d1, 0x0048, 0x31f2,
+ 0x2001, 0x8891, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f, 0x007c,
+ 0x027e, 0x2001, 0x8852, 0x2004, 0xd0c4, 0x0040, 0x3203, 0x2011,
+ 0x8014, 0x1078, 0x317a, 0x027f, 0x007c, 0x81ff, 0x00c0, 0x27c9,
+ 0x127e, 0x2091, 0x8000, 0x6030, 0xc08d, 0xc0ac, 0x6032, 0x1078,
+ 0x3c73, 0x127f, 0x0078, 0x279f, 0x7824, 0x2008, 0xa18c, 0xfffd,
+ 0x00c0, 0x321f, 0x61cc, 0xa10d, 0x61ce, 0x0078, 0x279f, 0x0078,
+ 0x27cd, 0x81ff, 0x00c0, 0x27c9, 0x6000, 0xa086, 0x0003, 0x00c0,
+ 0x27c9, 0x2001, 0x8852, 0x2004, 0xd0a4, 0x00c0, 0x27c9, 0x1078,
+ 0x3143, 0x0040, 0x27cd, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
+ 0x00c0, 0x323e, 0x7828, 0xa005, 0x0040, 0x279f, 0x0c7e, 0x1078,
+ 0x3119, 0x0c7f, 0x0040, 0x27c9, 0x6837, 0x0000, 0x6833, 0x0000,
+ 0x6838, 0xc0fd, 0x683a, 0x1078, 0x79ed, 0x0040, 0x27c9, 0x7007,
+ 0x0003, 0x701b, 0x3254, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040,
+ 0x27c9, 0x0078, 0x279f, 0x2001, 0x8800, 0x2004, 0xa086, 0x0003,
+ 0x00c0, 0x27c9, 0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078,
+ 0x3119, 0x0040, 0x27c9, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023,
+ 0x0000, 0x702f, 0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x1078,
+ 0x3f8e, 0x00c0, 0x32ad, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006,
+ 0x0040, 0x3288, 0xa0c4, 0xff00, 0xa8c6, 0x0600, 0x00c0, 0x32ad,
+ 0x2001, 0x8852, 0x2004, 0xd0ac, 0x00c0, 0x3292, 0x1078, 0x4233,
+ 0x0040, 0x32ad, 0xd784, 0x0040, 0x32a0, 0xac80, 0x0006, 0x2098,
+ 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078, 0x2fa3, 0x0078, 0x32a9,
+ 0xac80, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078,
+ 0x2fa3, 0x21a2, 0x94a0, 0xa6b0, 0x0005, 0x8108, 0xd78c, 0x0040,
+ 0x32b7, 0xa186, 0x0100, 0x0040, 0x32c1, 0x0078, 0x32bb, 0xa186,
+ 0x007e, 0x0040, 0x32c1, 0xa686, 0x0028, 0x0040, 0x32ca, 0x0078,
+ 0x3277, 0x86ff, 0x00c0, 0x32c8, 0x7120, 0x810b, 0x0078, 0x279f,
+ 0x702f, 0x0001, 0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061,
+ 0x88d1, 0x6007, 0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a,
+ 0x642e, 0x6532, 0x2c10, 0x1078, 0x137b, 0x7007, 0x0002, 0x701b,
+ 0x32e2, 0x007c, 0x702c, 0xa005, 0x00c0, 0x32f4, 0x711c, 0x7024,
+ 0x20a0, 0x7728, 0x2031, 0x0000, 0x2061, 0x88d1, 0x6224, 0x6328,
+ 0x642c, 0x6530, 0x0078, 0x3277, 0x7120, 0x810b, 0x0078, 0x279f,
+ 0x2029, 0x007e, 0x7924, 0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00,
+ 0x8007, 0xa0e2, 0x0020, 0x0048, 0x27cd, 0xa502, 0x0048, 0x27cd,
+ 0xa184, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x27cd, 0xa502, 0x0048,
+ 0x27cd, 0xa284, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x27cd,
+ 0xa502, 0x0048, 0x27cd, 0xa284, 0x00ff, 0xa0e2, 0x0020, 0x0048,
+ 0x27cd, 0xa502, 0x0048, 0x27cd, 0xa384, 0xff00, 0x8007, 0xa0e2,
+ 0x0020, 0x0048, 0x27cd, 0xa502, 0x0048, 0x27cd, 0xa384, 0x00ff,
+ 0xa0e2, 0x0020, 0x0048, 0x27cd, 0xa502, 0x0048, 0x27cd, 0xa484,
+ 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x27cd, 0xa502, 0x0048,
+ 0x27cd, 0xa484, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x27cd, 0xa502,
+ 0x0048, 0x27cd, 0x2061, 0x8a9c, 0x6102, 0x6206, 0x630a, 0x640e,
+ 0x0078, 0x279f, 0x007e, 0x2001, 0x8852, 0x2004, 0xd0cc, 0x007f,
+ 0x007c, 0x007e, 0x2001, 0x8871, 0x2004, 0xd0bc, 0x007f, 0x007c,
+ 0x6160, 0x7a24, 0x6300, 0x82ff, 0x00c0, 0x3369, 0x7926, 0x0078,
+ 0x279f, 0x83ff, 0x00c0, 0x27cd, 0x2001, 0xfff0, 0xa200, 0x00c8,
+ 0x27cd, 0x2019, 0xffff, 0x6064, 0xa302, 0xa200, 0x0048, 0x27cd,
+ 0x7926, 0x6262, 0x0078, 0x279f, 0x2001, 0x8800, 0x2004, 0xa086,
+ 0x0003, 0x00c0, 0x27c9, 0x7c28, 0x7d24, 0x7e38, 0x7f2c, 0x1078,
+ 0x3119, 0x0040, 0x27c9, 0x2009, 0x0000, 0x2019, 0x0000, 0x7023,
+ 0x0000, 0x702f, 0x0000, 0xad80, 0x0003, 0x7026, 0x20a0, 0xa1e0,
+ 0x8934, 0x2c64, 0x8cff, 0x0040, 0x33b6, 0x6004, 0xa084, 0x00ff,
+ 0xa086, 0x0006, 0x0040, 0x33ab, 0x6004, 0xa084, 0xff00, 0xa086,
+ 0x0600, 0x00c0, 0x33b6, 0x6014, 0x20a2, 0x94a0, 0x6010, 0x8007,
+ 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108, 0xa182,
+ 0x00ff, 0x0040, 0x33c1, 0xa386, 0x002a, 0x0040, 0x33ca, 0x0078,
+ 0x3397, 0x83ff, 0x00c0, 0x33c8, 0x7120, 0x810c, 0x0078, 0x279f,
+ 0x702f, 0x0001, 0x711e, 0x7020, 0xa300, 0x7022, 0x2061, 0x88d1,
+ 0x6007, 0x0000, 0x6312, 0x7024, 0x600e, 0x6426, 0x652a, 0x662e,
+ 0x6732, 0x2c10, 0x1078, 0x137b, 0x7007, 0x0002, 0x701b, 0x33e1,
+ 0x007c, 0x702c, 0xa005, 0x00c0, 0x33f2, 0x711c, 0x7024, 0x20a0,
+ 0x2019, 0x0000, 0x2061, 0x88d1, 0x6424, 0x6528, 0x662c, 0x6730,
+ 0x0078, 0x3397, 0x7120, 0x810c, 0x0078, 0x279f, 0x81ff, 0x00c0,
+ 0x27c9, 0x60c0, 0xd09c, 0x0040, 0x27c9, 0x1078, 0x3119, 0x0040,
+ 0x27c9, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3163,
+ 0x701b, 0x340b, 0x007c, 0x0d7e, 0xade8, 0x000d, 0x6828, 0xa0be,
+ 0x7000, 0x0040, 0x341e, 0xa0be, 0x7100, 0x0040, 0x341e, 0xa0be,
+ 0x7200, 0x0040, 0x341e, 0x0d7f, 0x0078, 0x27cd, 0x6820, 0x6924,
+ 0x1078, 0x2245, 0x00c0, 0x3447, 0x1078, 0x3f53, 0x00c0, 0x3447,
+ 0x7122, 0x6612, 0x6516, 0x6e18, 0x0c7e, 0x1078, 0x3119, 0x0040,
+ 0x3447, 0x1078, 0x3119, 0x0040, 0x3447, 0x0c7f, 0x0d7f, 0x6837,
+ 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x1078, 0x7964,
+ 0x0040, 0x27c9, 0x7007, 0x0003, 0x701b, 0x344a, 0x007c, 0x0d7f,
+ 0x0078, 0x27c9, 0x7120, 0x1078, 0x3f76, 0x6820, 0xa086, 0x8001,
+ 0x0040, 0x27c9, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002, 0x007e,
+ 0x20a9, 0x002a, 0x2098, 0x20a0, 0x1078, 0x3cbc, 0x007f, 0xade8,
+ 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0x88d1, 0x6007,
+ 0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x00c0, 0x3471, 0x0078,
+ 0x3475, 0xa7c6, 0x7100, 0x00c0, 0x347d, 0xa6c2, 0x0004, 0x0048,
+ 0x27cd, 0x2009, 0x0004, 0x0078, 0x3167, 0xa7c6, 0x7200, 0x00c0,
+ 0x27cd, 0xa6c2, 0x0054, 0x0048, 0x27cd, 0x600e, 0x6013, 0x002a,
+ 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x137b, 0x7007,
+ 0x0002, 0x701b, 0x3494, 0x007c, 0x701c, 0x2068, 0x6804, 0xa080,
+ 0x0001, 0x2004, 0xa080, 0x0002, 0x007e, 0x20a9, 0x002a, 0x2098,
+ 0x20a0, 0x1078, 0x3cbc, 0x007f, 0x2009, 0x002a, 0x2061, 0x88d1,
+ 0x6224, 0x6328, 0x642c, 0x6530, 0x0078, 0x3167, 0x81ff, 0x00c0,
+ 0x27c9, 0x1078, 0x3131, 0x0040, 0x27cd, 0x1078, 0x4017, 0x0040,
+ 0x27c9, 0x1078, 0x4180, 0x0078, 0x279f, 0x7824, 0xd084, 0x0040,
+ 0x2d64, 0x1078, 0x3143, 0x0040, 0x27cd, 0x0c7e, 0x1078, 0x3119,
+ 0x0c7f, 0x00c0, 0x34cf, 0x2009, 0x0002, 0x0078, 0x27c9, 0x6004,
+ 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x34f8, 0x2001, 0x8852,
+ 0x2004, 0xd0b4, 0x0040, 0x2d99, 0x6000, 0xd08c, 0x00c0, 0x2d99,
+ 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x7980, 0x00c0,
+ 0x34ed, 0x2009, 0x0003, 0x0078, 0x27c9, 0x7007, 0x0003, 0x701b,
+ 0x34f2, 0x007c, 0x1078, 0x3143, 0x0040, 0x27cd, 0x0078, 0x2d99,
+ 0x2009, 0x882d, 0x210c, 0x81ff, 0x0040, 0x3502, 0x2009, 0x0001,
+ 0x0078, 0x27c9, 0x2001, 0x8800, 0x2004, 0xa086, 0x0003, 0x0040,
+ 0x350d, 0x2009, 0x0007, 0x0078, 0x27c9, 0x2001, 0x8852, 0x2004,
+ 0xd0ac, 0x0040, 0x3517, 0x2009, 0x0008, 0x0078, 0x27c9, 0x609c,
+ 0xd0a4, 0x00c0, 0x351e, 0xd0ac, 0x00c0, 0x2d99, 0x6837, 0x0000,
+ 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x79ed, 0x00c0,
+ 0x352d, 0x2009, 0x0003, 0x0078, 0x27c9, 0x7007, 0x0003, 0x701b,
+ 0x3532, 0x007c, 0x6830, 0xa086, 0x0100, 0x00c0, 0x353b, 0x2009,
+ 0x0004, 0x0078, 0x27c9, 0x1078, 0x3143, 0x0040, 0x27cd, 0x0078,
+ 0x34d6, 0x127e, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0x8800,
+ 0x6044, 0xd0a4, 0x00c0, 0x356a, 0xd084, 0x0040, 0x3553, 0x1078,
+ 0x36c6, 0x0078, 0x3566, 0xd08c, 0x0040, 0x355a, 0x1078, 0x35dd,
+ 0x0078, 0x3566, 0xd094, 0x0040, 0x3561, 0x1078, 0x35b1, 0x0078,
+ 0x3566, 0xd09c, 0x0040, 0x3566, 0x1078, 0x3574, 0x0e7f, 0x0c7f,
+ 0x127f, 0x007c, 0x017e, 0x6128, 0xd19c, 0x00c0, 0x3571, 0xc19d,
+ 0x612a, 0x017f, 0x0078, 0x3566, 0x624c, 0xa286, 0xf0f0, 0x00c0,
+ 0x3585, 0x6048, 0xa086, 0xf0f0, 0x0040, 0x3585, 0x624a, 0x6043,
+ 0x0090, 0x6043, 0x0010, 0x0078, 0x35b0, 0xa294, 0xff00, 0xa296,
+ 0xf700, 0x0040, 0x3596, 0x6240, 0xa294, 0x0010, 0x0040, 0x3596,
+ 0x2009, 0x00f7, 0x1078, 0x3cdc, 0x0078, 0x35b0, 0x6043, 0x0040,
+ 0x6043, 0x0000, 0x7073, 0x0000, 0x708b, 0x0001, 0x70ab, 0x0000,
+ 0x70c3, 0x0000, 0x2009, 0x8ec0, 0x200b, 0x0000, 0x7083, 0x0000,
+ 0x7077, 0x000f, 0x2009, 0x000f, 0x2011, 0x3c2e, 0x1078, 0x5181,
+ 0x007c, 0x157e, 0x7074, 0xa005, 0x00c0, 0x35db, 0x2011, 0x3c2e,
+ 0x1078, 0x50f2, 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042,
+ 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x00c0, 0x35d4, 0x00f0, 0x35c2,
+ 0x6242, 0x7087, 0x0000, 0x6040, 0xa094, 0x0010, 0xa285, 0x0080,
+ 0x6042, 0x6242, 0x0078, 0x35db, 0x6242, 0x7087, 0x0000, 0x707b,
+ 0x0000, 0x0078, 0x35db, 0x157f, 0x007c, 0x7078, 0xa08a, 0x0003,
+ 0x00c8, 0x35e6, 0x1079, 0x35e9, 0x0078, 0x35e8, 0x1078, 0x12d2,
+ 0x007c, 0x35ec, 0x363b, 0x36c5, 0x0f7e, 0x707b, 0x0001, 0x20e1,
+ 0xa000, 0x20e1, 0x8700, 0x1078, 0x1f57, 0x20e1, 0x9080, 0x20e1,
+ 0x4000, 0x2079, 0x8d00, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b,
+ 0x0000, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b,
+ 0x0000, 0x781f, 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b,
+ 0x0000, 0x782f, 0x0000, 0x2079, 0x8d0c, 0x207b, 0x1101, 0x7807,
+ 0x0000, 0x2099, 0x8805, 0x20a1, 0x8d0e, 0x20a9, 0x0004, 0x53a3,
+ 0x2079, 0x8d12, 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0x8d00,
+ 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f,
+ 0x0000, 0x1078, 0x3c5a, 0x0f7f, 0x707f, 0x0000, 0x6043, 0x0008,
+ 0x6043, 0x0000, 0x007c, 0x0d7e, 0x707c, 0x707f, 0x0000, 0xa025,
+ 0x0040, 0x36af, 0x6020, 0xd0b4, 0x00c0, 0x36ad, 0x7188, 0x81ff,
+ 0x0040, 0x3696, 0xa486, 0x000c, 0x00c0, 0x36a1, 0xa480, 0x0018,
+ 0x8004, 0x20a8, 0x2011, 0x8d80, 0x2019, 0x8d00, 0x220c, 0x2304,
+ 0xa106, 0x00c0, 0x366d, 0x8210, 0x8318, 0x00f0, 0x3656, 0x6043,
+ 0x0004, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x707b,
+ 0x0002, 0x7087, 0x0002, 0x0078, 0x36ad, 0x2069, 0x8d80, 0x6930,
+ 0xa18e, 0x1101, 0x00c0, 0x36a1, 0x6834, 0xa005, 0x00c0, 0x36a1,
+ 0x6900, 0xa18c, 0x00ff, 0x00c0, 0x3681, 0x6804, 0xa005, 0x0040,
+ 0x3696, 0x2011, 0x8d8e, 0x2019, 0x8805, 0x20a9, 0x0004, 0x220c,
+ 0x2304, 0xa102, 0x0048, 0x3694, 0x00c0, 0x36a1, 0x8210, 0x8318,
+ 0x00f0, 0x3687, 0x0078, 0x36a1, 0x708b, 0x0000, 0x20e1, 0x9080,
+ 0x20e1, 0x4000, 0x2099, 0x8d80, 0x20a1, 0x020b, 0x20a9, 0x0014,
+ 0x53a6, 0x6043, 0x0008, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0,
+ 0x36ad, 0x60c3, 0x000c, 0x1078, 0x3c5a, 0x0d7f, 0x007c, 0x6020,
+ 0xd0b4, 0x00c0, 0x36ad, 0x60c3, 0x000c, 0x2011, 0x8aac, 0x2013,
+ 0x0000, 0x707f, 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7,
+ 0x9575, 0x1078, 0x6229, 0x0078, 0x36ad, 0x007c, 0x7084, 0xa08a,
+ 0x001d, 0x00c8, 0x36cf, 0x1079, 0x36d2, 0x0078, 0x36d1, 0x1078,
+ 0x12d2, 0x007c, 0x36fc, 0x370b, 0x373c, 0x3751, 0x3781, 0x37ad,
+ 0x37dd, 0x3813, 0x3843, 0x386b, 0x38b4, 0x38de, 0x3902, 0x3918,
+ 0x3940, 0x3953, 0x395c, 0x3988, 0x39b6, 0x39e2, 0x3a10, 0x3a46,
+ 0x3a8f, 0x3abe, 0x3ae0, 0x3b22, 0x3b48, 0x3b61, 0x3b62, 0x0c7e,
+ 0x2061, 0x8800, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084,
+ 0xfff9, 0x6006, 0x0c7f, 0x007c, 0x608b, 0xbc94, 0x608f, 0xf0f0,
+ 0x6043, 0x0002, 0x7087, 0x0001, 0x2009, 0x07d0, 0x2011, 0x3c35,
+ 0x1078, 0x50e5, 0x007c, 0x0f7e, 0x707c, 0xa086, 0x0014, 0x00c0,
+ 0x373a, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x373a, 0x2079,
+ 0x8d80, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x3738, 0x7834, 0xa005,
+ 0x00c0, 0x3738, 0x7a38, 0xd2fc, 0x0040, 0x372e, 0x70a8, 0xa005,
+ 0x00c0, 0x372e, 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x2011, 0x3c35,
+ 0x1078, 0x50f2, 0x7087, 0x0010, 0x1078, 0x395c, 0x0078, 0x373a,
+ 0x707f, 0x0000, 0x0f7f, 0x007c, 0x7087, 0x0003, 0x6043, 0x0004,
+ 0x1078, 0x3cc4, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9, 0x000a,
+ 0x20a3, 0x0000, 0x00f0, 0x3748, 0x60c3, 0x0014, 0x1078, 0x3c5a,
+ 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x377f, 0x2011, 0x3c35,
+ 0x1078, 0x50f2, 0xa086, 0x0014, 0x00c0, 0x377b, 0x2079, 0x8d80,
+ 0x7a30, 0xa296, 0x1102, 0x00c0, 0x377b, 0x7834, 0xa005, 0x00c0,
+ 0x377b, 0x7a38, 0xd2fc, 0x0040, 0x3775, 0x70a8, 0xa005, 0x00c0,
+ 0x3775, 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x7087, 0x0004, 0x1078,
+ 0x3781, 0x0078, 0x377f, 0x7087, 0x0002, 0x707f, 0x0000, 0x0f7f,
+ 0x007c, 0x7087, 0x0005, 0x1078, 0x3cc4, 0x20a3, 0x1103, 0x20a3,
+ 0x0000, 0x3430, 0x2011, 0x8d8e, 0x1078, 0x3d0d, 0x00c0, 0x379f,
+ 0x7070, 0xa005, 0x00c0, 0x379f, 0x714c, 0xa186, 0xffff, 0x0040,
+ 0x379f, 0x1078, 0x3bf9, 0x0040, 0x379f, 0x1078, 0x3cf3, 0x20a9,
+ 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x60c3, 0x0014, 0x1078, 0x3c5a, 0x007c, 0x0f7e, 0x707c, 0xa005,
+ 0x0040, 0x37db, 0x2011, 0x3c35, 0x1078, 0x50f2, 0xa086, 0x0014,
+ 0x00c0, 0x37d7, 0x2079, 0x8d80, 0x7a30, 0xa296, 0x1103, 0x00c0,
+ 0x37d7, 0x7834, 0xa005, 0x00c0, 0x37d7, 0x7a38, 0xd2fc, 0x0040,
+ 0x37d1, 0x70a8, 0xa005, 0x00c0, 0x37d1, 0x1078, 0x3cf3, 0x70ab,
+ 0x0001, 0x7087, 0x0006, 0x1078, 0x37dd, 0x0078, 0x37db, 0x7087,
+ 0x0002, 0x707f, 0x0000, 0x0f7f, 0x007c, 0x7087, 0x0007, 0x1078,
+ 0x3cc4, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0x8d8e,
+ 0x1078, 0x3d0d, 0x00c0, 0x3805, 0x7070, 0xa005, 0x00c0, 0x3805,
+ 0x7150, 0xa186, 0xffff, 0x0040, 0x3805, 0xa180, 0x25b2, 0x200c,
+ 0xa18c, 0xff00, 0x810f, 0x1078, 0x3bf9, 0x0040, 0x3805, 0x1078,
+ 0x3359, 0x0040, 0x3805, 0x1078, 0x2262, 0x20a9, 0x0008, 0x2298,
+ 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+ 0x1078, 0x3c5a, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3841,
+ 0x2011, 0x3c35, 0x1078, 0x50f2, 0xa086, 0x0014, 0x00c0, 0x383d,
+ 0x2079, 0x8d80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x383d, 0x7834,
+ 0xa005, 0x00c0, 0x383d, 0x7a38, 0xd2fc, 0x0040, 0x3837, 0x70a8,
+ 0xa005, 0x00c0, 0x3837, 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x7087,
+ 0x0008, 0x1078, 0x3843, 0x0078, 0x3841, 0x7087, 0x0002, 0x707f,
+ 0x0000, 0x0f7f, 0x007c, 0x7087, 0x0009, 0x1078, 0x3cc4, 0x20a3,
+ 0x1105, 0x20a3, 0x0100, 0x3430, 0x1078, 0x3d0d, 0x00c0, 0x385c,
+ 0x7070, 0xa005, 0x00c0, 0x385c, 0x1078, 0x3b63, 0x00c0, 0x3866,
+ 0xa085, 0x0001, 0x1078, 0x2262, 0x20a9, 0x0008, 0x2099, 0x8d8e,
+ 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+ 0x1078, 0x3c5a, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x38b2,
+ 0x2011, 0x3c35, 0x1078, 0x50f2, 0xa086, 0x0014, 0x00c0, 0x38ae,
+ 0x2079, 0x8d80, 0x7a30, 0xa296, 0x1105, 0x00c0, 0x38ae, 0x7834,
+ 0x2011, 0x0100, 0xa21e, 0x00c0, 0x3897, 0x7a38, 0xd2fc, 0x0040,
+ 0x3891, 0x70a8, 0xa005, 0x00c0, 0x3891, 0x1078, 0x3cf3, 0x70ab,
+ 0x0001, 0x7087, 0x000a, 0x1078, 0x38b4, 0x0078, 0x38b2, 0xa005,
+ 0x00c0, 0x38ae, 0x7a38, 0xd2fc, 0x0040, 0x38a6, 0x70a8, 0xa005,
+ 0x00c0, 0x38a6, 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x7083, 0x0000,
+ 0x7087, 0x000e, 0x1078, 0x3940, 0x0078, 0x38b2, 0x7087, 0x0002,
+ 0x707f, 0x0000, 0x0f7f, 0x007c, 0x7087, 0x000b, 0x2011, 0x8d0e,
+ 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002,
+ 0x2009, 0x0000, 0x41a4, 0x1078, 0x3cc4, 0x20a3, 0x1106, 0x20a3,
+ 0x0000, 0x1078, 0x3d0d, 0x0040, 0x38d1, 0x2013, 0x0000, 0x0078,
+ 0x38d5, 0x6030, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042,
+ 0x53a6, 0x60c3, 0x0084, 0x1078, 0x3c5a, 0x007c, 0x0f7e, 0x707c,
+ 0xa005, 0x0040, 0x3900, 0x2011, 0x3c35, 0x1078, 0x50f2, 0xa086,
+ 0x0084, 0x00c0, 0x38fc, 0x2079, 0x8d80, 0x7a30, 0xa296, 0x1106,
+ 0x00c0, 0x38fc, 0x7834, 0xa005, 0x00c0, 0x38fc, 0x7087, 0x000c,
+ 0x1078, 0x3902, 0x0078, 0x3900, 0x7087, 0x0002, 0x707f, 0x0000,
+ 0x0f7f, 0x007c, 0x7087, 0x000d, 0x1078, 0x3cc4, 0x20a3, 0x1107,
+ 0x20a3, 0x0000, 0x2099, 0x8d8e, 0x20a9, 0x0040, 0x53a6, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x1078, 0x3c5a, 0x007c,
+ 0x0f7e, 0x707c, 0xa005, 0x0040, 0x393e, 0x2011, 0x3c35, 0x1078,
+ 0x50f2, 0xa086, 0x0084, 0x00c0, 0x393a, 0x2079, 0x8d80, 0x7a30,
+ 0xa296, 0x1107, 0x00c0, 0x393a, 0x7834, 0xa005, 0x00c0, 0x393a,
+ 0x7083, 0x0001, 0x1078, 0x3cb6, 0x7087, 0x000e, 0x1078, 0x3940,
+ 0x0078, 0x393e, 0x7087, 0x0002, 0x707f, 0x0000, 0x0f7f, 0x007c,
+ 0x7087, 0x000f, 0x707f, 0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5,
+ 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x3c35,
+ 0x1078, 0x50e5, 0x007c, 0x707c, 0xa005, 0x0040, 0x395b, 0x2011,
+ 0x3c35, 0x1078, 0x50f2, 0x007c, 0x7087, 0x0011, 0x7168, 0x81ff,
+ 0x0040, 0x3971, 0x2009, 0x0000, 0x706c, 0xa084, 0x00ff, 0x1078,
+ 0x2245, 0xa186, 0x0080, 0x0040, 0x3971, 0x2011, 0x8d8e, 0x1078,
+ 0x3bf9, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x8d80, 0x20a1,
+ 0x020b, 0x747c, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8,
+ 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, 0x1078, 0x3c5a, 0x007c,
+ 0x0f7e, 0x707c, 0xa005, 0x0040, 0x39b4, 0x2011, 0x3c35, 0x1078,
+ 0x50f2, 0xa086, 0x0014, 0x00c0, 0x39b2, 0x2079, 0x8d80, 0x7a30,
+ 0xa296, 0x1103, 0x00c0, 0x39b2, 0x7834, 0xa005, 0x00c0, 0x39b2,
+ 0x7a38, 0xd2fc, 0x0040, 0x39ac, 0x70a8, 0xa005, 0x00c0, 0x39ac,
+ 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x7087, 0x0012, 0x1078, 0x39b6,
+ 0x0078, 0x39b4, 0x707f, 0x0000, 0x0f7f, 0x007c, 0x7087, 0x0013,
+ 0x1078, 0x3cd0, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011,
+ 0x8d8e, 0x1078, 0x3d0d, 0x00c0, 0x39d4, 0x7070, 0xa005, 0x00c0,
+ 0x39d4, 0x714c, 0xa186, 0xffff, 0x0040, 0x39d4, 0x1078, 0x3bf9,
+ 0x0040, 0x39d4, 0x1078, 0x3cf3, 0x20a9, 0x0008, 0x2298, 0x26a0,
0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078,
- 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x3398, 0x2011,
- 0x3558, 0x1078, 0x4689, 0xa086, 0x0014, 0x00c0, 0x3396, 0x2079,
- 0x7c80, 0x7a30, 0xa296, 0x1105, 0x00c0, 0x3396, 0x7834, 0x2011,
- 0x0100, 0xa21e, 0x00c0, 0x337f, 0x7a38, 0xd2f4, 0x0040, 0x3372,
- 0x70bf, 0x0008, 0xd2fc, 0x0040, 0x337d, 0x70a4, 0xa005, 0x00c0,
- 0x337d, 0x1078, 0x3611, 0x70a7, 0x0001, 0x0078, 0x3390, 0xa005,
- 0x00c0, 0x3396, 0x7a38, 0xd2fc, 0x0040, 0x338e, 0x70a4, 0xa005,
- 0x00c0, 0x338e, 0x1078, 0x3611, 0x70a7, 0x0001, 0x707f, 0x0000,
- 0x7083, 0x0016, 0x1078, 0x339a, 0x0078, 0x3398, 0x707b, 0x0000,
- 0x0f7f, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x7c80,
- 0x20a1, 0x020b, 0x20a9, 0x000e, 0x53a6, 0x3430, 0x2011, 0x7c8e,
- 0x7083, 0x0017, 0x0078, 0x33ae, 0x7083, 0x001b, 0x706c, 0xa005,
- 0x00c0, 0x33b8, 0x1078, 0x3486, 0x0040, 0x33c8, 0x0078, 0x33c2,
- 0x20a9, 0x0008, 0x2099, 0x7c8e, 0x26a0, 0x53a6, 0x20a3, 0x0000,
- 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x3578, 0x0078, 0x33ca,
- 0x1078, 0x303e, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x33eb,
- 0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0084, 0x00c0, 0x33e9,
- 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x33e9, 0x7834,
- 0xa005, 0x00c0, 0x33e9, 0x7083, 0x0018, 0x1078, 0x33ed, 0x0078,
- 0x33eb, 0x707b, 0x0000, 0x0f7f, 0x007c, 0x7083, 0x0019, 0x1078,
- 0x35ee, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x3430, 0x2099, 0x7c8e,
- 0x2039, 0x7c0e, 0x27a0, 0x20a9, 0x0040, 0x53a3, 0x2728, 0x2514,
- 0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007,
- 0xa205, 0x202a, 0x6030, 0x2310, 0x8214, 0xa2a0, 0x7c0e, 0x2414,
- 0xa38c, 0x0001, 0x0040, 0x3418, 0xa294, 0xff00, 0x0078, 0x341b,
- 0xa294, 0x00ff, 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9,
- 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084,
- 0x1078, 0x3578, 0x007c, 0x0f7e, 0x7078, 0xa005, 0x0040, 0x344f,
- 0x2011, 0x3558, 0x1078, 0x4689, 0xa086, 0x0084, 0x00c0, 0x344d,
- 0x2079, 0x7c80, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x344d, 0x7834,
- 0xa005, 0x00c0, 0x344d, 0x707f, 0x0001, 0x1078, 0x35d4, 0x7083,
- 0x001a, 0x1078, 0x3451, 0x0078, 0x344f, 0x707b, 0x0000, 0x0f7f,
- 0x007c, 0x7083, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
- 0x7c80, 0x20a1, 0x020b, 0x7478, 0xa480, 0x0018, 0xa080, 0x0007,
- 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078,
- 0x3578, 0x007c, 0x7078, 0xa005, 0x0040, 0x3476, 0x2011, 0x3558,
- 0x1078, 0x4689, 0x7083, 0x001c, 0x1078, 0x3477, 0x007c, 0x707b,
- 0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5, 0x6043, 0x0001, 0x2009,
- 0x07d0, 0x2011, 0x3558, 0x1078, 0x467c, 0x007c, 0x087e, 0x097e,
- 0x2029, 0x7752, 0x252c, 0x20a9, 0x0008, 0x2041, 0x7c0e, 0x28a0,
- 0x2099, 0x7c8e, 0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4,
- 0x0040, 0x349c, 0x2011, 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6,
- 0xffff, 0x00c0, 0x34ae, 0xd5d4, 0x0040, 0x34a9, 0x8210, 0x0078,
- 0x34aa, 0x8211, 0x00f0, 0x349c, 0x0078, 0x3513, 0x82ff, 0x00c0,
- 0x34c0, 0xd5d4, 0x0040, 0x34ba, 0xa1a6, 0x3fff, 0x0040, 0x34a6,
- 0x0078, 0x34be, 0xa1a6, 0x3fff, 0x0040, 0x3513, 0xa18d, 0xc000,
- 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0040, 0x34c9, 0x2019,
- 0x0010, 0x2120, 0xd5d4, 0x0040, 0x34d0, 0x8423, 0x0078, 0x34d1,
- 0x8424, 0x00c8, 0x34de, 0xd5d4, 0x0040, 0x34d9, 0x8319, 0x0078,
- 0x34da, 0x8318, 0x00f0, 0x34ca, 0x0078, 0x3513, 0x23a8, 0x2021,
- 0x0001, 0x8426, 0x8425, 0x00f0, 0x34e2, 0x2328, 0x8529, 0xa2be,
- 0x0007, 0x0040, 0x34f6, 0x007e, 0x2039, 0x0007, 0x2200, 0xa73a,
- 0x007f, 0x27a8, 0xa5a8, 0x0010, 0x00f0, 0x34f2, 0x754e, 0xa5c8,
- 0x2329, 0x292c, 0xa5ac, 0x00ff, 0x6532, 0x60e7, 0x0000, 0x65ea,
- 0x2018, 0x2304, 0xa405, 0x201a, 0x706f, 0x0001, 0x26a0, 0x2898,
- 0x20a9, 0x0008, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085,
- 0x0001, 0x0078, 0x3519, 0xa006, 0x0078, 0x3519, 0xa006, 0x1078,
- 0x12cd, 0x097f, 0x087f, 0x007c, 0x2118, 0x2021, 0x0000, 0x2001,
- 0x0007, 0xa39a, 0x0010, 0x0048, 0x3529, 0x8420, 0x8001, 0x0078,
- 0x3521, 0x2118, 0x84ff, 0x0040, 0x3532, 0xa39a, 0x0010, 0x8421,
- 0x00c0, 0x352d, 0x2021, 0x0001, 0x83ff, 0x0040, 0x353b, 0x8423,
- 0x8319, 0x00c0, 0x3537, 0xa238, 0x2704, 0xa42c, 0x00c0, 0x3550,
- 0xa405, 0x203a, 0x714e, 0xa1a0, 0x2329, 0x242c, 0xa5ac, 0x00ff,
- 0x6532, 0x60e7, 0x0000, 0x65ea, 0x706f, 0x0001, 0xa084, 0x0000,
- 0x007c, 0x0e7e, 0x2071, 0x7700, 0x7073, 0x0000, 0x0e7f, 0x007c,
- 0x0e7e, 0x0f7e, 0x2079, 0x0100, 0x2071, 0x0140, 0x1078, 0x569c,
- 0x7004, 0xa084, 0x4000, 0x0040, 0x3569, 0x7003, 0x1000, 0x7003,
- 0x0000, 0x127e, 0x2091, 0x8000, 0x2071, 0x7720, 0x2073, 0x0000,
- 0x7843, 0x0090, 0x7843, 0x0010, 0x127f, 0x0f7f, 0x0e7f, 0x007c,
- 0x127e, 0x2091, 0x8000, 0x2011, 0x7940, 0x2013, 0x0000, 0x707b,
- 0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575,
- 0x1078, 0x5693, 0x2009, 0x07d0, 0x2011, 0x3558, 0x1078, 0x4719,
- 0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x2009,
- 0x00f7, 0x1078, 0x35fa, 0x2061, 0x7949, 0x601b, 0x0000, 0x601f,
- 0x0000, 0x2061, 0x7700, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043,
- 0x0090, 0x6043, 0x0010, 0x2009, 0x001e, 0x2011, 0x35b6, 0x1078,
- 0x467c, 0x127f, 0x0c7f, 0x027f, 0x017f, 0x007c, 0x0e7e, 0x007e,
- 0x127e, 0x2091, 0x8000, 0x2071, 0x0100, 0x1078, 0x569c, 0x2071,
- 0x0140, 0x7004, 0xa084, 0x4000, 0x0040, 0x35ca, 0x7003, 0x1000,
- 0x7003, 0x0000, 0x2001, 0x0001, 0x1078, 0x2025, 0x1078, 0x3591,
- 0x127f, 0x007f, 0x0e7f, 0x007c, 0x20a9, 0x0040, 0x20a1, 0x7dc0,
- 0x2099, 0x7c8e, 0x3304, 0x8007, 0x20a2, 0x9398, 0x94a0, 0x00f0,
- 0x35da, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x7c00,
- 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c, 0x20e1, 0x9080,
- 0x20e1, 0x4000, 0x2099, 0x7c80, 0x20a1, 0x020b, 0x20a9, 0x000c,
- 0x53a6, 0x007c, 0x0c7e, 0x007e, 0x2061, 0x0100, 0x810f, 0x2001,
- 0x772c, 0x2004, 0xa005, 0x00c0, 0x360b, 0x6030, 0xa084, 0x00ff,
- 0xa105, 0x0078, 0x360d, 0xa185, 0x00f7, 0x604a, 0x007f, 0x0c7f,
- 0x007c, 0x017e, 0x047e, 0x2001, 0x7752, 0x2004, 0xd0a4, 0x0040,
- 0x3624, 0xa006, 0x2020, 0x2009, 0x002a, 0x1078, 0x7641, 0x2001,
- 0x770c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x1078, 0x2293,
- 0x047f, 0x017f, 0x007c, 0x157e, 0x20a9, 0x00ff, 0x2009, 0x7820,
- 0xa006, 0x200a, 0x8108, 0x00f0, 0x3631, 0x157f, 0x007c, 0x0d7e,
- 0x037e, 0x157e, 0x137e, 0x147e, 0x2069, 0x7751, 0xa006, 0x6002,
- 0x6007, 0x0707, 0x600a, 0x600e, 0x6012, 0xa198, 0x2329, 0x231c,
- 0xa39c, 0x00ff, 0x6316, 0x20a9, 0x0004, 0xac98, 0x0006, 0x23a0,
- 0x40a4, 0x20a9, 0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4, 0x603e,
- 0x6042, 0x604e, 0x6052, 0x6056, 0x605a, 0x605e, 0x6062, 0x6066,
- 0x606a, 0x606e, 0x6072, 0x6076, 0x607a, 0x607e, 0x6082, 0x6086,
- 0x608a, 0x608e, 0x6092, 0x6096, 0x609a, 0x609e, 0x61a2, 0x0d7e,
- 0x60a4, 0xa06d, 0x0040, 0x3676, 0x1078, 0x1340, 0x60a7, 0x0000,
- 0x60a8, 0xa06d, 0x0040, 0x367e, 0x1078, 0x1340, 0x60ab, 0x0000,
- 0x0d7f, 0xa006, 0x604a, 0x6810, 0x603a, 0x680c, 0x6046, 0x6814,
- 0xa084, 0x00ff, 0x6042, 0x147f, 0x137f, 0x157f, 0x037f, 0x0d7f,
- 0x007c, 0x127e, 0x2091, 0x8000, 0x6944, 0x6e48, 0xa684, 0x3fff,
- 0xa082, 0x4000, 0x00c8, 0x3737, 0xa18c, 0xff00, 0x810f, 0xa182,
- 0x00ff, 0x00c8, 0x373d, 0x2001, 0x770c, 0x2004, 0xa084, 0x0003,
- 0x00c0, 0x3720, 0xa188, 0x7820, 0x2104, 0xa065, 0x0040, 0x370e,
- 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x3714, 0x60a4,
- 0xa00d, 0x0040, 0x36bf, 0x1078, 0x3a5c, 0x0040, 0x3708, 0x60a8,
- 0xa00d, 0x0040, 0x36d9, 0x1078, 0x3aac, 0x00c0, 0x36d9, 0x694c,
- 0xd1fc, 0x00c0, 0x36cf, 0x1078, 0x37d1, 0x0078, 0x3703, 0x1078,
- 0x37a2, 0x694c, 0xd1ec, 0x00c0, 0x3703, 0x1078, 0x3931, 0x0078,
- 0x3703, 0x694c, 0xa184, 0xa000, 0x0040, 0x36f3, 0xd1ec, 0x0040,
- 0x36ec, 0xd1fc, 0x0040, 0x36e8, 0x1078, 0x3942, 0x0078, 0x36ef,
- 0x1078, 0x3942, 0x0078, 0x36f3, 0xd1fc, 0x0040, 0x36f3, 0x1078,
- 0x37a2, 0x0078, 0x3703, 0x6050, 0xa00d, 0x0040, 0x36fe, 0x2d00,
- 0x200a, 0x6803, 0x0000, 0x6052, 0x0078, 0x3703, 0x2d00, 0x6052,
- 0x604e, 0x6803, 0x0000, 0x1078, 0x4960, 0xa006, 0x127f, 0x007c,
- 0x2001, 0x0005, 0x2009, 0x0000, 0x0078, 0x3741, 0x2001, 0x0028,
- 0x2009, 0x0000, 0x0078, 0x3741, 0xa082, 0x0006, 0x00c8, 0x3720,
- 0x60a0, 0xd0bc, 0x0040, 0x36b7, 0x2001, 0x0028, 0x0078, 0x3733,
- 0x2009, 0x770c, 0x210c, 0xd18c, 0x0040, 0x372a, 0x2001, 0x0004,
- 0x0078, 0x3733, 0xd184, 0x0040, 0x3731, 0x2001, 0x0004, 0x0078,
- 0x3733, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x3741, 0x2001,
- 0x0029, 0x2009, 0x0000, 0x0078, 0x3741, 0x2001, 0x0029, 0x2009,
- 0x0000, 0xa005, 0x127f, 0x007c, 0x6944, 0x6e48, 0xa684, 0x3fff,
- 0xa082, 0x4000, 0x00c8, 0x3787, 0xa18c, 0xff00, 0x810f, 0xa182,
- 0x00ff, 0x00c8, 0x3777, 0xa188, 0x7820, 0x2104, 0xa065, 0x0040,
- 0x3777, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x377d,
- 0x684c, 0xd0ec, 0x0040, 0x376a, 0x1078, 0x3942, 0x1078, 0x37a2,
- 0x0078, 0x3772, 0x1078, 0x37a2, 0x684c, 0xd0fc, 0x0040, 0x3772,
- 0x1078, 0x3931, 0x1078, 0x398a, 0xa006, 0x0078, 0x378b, 0x2001,
- 0x0028, 0x2009, 0x0000, 0x0078, 0x378b, 0xa082, 0x0006, 0x0048,
- 0x3760, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x378b, 0x2001,
- 0x0029, 0x2009, 0x0000, 0xa005, 0x007c, 0x127e, 0x2091, 0x8000,
- 0x6050, 0xa00d, 0x0040, 0x379b, 0x2d00, 0x200a, 0x6803, 0x0000,
- 0x6052, 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000,
- 0x0078, 0x3799, 0x127e, 0x2091, 0x8000, 0x604c, 0xa005, 0x0040,
- 0x37ae, 0x6802, 0x2d00, 0x604e, 0x127f, 0x007c, 0x2d00, 0x6052,
- 0x604e, 0x6803, 0x0000, 0x0078, 0x37ac, 0x127e, 0x2091, 0x8000,
- 0x604c, 0xa06d, 0x0040, 0x37c3, 0x6800, 0xa005, 0x00c0, 0x37c1,
- 0x6052, 0x604e, 0xad05, 0x127f, 0x007c, 0x604c, 0xa06d, 0x0040,
- 0x37d0, 0x6800, 0xa005, 0x00c0, 0x37ce, 0x6052, 0x604e, 0xad05,
- 0x007c, 0x6803, 0x0000, 0x6084, 0xa00d, 0x0040, 0x37db, 0x2d00,
- 0x200a, 0x6086, 0x007c, 0x2d00, 0x6086, 0x6082, 0x0078, 0x37da,
- 0x127e, 0x0c7e, 0x027e, 0x2091, 0x8000, 0x6218, 0x2260, 0x6200,
- 0xa005, 0x0040, 0x37ee, 0xc285, 0x0078, 0x37ef, 0xc284, 0x6202,
- 0x027f, 0x0c7f, 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000,
- 0x6218, 0x2260, 0x6204, 0xa294, 0xff00, 0xa215, 0x6206, 0x0c7f,
- 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260,
- 0x6204, 0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x0c7f, 0x127f,
- 0x007c, 0x027e, 0xa182, 0x00ff, 0x0048, 0x381a, 0xa085, 0x0001,
- 0x0078, 0x3832, 0xa190, 0x7820, 0x2204, 0xa065, 0x00c0, 0x3831,
- 0x017e, 0x0d7e, 0x1078, 0x130c, 0x2d60, 0x0d7f, 0x017f, 0x0040,
- 0x3816, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab, 0x0000, 0x1078,
- 0x3637, 0xa006, 0x027f, 0x007c, 0x027e, 0xa182, 0x00ff, 0x0048,
- 0x383d, 0xa085, 0x0001, 0x0078, 0x384a, 0x0d7e, 0xa190, 0x7820,
- 0x2204, 0xa06d, 0x0040, 0x3848, 0x2013, 0x0000, 0x1078, 0x1340,
- 0x0d7f, 0xa006, 0x027f, 0x007c, 0x017e, 0xa182, 0x00ff, 0x0048,
- 0x3855, 0xa085, 0x0001, 0x0078, 0x385c, 0xa188, 0x7820, 0x2104,
- 0xa065, 0x0040, 0x3851, 0xa006, 0x017f, 0x007c, 0x0d7e, 0x157e,
- 0x137e, 0x147e, 0x600b, 0x0000, 0x600f, 0x0000, 0x6000, 0xc08c,
- 0x6002, 0x2069, 0x7c8e, 0x6808, 0x605e, 0x6810, 0x6062, 0x6138,
- 0xa10a, 0x0048, 0x3874, 0x603a, 0x6814, 0x6066, 0x2099, 0x7c96,
- 0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, 0x7c9a,
- 0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, 0x7cae,
- 0x6808, 0x606a, 0x690c, 0x616e, 0x6810, 0x6072, 0x6818, 0x6076,
- 0xa182, 0x0211, 0x00c8, 0x3898, 0x2009, 0x0008, 0x0078, 0x38c2,
- 0xa182, 0x0259, 0x00c8, 0x38a0, 0x2009, 0x0007, 0x0078, 0x38c2,
- 0xa182, 0x02c1, 0x00c8, 0x38a8, 0x2009, 0x0006, 0x0078, 0x38c2,
- 0xa182, 0x0349, 0x00c8, 0x38b0, 0x2009, 0x0005, 0x0078, 0x38c2,
- 0xa182, 0x0421, 0x00c8, 0x38b8, 0x2009, 0x0004, 0x0078, 0x38c2,
- 0xa182, 0x0581, 0x00c8, 0x38c0, 0x2009, 0x0003, 0x0078, 0x38c2,
- 0x2009, 0x0002, 0x6192, 0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c,
- 0x0e7e, 0x2071, 0x7c8d, 0x2e04, 0x6896, 0x2071, 0x7c8e, 0x7004,
- 0x689a, 0x701c, 0x689e, 0x0e7f, 0x007c, 0x0d7e, 0x127e, 0x2091,
- 0x8000, 0x60a4, 0xa06d, 0x0040, 0x38f9, 0x6900, 0x81ff, 0x00c0,
- 0x390d, 0x6a04, 0xa282, 0x0010, 0x00c8, 0x3912, 0xad88, 0x0004,
- 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0040, 0x38f4, 0x8108,
- 0x00f0, 0x38ea, 0x1078, 0x12cd, 0x260a, 0x8210, 0x6a06, 0x0078,
- 0x390d, 0x1078, 0x130c, 0x0040, 0x3912, 0x2d00, 0x60a6, 0x6803,
+ 0x3c5a, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3a0e, 0x2011,
+ 0x3c35, 0x1078, 0x50f2, 0xa086, 0x0014, 0x00c0, 0x3a0c, 0x2079,
+ 0x8d80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3a0c, 0x7834, 0xa005,
+ 0x00c0, 0x3a0c, 0x7a38, 0xd2fc, 0x0040, 0x3a06, 0x70a8, 0xa005,
+ 0x00c0, 0x3a06, 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x7087, 0x0014,
+ 0x1078, 0x3a10, 0x0078, 0x3a0e, 0x707f, 0x0000, 0x0f7f, 0x007c,
+ 0x7087, 0x0015, 0x1078, 0x3cd0, 0x20a3, 0x1104, 0x20a3, 0x0000,
+ 0x3430, 0x2011, 0x8d8e, 0x1078, 0x3d0d, 0x00c0, 0x3a38, 0x7070,
+ 0xa005, 0x00c0, 0x3a38, 0x7150, 0xa186, 0xffff, 0x0040, 0x3a38,
+ 0xa180, 0x25b2, 0x200c, 0xa18c, 0xff00, 0x810f, 0x1078, 0x3bf9,
+ 0x0040, 0x3a38, 0x1078, 0x3359, 0x0040, 0x3a38, 0x1078, 0x2262,
+ 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x60c3, 0x0014, 0x1078, 0x3c5a, 0x007c, 0x0f7e, 0x707c,
+ 0xa005, 0x0040, 0x3a8d, 0x2011, 0x3c35, 0x1078, 0x50f2, 0xa086,
+ 0x0014, 0x00c0, 0x3a8b, 0x2079, 0x8d80, 0x7a30, 0xa296, 0x1105,
+ 0x00c0, 0x3a8b, 0x7834, 0x2011, 0x0100, 0xa21e, 0x00c0, 0x3a6e,
+ 0x7a38, 0xd2fc, 0x0040, 0x3a6c, 0x70a8, 0xa005, 0x00c0, 0x3a6c,
+ 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x0078, 0x3a7f, 0xa005, 0x00c0,
+ 0x3a8b, 0x7a38, 0xd2fc, 0x0040, 0x3a7d, 0x70a8, 0xa005, 0x00c0,
+ 0x3a7d, 0x1078, 0x3cf3, 0x70ab, 0x0001, 0x7083, 0x0000, 0x7a38,
+ 0xd2f4, 0x0040, 0x3a85, 0x70c3, 0x0008, 0x7087, 0x0016, 0x1078,
+ 0x3a8f, 0x0078, 0x3a8d, 0x707f, 0x0000, 0x0f7f, 0x007c, 0x20e1,
+ 0x9080, 0x20e1, 0x4000, 0x2099, 0x8d80, 0x20a1, 0x020b, 0x20a9,
+ 0x000e, 0x53a6, 0x3430, 0x2011, 0x8d8e, 0x7087, 0x0017, 0x1078,
+ 0x3d0d, 0x00c0, 0x3aaf, 0x7070, 0xa005, 0x00c0, 0x3aaf, 0x1078,
+ 0x3b63, 0x00c0, 0x3ab9, 0xa085, 0x0001, 0x1078, 0x2262, 0x20a9,
+ 0x0008, 0x2099, 0x8d8e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x60c3, 0x0014, 0x1078, 0x3c5a, 0x007c, 0x0f7e, 0x707c,
+ 0xa005, 0x0040, 0x3ade, 0x2011, 0x3c35, 0x1078, 0x50f2, 0xa086,
+ 0x0084, 0x00c0, 0x3adc, 0x2079, 0x8d80, 0x7a30, 0xa296, 0x1106,
+ 0x00c0, 0x3adc, 0x7834, 0xa005, 0x00c0, 0x3adc, 0x7087, 0x0018,
+ 0x1078, 0x3ae0, 0x0078, 0x3ade, 0x707f, 0x0000, 0x0f7f, 0x007c,
+ 0x7087, 0x0019, 0x1078, 0x3cd0, 0x20a3, 0x1106, 0x20a3, 0x0000,
+ 0x3430, 0x2099, 0x8d8e, 0x2039, 0x8d0e, 0x27a0, 0x20a9, 0x0040,
+ 0x53a3, 0x1078, 0x3d0d, 0x00c0, 0x3b14, 0x2728, 0x2514, 0x8207,
+ 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007, 0xa205,
+ 0x202a, 0x6030, 0x2310, 0x8214, 0xa2a0, 0x8d0e, 0x2414, 0xa38c,
+ 0x0001, 0x0040, 0x3b0f, 0xa294, 0xff00, 0x0078, 0x3b12, 0xa294,
+ 0x00ff, 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040,
+ 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x1078,
+ 0x3c5a, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3b46, 0x2011,
+ 0x3c35, 0x1078, 0x50f2, 0xa086, 0x0084, 0x00c0, 0x3b44, 0x2079,
+ 0x8d80, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x3b44, 0x7834, 0xa005,
+ 0x00c0, 0x3b44, 0x7083, 0x0001, 0x1078, 0x3cb6, 0x7087, 0x001a,
+ 0x1078, 0x3b48, 0x0078, 0x3b46, 0x707f, 0x0000, 0x0f7f, 0x007c,
+ 0x7087, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x8d80,
+ 0x20a1, 0x020b, 0x747c, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084,
+ 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078, 0x3c5a,
+ 0x007c, 0x007c, 0x007c, 0x087e, 0x097e, 0x2029, 0x8852, 0x252c,
+ 0x20a9, 0x0008, 0x2041, 0x8d0e, 0x28a0, 0x2099, 0x8d8e, 0x53a3,
+ 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0040, 0x3b79, 0x2011,
+ 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x00c0, 0x3b8b,
+ 0xd5d4, 0x0040, 0x3b86, 0x8210, 0x0078, 0x3b87, 0x8211, 0x00f0,
+ 0x3b79, 0x0078, 0x3bf0, 0x82ff, 0x00c0, 0x3b9d, 0xd5d4, 0x0040,
+ 0x3b97, 0xa1a6, 0x3fff, 0x0040, 0x3b83, 0x0078, 0x3b9b, 0xa1a6,
+ 0x3fff, 0x0040, 0x3bf0, 0xa18d, 0xc000, 0x20a9, 0x0010, 0x2019,
+ 0x0001, 0xd5d4, 0x0040, 0x3ba6, 0x2019, 0x0010, 0x2120, 0xd5d4,
+ 0x0040, 0x3bad, 0x8423, 0x0078, 0x3bae, 0x8424, 0x00c8, 0x3bbb,
+ 0xd5d4, 0x0040, 0x3bb6, 0x8319, 0x0078, 0x3bb7, 0x8318, 0x00f0,
+ 0x3ba7, 0x0078, 0x3bf0, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425,
+ 0x00f0, 0x3bbf, 0x2328, 0x8529, 0xa2be, 0x0007, 0x0040, 0x3bd3,
+ 0x007e, 0x2039, 0x0007, 0x2200, 0xa73a, 0x007f, 0x27a8, 0xa5a8,
+ 0x0010, 0x00f0, 0x3bcf, 0x754e, 0xa5c8, 0x25b2, 0x292c, 0xa5ac,
+ 0x00ff, 0x6532, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0xa405,
+ 0x201a, 0x7073, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008, 0x53a6,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0078, 0x3bf6,
+ 0xa006, 0x0078, 0x3bf6, 0xa006, 0x1078, 0x12d2, 0x097f, 0x087f,
+ 0x007c, 0x2118, 0x2021, 0x0000, 0x2001, 0x0007, 0xa39a, 0x0010,
+ 0x0048, 0x3c06, 0x8420, 0x8001, 0x0078, 0x3bfe, 0x2118, 0x84ff,
+ 0x0040, 0x3c0f, 0xa39a, 0x0010, 0x8421, 0x00c0, 0x3c0a, 0x2021,
+ 0x0001, 0x83ff, 0x0040, 0x3c18, 0x8423, 0x8319, 0x00c0, 0x3c14,
+ 0xa238, 0x2704, 0xa42c, 0x00c0, 0x3c2d, 0xa405, 0x203a, 0x714e,
+ 0xa1a0, 0x25b2, 0x242c, 0xa5ac, 0x00ff, 0x6532, 0x60e7, 0x0000,
+ 0x65ea, 0x7073, 0x0001, 0xa084, 0x0000, 0x007c, 0x0e7e, 0x2071,
+ 0x8800, 0x7077, 0x0000, 0x0e7f, 0x007c, 0x0e7e, 0x0f7e, 0x2079,
+ 0x0100, 0x2071, 0x0140, 0x1078, 0x6232, 0x7004, 0xa084, 0x4000,
+ 0x0040, 0x3c46, 0x7003, 0x1000, 0x7003, 0x0000, 0x127e, 0x2091,
+ 0x8000, 0x2071, 0x8821, 0x2073, 0x0000, 0x7840, 0x027e, 0xa094,
+ 0x0010, 0xa285, 0x0080, 0x7842, 0x7a42, 0x027f, 0x127f, 0x0f7f,
+ 0x0e7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x2011, 0x8aac, 0x2013,
+ 0x0000, 0x707f, 0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3, 0x0056,
+ 0x60a7, 0x9575, 0x1078, 0x6229, 0x2009, 0x07d0, 0x2011, 0x3c35,
+ 0x1078, 0x5181, 0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e, 0x2091,
+ 0x8000, 0x2009, 0x00f7, 0x1078, 0x3cdc, 0x2061, 0x8ab5, 0x601b,
+ 0x0000, 0x601f, 0x0000, 0x2061, 0x8800, 0x6003, 0x0001, 0x2061,
+ 0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x001e, 0x2011,
+ 0x3c98, 0x1078, 0x50e5, 0x127f, 0x0c7f, 0x027f, 0x017f, 0x007c,
+ 0x0e7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x0100, 0x1078,
+ 0x6232, 0x2071, 0x0140, 0x7004, 0xa084, 0x4000, 0x0040, 0x3cac,
+ 0x7003, 0x1000, 0x7003, 0x0000, 0x2001, 0x0001, 0x1078, 0x21f3,
+ 0x1078, 0x3c73, 0x127f, 0x007f, 0x0e7f, 0x007c, 0x20a9, 0x0040,
+ 0x20a1, 0x8ec0, 0x2099, 0x8d8e, 0x3304, 0x8007, 0x20a2, 0x9398,
+ 0x94a0, 0x00f0, 0x3cbc, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000,
+ 0x2099, 0x8d00, 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c,
+ 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x8d80, 0x20a1, 0x020b,
+ 0x20a9, 0x000c, 0x53a6, 0x007c, 0x0c7e, 0x007e, 0x2061, 0x0100,
+ 0x810f, 0x2001, 0x882d, 0x2004, 0xa005, 0x00c0, 0x3ced, 0x6030,
+ 0xa084, 0x00ff, 0xa105, 0x0078, 0x3cef, 0xa185, 0x00f7, 0x604a,
+ 0x007f, 0x0c7f, 0x007c, 0x017e, 0x047e, 0x2001, 0x8852, 0x2004,
+ 0xd0a4, 0x0040, 0x3d06, 0xa006, 0x2020, 0x2009, 0x002a, 0x1078,
+ 0x86f5, 0x2001, 0x880c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a,
+ 0x1078, 0x249d, 0x047f, 0x017f, 0x007c, 0x007e, 0x2001, 0x880c,
+ 0x2004, 0xd09c, 0x0040, 0x3d14, 0x007f, 0x007c, 0x007e, 0x017e,
+ 0x127e, 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0xa18d, 0x0006,
+ 0x2102, 0x127f, 0x017f, 0x007f, 0x007c, 0x157e, 0x20a9, 0x00ff,
+ 0x2009, 0x8934, 0xa006, 0x200a, 0x8108, 0x00f0, 0x3d2b, 0x157f,
+ 0x007c, 0x0d7e, 0x037e, 0x157e, 0x137e, 0x147e, 0x2069, 0x8851,
+ 0xa006, 0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012, 0xa198,
+ 0x25b2, 0x231c, 0xa39c, 0x00ff, 0x6316, 0x20a9, 0x0004, 0xac98,
+ 0x0006, 0x23a0, 0x40a4, 0x20a9, 0x0004, 0xac98, 0x000a, 0x23a0,
+ 0x40a4, 0x603e, 0x6042, 0x604e, 0x6052, 0x6056, 0x605a, 0x605e,
+ 0x6062, 0x6066, 0x606a, 0x606e, 0x6072, 0x6076, 0x607a, 0x607e,
+ 0x6082, 0x6086, 0x608a, 0x608e, 0x6092, 0x6096, 0x609a, 0x609e,
+ 0x61a2, 0x0d7e, 0x60a4, 0xa06d, 0x0040, 0x3d70, 0x1078, 0x1344,
+ 0x60a7, 0x0000, 0x60a8, 0xa06d, 0x0040, 0x3d78, 0x1078, 0x1344,
+ 0x60ab, 0x0000, 0x0d7f, 0xa006, 0x604a, 0x6810, 0x603a, 0x680c,
+ 0x6046, 0x6814, 0xa084, 0x00ff, 0x6042, 0x147f, 0x137f, 0x157f,
+ 0x037f, 0x0d7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x6944, 0x6e48,
+ 0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8, 0x3e31, 0xa18c, 0xff00,
+ 0x810f, 0xa182, 0x00ff, 0x00c8, 0x3e37, 0x2001, 0x880c, 0x2004,
+ 0xa084, 0x0003, 0x00c0, 0x3e1a, 0xa188, 0x8934, 0x2104, 0xa065,
+ 0x0040, 0x3e08, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0,
+ 0x3e0e, 0x60a4, 0xa00d, 0x0040, 0x3db9, 0x1078, 0x41b1, 0x0040,
+ 0x3e02, 0x60a8, 0xa00d, 0x0040, 0x3dd3, 0x1078, 0x4202, 0x00c0,
+ 0x3dd3, 0x694c, 0xd1fc, 0x00c0, 0x3dc9, 0x1078, 0x3ee2, 0x0078,
+ 0x3dfd, 0x1078, 0x3e9c, 0x694c, 0xd1ec, 0x00c0, 0x3dfd, 0x1078,
+ 0x407a, 0x0078, 0x3dfd, 0x694c, 0xa184, 0xa000, 0x0040, 0x3ded,
+ 0xd1ec, 0x0040, 0x3de6, 0xd1fc, 0x0040, 0x3de2, 0x1078, 0x408b,
+ 0x0078, 0x3de9, 0x1078, 0x408b, 0x0078, 0x3ded, 0xd1fc, 0x0040,
+ 0x3ded, 0x1078, 0x3e9c, 0x0078, 0x3dfd, 0x6050, 0xa00d, 0x0040,
+ 0x3df8, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x0078, 0x3dfd,
+ 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x1078, 0x53b8, 0xa006,
+ 0x127f, 0x007c, 0x2001, 0x0005, 0x2009, 0x0000, 0x0078, 0x3e3b,
+ 0x2001, 0x0028, 0x2009, 0x0000, 0x0078, 0x3e3b, 0xa082, 0x0006,
+ 0x00c8, 0x3e1a, 0x60a0, 0xd0bc, 0x0040, 0x3db1, 0x2001, 0x0028,
+ 0x0078, 0x3e2d, 0x2009, 0x880c, 0x210c, 0xd18c, 0x0040, 0x3e24,
+ 0x2001, 0x0004, 0x0078, 0x3e2d, 0xd184, 0x0040, 0x3e2b, 0x2001,
+ 0x0004, 0x0078, 0x3e2d, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078,
+ 0x3e3b, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x3e3b, 0x2001,
+ 0x0029, 0x2009, 0x0000, 0xa005, 0x127f, 0x007c, 0x6944, 0x6e48,
+ 0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8, 0x3e81, 0xa18c, 0xff00,
+ 0x810f, 0xa182, 0x00ff, 0x00c8, 0x3e71, 0xa188, 0x8934, 0x2104,
+ 0xa065, 0x0040, 0x3e71, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006,
+ 0x00c0, 0x3e77, 0x684c, 0xd0ec, 0x0040, 0x3e64, 0x1078, 0x408b,
+ 0x1078, 0x3e9c, 0x0078, 0x3e6c, 0x1078, 0x3e9c, 0x684c, 0xd0fc,
+ 0x0040, 0x3e6c, 0x1078, 0x407a, 0x1078, 0x40d3, 0xa006, 0x0078,
+ 0x3e85, 0x2001, 0x0028, 0x2009, 0x0000, 0x0078, 0x3e85, 0xa082,
+ 0x0006, 0x0048, 0x3e5a, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078,
+ 0x3e85, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x007c, 0x127e,
+ 0x2091, 0x8000, 0x6050, 0xa00d, 0x0040, 0x3e95, 0x2d00, 0x200a,
+ 0x6803, 0x0000, 0x6052, 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e,
+ 0x6803, 0x0000, 0x0078, 0x3e93, 0x127e, 0x2091, 0x8000, 0x604c,
+ 0xa005, 0x0040, 0x3eb2, 0x0e7e, 0x2071, 0x8aa2, 0x7004, 0xa086,
+ 0x0002, 0x0040, 0x3eb9, 0x0e7f, 0x604c, 0x6802, 0x2d00, 0x604e,
+ 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0078,
+ 0x3eb0, 0x701c, 0xac06, 0x00c0, 0x3eab, 0x604c, 0x2070, 0x7000,
+ 0x6802, 0x2d00, 0x7002, 0x0e7f, 0x127f, 0x007c, 0x127e, 0x2091,
+ 0x8000, 0x604c, 0xa06d, 0x0040, 0x3ed4, 0x6800, 0xa005, 0x00c0,
+ 0x3ed2, 0x6052, 0x604e, 0xad05, 0x127f, 0x007c, 0x604c, 0xa06d,
+ 0x0040, 0x3ee1, 0x6800, 0xa005, 0x00c0, 0x3edf, 0x6052, 0x604e,
+ 0xad05, 0x007c, 0x6803, 0x0000, 0x6084, 0xa00d, 0x0040, 0x3eec,
+ 0x2d00, 0x200a, 0x6086, 0x007c, 0x2d00, 0x6086, 0x6082, 0x0078,
+ 0x3eeb, 0x127e, 0x0c7e, 0x027e, 0x2091, 0x8000, 0x6218, 0x2260,
+ 0x6200, 0xa005, 0x0040, 0x3eff, 0xc285, 0x0078, 0x3f00, 0xc284,
+ 0x6202, 0x027f, 0x0c7f, 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091,
+ 0x8000, 0x6218, 0x2260, 0x6204, 0x007e, 0xa086, 0x0006, 0x00c0,
+ 0x3f24, 0x609c, 0xd0ac, 0x0040, 0x3f24, 0x2001, 0x8852, 0x2004,
+ 0xd0a4, 0x0040, 0x3f24, 0xa284, 0xff00, 0x8007, 0xa086, 0x0007,
+ 0x00c0, 0x3f24, 0x6007, 0x0600, 0x007f, 0xa294, 0xff00, 0xa215,
+ 0x6206, 0x0c7f, 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000,
+ 0x6218, 0x2260, 0x6204, 0x007e, 0xa086, 0x0006, 0x00c0, 0x3f4a,
+ 0x609c, 0xd0a4, 0x0040, 0x3f4a, 0x2001, 0x8852, 0x2004, 0xd0ac,
+ 0x00c0, 0x3f4a, 0xa284, 0x00ff, 0xa086, 0x0007, 0x00c0, 0x3f4a,
+ 0x6007, 0x0006, 0x007f, 0xa294, 0x00ff, 0x8007, 0xa215, 0x6206,
+ 0x0c7f, 0x127f, 0x007c, 0x027e, 0xa182, 0x00ff, 0x0048, 0x3f5c,
+ 0xa085, 0x0001, 0x0078, 0x3f74, 0xa190, 0x8934, 0x2204, 0xa065,
+ 0x00c0, 0x3f73, 0x017e, 0x0d7e, 0x1078, 0x1310, 0x2d60, 0x0d7f,
+ 0x017f, 0x0040, 0x3f58, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab,
+ 0x0000, 0x1078, 0x3d31, 0xa006, 0x027f, 0x007c, 0x027e, 0xa182,
+ 0x00ff, 0x0048, 0x3f7f, 0xa085, 0x0001, 0x0078, 0x3f8c, 0x0d7e,
+ 0xa190, 0x8934, 0x2204, 0xa06d, 0x0040, 0x3f8a, 0x2013, 0x0000,
+ 0x1078, 0x1344, 0x0d7f, 0xa006, 0x027f, 0x007c, 0x017e, 0xa182,
+ 0x00ff, 0x0048, 0x3f97, 0xa085, 0x0001, 0x0078, 0x3f9e, 0xa188,
+ 0x8934, 0x2104, 0xa065, 0x0040, 0x3f93, 0xa006, 0x017f, 0x007c,
+ 0x0d7e, 0x157e, 0x137e, 0x147e, 0x600b, 0x0000, 0x600f, 0x0000,
+ 0x6000, 0xc08c, 0x6002, 0x2069, 0x8d8e, 0x6808, 0x605e, 0x6810,
+ 0x6062, 0x6138, 0xa10a, 0x0048, 0x3fb6, 0x603a, 0x6814, 0x6066,
+ 0x2099, 0x8d96, 0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x53a3,
+ 0x2099, 0x8d9a, 0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x53a3,
+ 0x2069, 0x8dae, 0x6808, 0x606a, 0x690c, 0x616e, 0x6810, 0x6072,
+ 0x6818, 0x6076, 0xa182, 0x0211, 0x00c8, 0x3fda, 0x2009, 0x0008,
+ 0x0078, 0x4004, 0xa182, 0x0259, 0x00c8, 0x3fe2, 0x2009, 0x0007,
+ 0x0078, 0x4004, 0xa182, 0x02c1, 0x00c8, 0x3fea, 0x2009, 0x0006,
+ 0x0078, 0x4004, 0xa182, 0x0349, 0x00c8, 0x3ff2, 0x2009, 0x0005,
+ 0x0078, 0x4004, 0xa182, 0x0421, 0x00c8, 0x3ffa, 0x2009, 0x0004,
+ 0x0078, 0x4004, 0xa182, 0x0581, 0x00c8, 0x4002, 0x2009, 0x0003,
+ 0x0078, 0x4004, 0x2009, 0x0002, 0x6192, 0x147f, 0x137f, 0x157f,
+ 0x0d7f, 0x007c, 0x0e7e, 0x2071, 0x8d8d, 0x2e04, 0x6896, 0x2071,
+ 0x8d8e, 0x7004, 0x689a, 0x701c, 0x689e, 0x0e7f, 0x007c, 0x0d7e,
+ 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x0040, 0x403b, 0x6900,
+ 0x81ff, 0x00c0, 0x404f, 0x6a04, 0xa282, 0x0010, 0x00c8, 0x4054,
+ 0xad88, 0x0004, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0040,
+ 0x4036, 0x8108, 0x00f0, 0x402c, 0x1078, 0x12d2, 0x260a, 0x8210,
+ 0x6a06, 0x0078, 0x404f, 0x1078, 0x132b, 0x0040, 0x4054, 0x2d00,
+ 0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b,
+ 0xffff, 0x8108, 0x00f0, 0x4047, 0x6807, 0x0001, 0x6e12, 0xa085,
+ 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006, 0x0078, 0x4051, 0x127e,
+ 0x2091, 0x8000, 0x0d7e, 0x60a4, 0xa00d, 0x0040, 0x4077, 0x2168,
+ 0x6800, 0xa005, 0x00c0, 0x4073, 0x1078, 0x41b1, 0x00c0, 0x4077,
+ 0x200b, 0xffff, 0x6804, 0xa08a, 0x0002, 0x0048, 0x4073, 0x8001,
+ 0x6806, 0x0078, 0x4077, 0x1078, 0x1344, 0x60a7, 0x0000, 0x0d7f,
+ 0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x4217, 0x0078,
+ 0x4083, 0x1078, 0x3e87, 0x1078, 0x4117, 0x00c0, 0x4081, 0x1078,
+ 0x40d3, 0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a8,
+ 0xa06d, 0x0040, 0x40af, 0x6950, 0x81ff, 0x00c0, 0x40c3, 0x6a54,
+ 0xa282, 0x0010, 0x00c8, 0x40d0, 0xad88, 0x0018, 0x20a9, 0x0010,
+ 0x2104, 0xa086, 0xffff, 0x0040, 0x40aa, 0x8108, 0x00f0, 0x40a0,
+ 0x1078, 0x12d2, 0x260a, 0x8210, 0x6a56, 0x0078, 0x40c3, 0x1078,
+ 0x132b, 0x0040, 0x40d0, 0x2d00, 0x60aa, 0x6853, 0x0000, 0xad88,
+ 0x0018, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x00f0, 0x40bb,
+ 0x6857, 0x0001, 0x6e62, 0x0078, 0x40c7, 0x1078, 0x3ee2, 0x1078,
+ 0x40dd, 0x00c0, 0x40c5, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c,
+ 0xa006, 0x0078, 0x40cd, 0x127e, 0x2091, 0x8000, 0x1078, 0x53b8,
+ 0x127f, 0x007c, 0xa01e, 0x0078, 0x40df, 0x2019, 0x0001, 0xa00e,
+ 0x127e, 0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x00c0,
+ 0x40fd, 0x8dff, 0x0040, 0x4112, 0x83ff, 0x0040, 0x40f5, 0x6848,
+ 0xa606, 0x0040, 0x4102, 0x0078, 0x40fd, 0x683c, 0xa406, 0x00c0,
+ 0x40fd, 0x6840, 0xa506, 0x0040, 0x4102, 0x2d08, 0x6800, 0x2068,
+ 0x0078, 0x40e9, 0x6a00, 0x604c, 0xad06, 0x00c0, 0x410a, 0x624e,
+ 0x0078, 0x410d, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, 0x4112,
+ 0x6152, 0x8dff, 0x127f, 0x007c, 0xa01e, 0x0078, 0x4119, 0x2019,
+ 0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x0040, 0x4145, 0x83ff,
+ 0x0040, 0x4128, 0x6848, 0xa606, 0x0040, 0x4135, 0x0078, 0x4130,
+ 0x683c, 0xa406, 0x00c0, 0x4130, 0x6840, 0xa506, 0x0040, 0x4135,
+ 0x2d08, 0x6800, 0x2068, 0x0078, 0x411c, 0x6a00, 0x6080, 0xad06,
+ 0x00c0, 0x413d, 0x6282, 0x0078, 0x4140, 0xa180, 0x0000, 0x2202,
+ 0x82ff, 0x00c0, 0x4145, 0x6186, 0x8dff, 0x007c, 0xa016, 0x1078,
+ 0x41aa, 0x00c0, 0x414d, 0x2011, 0x0001, 0x1078, 0x41fb, 0x00c0,
+ 0x4153, 0xa295, 0x0002, 0x007c, 0x1078, 0x4233, 0x0040, 0x415c,
+ 0x1078, 0x78b9, 0x0078, 0x415e, 0xa085, 0x0001, 0x007c, 0x1078,
+ 0x4233, 0x0040, 0x4167, 0x1078, 0x784f, 0x0078, 0x4169, 0xa085,
+ 0x0001, 0x007c, 0x1078, 0x4233, 0x0040, 0x4172, 0x1078, 0x7899,
+ 0x0078, 0x4174, 0xa085, 0x0001, 0x007c, 0x1078, 0x4233, 0x0040,
+ 0x417d, 0x1078, 0x786b, 0x0078, 0x417f, 0xa085, 0x0001, 0x007c,
+ 0x1078, 0x4233, 0x0040, 0x4188, 0x1078, 0x78d9, 0x0078, 0x418a,
+ 0xa085, 0x0001, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x8000,
+ 0x6080, 0xa06d, 0x0040, 0x41a2, 0x6800, 0x007e, 0x6837, 0x0103,
+ 0x6b4a, 0x6847, 0x0000, 0x1078, 0x7a46, 0x1078, 0x4376, 0x007f,
+ 0x0078, 0x4191, 0x6083, 0x0000, 0x6087, 0x0000, 0x0d7f, 0x007f,
+ 0x127f, 0x007c, 0x60a4, 0xa00d, 0x00c0, 0x41b1, 0xa085, 0x0001,
+ 0x007c, 0x0e7e, 0x2170, 0x7000, 0xa005, 0x00c0, 0x41c4, 0x20a9,
+ 0x0010, 0xae88, 0x0004, 0x2104, 0xa606, 0x0040, 0x41c4, 0x8108,
+ 0x00f0, 0x41bb, 0xa085, 0x0001, 0xa006, 0x0e7f, 0x007c, 0x0d7e,
+ 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x00c0, 0x41d5, 0x1078,
+ 0x132b, 0x0040, 0x41e7, 0x2d00, 0x60a6, 0x6803, 0x0001, 0x6807,
0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108,
- 0x00f0, 0x3905, 0x6807, 0x0001, 0x6e12, 0xa085, 0x0001, 0x127f,
- 0x0d7f, 0x007c, 0xa006, 0x0078, 0x390f, 0x127e, 0x2091, 0x8000,
- 0x1078, 0x3a55, 0x00c0, 0x392f, 0x200b, 0xffff, 0x0d7e, 0x60a4,
- 0x2068, 0x6804, 0xa08a, 0x0002, 0x0048, 0x392a, 0x8001, 0x6806,
- 0x0078, 0x392e, 0x1078, 0x1340, 0x60a7, 0x0000, 0x0d7f, 0x127f,
- 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x3ac1, 0x0078, 0x393a,
- 0x1078, 0x378d, 0x1078, 0x39ce, 0x00c0, 0x3938, 0x1078, 0x398a,
- 0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a8, 0xa06d,
- 0x0040, 0x3966, 0x6950, 0x81ff, 0x00c0, 0x397a, 0x6a54, 0xa282,
- 0x0010, 0x00c8, 0x3987, 0xad88, 0x0018, 0x20a9, 0x0010, 0x2104,
- 0xa086, 0xffff, 0x0040, 0x3961, 0x8108, 0x00f0, 0x3957, 0x1078,
- 0x12cd, 0x260a, 0x8210, 0x6a56, 0x0078, 0x397a, 0x1078, 0x130c,
- 0x0040, 0x3987, 0x2d00, 0x60aa, 0x6853, 0x0000, 0xad88, 0x0018,
- 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x00f0, 0x3972, 0x6857,
- 0x0001, 0x6e62, 0x0078, 0x397e, 0x1078, 0x37d1, 0x1078, 0x3994,
- 0x00c0, 0x397c, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006,
- 0x0078, 0x3984, 0x127e, 0x2091, 0x8000, 0x1078, 0x4960, 0x127f,
- 0x007c, 0xa01e, 0x0078, 0x3996, 0x2019, 0x0001, 0xa00e, 0x127e,
- 0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x00c0, 0x39b4,
- 0x8dff, 0x0040, 0x39c9, 0x83ff, 0x0040, 0x39ac, 0x6848, 0xa606,
- 0x0040, 0x39b9, 0x0078, 0x39b4, 0x683c, 0xa406, 0x00c0, 0x39b4,
- 0x6840, 0xa506, 0x0040, 0x39b9, 0x2d08, 0x6800, 0x2068, 0x0078,
- 0x39a0, 0x6a00, 0x604c, 0xad06, 0x00c0, 0x39c1, 0x624e, 0x0078,
- 0x39c4, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, 0x39c9, 0x6152,
- 0x8dff, 0x127f, 0x007c, 0xa01e, 0x0078, 0x39d0, 0x2019, 0x0001,
- 0xa00e, 0x6080, 0x2068, 0x8dff, 0x0040, 0x39fc, 0x83ff, 0x0040,
- 0x39df, 0x6848, 0xa606, 0x0040, 0x39ec, 0x0078, 0x39e7, 0x683c,
- 0xa406, 0x00c0, 0x39e7, 0x6840, 0xa506, 0x0040, 0x39ec, 0x2d08,
- 0x6800, 0x2068, 0x0078, 0x39d3, 0x6a00, 0x6080, 0xad06, 0x00c0,
- 0x39f4, 0x6282, 0x0078, 0x39f7, 0xa180, 0x0000, 0x2202, 0x82ff,
- 0x00c0, 0x39fc, 0x6186, 0x8dff, 0x007c, 0x1078, 0x3a55, 0x00c0,
- 0x3a03, 0x2011, 0x0001, 0x1078, 0x3aa5, 0x00c0, 0x3a09, 0xa295,
- 0x0002, 0x007c, 0x1078, 0x3add, 0x0040, 0x3a12, 0x1078, 0x6b2b,
- 0x0078, 0x3a14, 0xa085, 0x0001, 0x007c, 0x1078, 0x3add, 0x0040,
- 0x3a1d, 0x1078, 0x6aba, 0x0078, 0x3a1f, 0xa085, 0x0001, 0x007c,
- 0x1078, 0x3add, 0x0040, 0x3a28, 0x1078, 0x6b00, 0x0078, 0x3a2a,
- 0xa085, 0x0001, 0x007c, 0x1078, 0x3add, 0x0040, 0x3a33, 0x1078,
- 0x6ad6, 0x0078, 0x3a35, 0xa085, 0x0001, 0x007c, 0x127e, 0x007e,
- 0x0d7e, 0x2091, 0x8000, 0x6080, 0xa06d, 0x0040, 0x3a4d, 0x6800,
- 0x007e, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x6c54,
- 0x1078, 0x3b92, 0x007f, 0x0078, 0x3a3c, 0x6083, 0x0000, 0x6087,
- 0x0000, 0x0d7f, 0x007f, 0x127f, 0x007c, 0x60a4, 0xa00d, 0x00c0,
- 0x3a5c, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x2170, 0x7000, 0xa005,
- 0x00c0, 0x3a6f, 0x20a9, 0x0010, 0xae88, 0x0004, 0x2104, 0xa606,
- 0x0040, 0x3a6f, 0x8108, 0x00f0, 0x3a66, 0xa085, 0x0001, 0x0e7f,
- 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x00c0,
- 0x3a7f, 0x1078, 0x130c, 0x0040, 0x3a91, 0x2d00, 0x60a6, 0x6803,
- 0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b,
- 0xffff, 0x8108, 0x00f0, 0x3a87, 0xa085, 0x0001, 0x127f, 0x0d7f,
- 0x007c, 0xa006, 0x0078, 0x3a8e, 0x0d7e, 0x127e, 0x2091, 0x8000,
- 0x60a4, 0xa06d, 0x0040, 0x3aa2, 0x60a7, 0x0000, 0x1078, 0x1340,
- 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0x60a8, 0xa00d, 0x00c0,
- 0x3aac, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x2170, 0x7050, 0xa005,
- 0x00c0, 0x3abf, 0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606,
- 0x0040, 0x3abf, 0x8108, 0x00f0, 0x3ab6, 0xa085, 0x0001, 0x0e7f,
- 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x3aa5, 0x00c0, 0x3adb,
- 0x200b, 0xffff, 0x0d7e, 0x60a8, 0x2068, 0x6854, 0xa08a, 0x0002,
- 0x0048, 0x3ad6, 0x8001, 0x6856, 0x0078, 0x3ada, 0x1078, 0x1340,
- 0x60ab, 0x0000, 0x0d7f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c,
- 0x0f7e, 0x2079, 0x7751, 0x7804, 0xd0a4, 0x0040, 0x3b09, 0x157e,
- 0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x384c,
- 0x00c0, 0x3afd, 0x6004, 0xa084, 0xff00, 0x8007, 0xa086, 0x0006,
- 0x00c0, 0x3afd, 0x6000, 0xc0ed, 0x6002, 0x017f, 0x8108, 0x00f0,
- 0x3aed, 0x0c7f, 0x157f, 0x2009, 0x07d0, 0x2011, 0x3b0b, 0x1078,
- 0x4719, 0x0f7f, 0x007c, 0x2011, 0x3b0b, 0x1078, 0x4689, 0x157e,
- 0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x384c,
- 0x00c0, 0x3b37, 0x6000, 0xd0ec, 0x0040, 0x3b37, 0x047e, 0x62a0,
- 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x1078, 0x7641,
- 0x6000, 0xc0e5, 0xc0ec, 0x6002, 0x2019, 0x0029, 0x1078, 0x4a7e,
- 0x1078, 0x49c1, 0x2009, 0x0000, 0x1078, 0x747b, 0x047f, 0x017f,
- 0x8108, 0x00f0, 0x3b15, 0x0c7f, 0x157f, 0x007c, 0x0c7e, 0x6018,
- 0x2060, 0x6000, 0xc0ec, 0x6002, 0x0c7f, 0x007c, 0x2071, 0x77ff,
- 0x7003, 0x0001, 0x7007, 0x0000, 0x7013, 0x0000, 0x7017, 0x0000,
- 0x701b, 0x0000, 0x701f, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000,
- 0x705b, 0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x007c, 0x0e7e,
- 0x2071, 0x77ff, 0x684c, 0xa005, 0x00c0, 0x3b6d, 0x7028, 0xc085,
- 0x702a, 0xa085, 0x0001, 0x0078, 0x3b90, 0x6a60, 0x7236, 0x6b64,
- 0x733a, 0x6868, 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c,
- 0x702e, 0x6844, 0x7032, 0x2009, 0x000d, 0x200a, 0x8007, 0x8006,
- 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319,
- 0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0xa006,
- 0x0e7f, 0x007c, 0x0e7e, 0x6838, 0xd0fc, 0x00c0, 0x3be3, 0x6804,
- 0xa00d, 0x0040, 0x3bb1, 0x0d7e, 0x0e7e, 0x2071, 0x7700, 0x027e,
- 0xa016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff,
- 0x00c0, 0x3ba2, 0x702e, 0x70a0, 0xa200, 0x70a2, 0x027f, 0x0e7f,
- 0x0d7f, 0x2071, 0x77ff, 0x701c, 0xa005, 0x00c0, 0x3bf4, 0x0068,
- 0x3bf2, 0x2071, 0x7751, 0x7004, 0xd09c, 0x0040, 0x3bf2, 0x6934,
- 0xa186, 0x0103, 0x00c0, 0x3c05, 0x6948, 0x6844, 0xa105, 0x00c0,
- 0x3be5, 0x2009, 0x8020, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0,
- 0x3bf2, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001,
- 0x2091, 0x4080, 0x2071, 0x7700, 0x702c, 0x206a, 0x2d00, 0x702e,
- 0x70a0, 0x8000, 0x70a2, 0x0e7f, 0x007c, 0x6844, 0xa086, 0x0100,
- 0x00c0, 0x3bf2, 0x6868, 0xa005, 0x00c0, 0x3bf2, 0x2009, 0x8020,
- 0x0078, 0x3bcb, 0x2071, 0x77ff, 0x2d08, 0x206b, 0x0000, 0x7010,
- 0x8000, 0x7012, 0x7018, 0xa06d, 0x711a, 0x0040, 0x3c02, 0x6902,
- 0x0078, 0x3c03, 0x711e, 0x0078, 0x3be3, 0xa18c, 0x00ff, 0xa186,
- 0x0017, 0x0040, 0x3c13, 0xa186, 0x001e, 0x0040, 0x3c13, 0xa18e,
- 0x001f, 0x00c0, 0x3bf2, 0x684c, 0xd0cc, 0x0040, 0x3bf2, 0x6850,
- 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, 0x3bf2, 0x2009, 0x8021,
- 0x0078, 0x3bcb, 0x007e, 0x6837, 0x0103, 0x20a9, 0x001c, 0xad80,
- 0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x007f, 0x684a, 0x6952,
- 0x007c, 0x2071, 0x77ff, 0x7004, 0x0079, 0x3c36, 0x3c3e, 0x3c4d,
- 0x3cdd, 0x3cde, 0x3cee, 0x3cf4, 0x3c3f, 0x3ccb, 0x007c, 0x127e,
- 0x2091, 0x8000, 0x0068, 0x3c4c, 0x2009, 0x000d, 0x7030, 0x200a,
- 0x2091, 0x4080, 0x7007, 0x0001, 0x127f, 0x701c, 0xa06d, 0x0040,
- 0x3cca, 0x0e7e, 0x2071, 0x7751, 0x7004, 0xd09c, 0x0040, 0x3cac,
- 0x6934, 0xa186, 0x0103, 0x00c0, 0x3c82, 0x6948, 0x6844, 0xa105,
- 0x00c0, 0x3c9f, 0x2009, 0x8020, 0x127e, 0x2091, 0x8000, 0x0068,
- 0x3c7e, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x3c7e, 0x7122,
- 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080,
- 0x127f, 0x0e7f, 0x1078, 0x3d27, 0x0078, 0x3cca, 0x127f, 0x0e7f,
- 0x0078, 0x3cca, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0040, 0x3c90,
- 0xa186, 0x001e, 0x0040, 0x3c90, 0xa18e, 0x001f, 0x00c0, 0x3cac,
- 0x684c, 0xd0cc, 0x0040, 0x3cac, 0x6850, 0xa084, 0x00ff, 0xa086,
- 0x0001, 0x00c0, 0x3cac, 0x2009, 0x8021, 0x0078, 0x3c64, 0x6844,
- 0xa086, 0x0100, 0x00c0, 0x3cac, 0x6868, 0xa005, 0x00c0, 0x3cac,
- 0x2009, 0x8020, 0x0078, 0x3c64, 0x0e7f, 0x1078, 0x3d3b, 0x0040,
- 0x3cca, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003,
- 0x00c0, 0x3cc1, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040, 0x3cc1,
- 0x710e, 0x7007, 0x0003, 0x1078, 0x3d5b, 0x7050, 0xa086, 0x0100,
- 0x0040, 0x3cde, 0x007c, 0x701c, 0xa06d, 0x0040, 0x3cdc, 0x1078,
- 0x3d3b, 0x0040, 0x3cdc, 0x7007, 0x0003, 0x1078, 0x3d5b, 0x7050,
- 0xa086, 0x0100, 0x0040, 0x3cde, 0x007c, 0x007c, 0x7050, 0xa09e,
- 0x0100, 0x00c0, 0x3ce7, 0x7007, 0x0004, 0x0078, 0x3cee, 0xa086,
- 0x0200, 0x00c0, 0x3ced, 0x7007, 0x0005, 0x007c, 0x1078, 0x3cf5,
- 0x7006, 0x1078, 0x3d27, 0x007c, 0x007c, 0x702c, 0x7130, 0x8108,
- 0xa102, 0x0048, 0x3d02, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072,
- 0x0078, 0x3d0c, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x3d0c,
- 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001, 0x700e,
- 0x00c0, 0x3d20, 0x127e, 0x2091, 0x8000, 0x0068, 0x3d23, 0x2001,
- 0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x127f, 0x007c,
- 0x2001, 0x0007, 0x007c, 0x2001, 0x0006, 0x127f, 0x007c, 0x701c,
- 0xa06d, 0x0040, 0x3d3a, 0x127e, 0x2091, 0x8000, 0x7010, 0x8001,
- 0x7012, 0x2d04, 0x701e, 0xa005, 0x00c0, 0x3d37, 0x701a, 0x127f,
- 0x1078, 0x1340, 0x007c, 0x2019, 0x000d, 0x2304, 0x230c, 0xa10e,
- 0x0040, 0x3d4a, 0x2304, 0x230c, 0xa10e, 0x0040, 0x3d4a, 0xa006,
- 0x0078, 0x3d5a, 0x732c, 0x8319, 0x7130, 0xa102, 0x00c0, 0x3d54,
- 0x2300, 0xa005, 0x0078, 0x3d5a, 0x0048, 0x3d59, 0xa302, 0x0078,
- 0x3d5a, 0x8002, 0x007c, 0x2d00, 0x7026, 0xa080, 0x000d, 0x7056,
- 0x7053, 0x0000, 0x127e, 0x2091, 0x8000, 0x2009, 0x7959, 0x2104,
- 0xc08d, 0x200a, 0x127f, 0x1078, 0x1391, 0x007c, 0x2071, 0x77cd,
- 0x7003, 0x0000, 0x7007, 0x0000, 0x700f, 0x0000, 0x702b, 0x0001,
- 0x704f, 0x0000, 0x7053, 0x0001, 0x705f, 0x0020, 0x7063, 0x0040,
- 0x7083, 0x0000, 0x708b, 0x0000, 0x708f, 0x0001, 0x70bf, 0x0000,
- 0x007c, 0x0e7e, 0x2071, 0x77cd, 0x6848, 0xa005, 0x00c0, 0x3d97,
- 0x7028, 0xc085, 0x702a, 0xa085, 0x0001, 0x0078, 0x3dbc, 0x6a50,
- 0x7236, 0x6b54, 0x733a, 0x6858, 0x703e, 0x707a, 0x685c, 0x7042,
- 0x707e, 0x6848, 0x702e, 0x6840, 0x7032, 0x2009, 0x000c, 0x200a,
- 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210,
- 0x2100, 0xa319, 0x7272, 0x7376, 0x7028, 0xc084, 0x702a, 0x7007,
- 0x0001, 0x700f, 0x0000, 0xa006, 0x0e7f, 0x007c, 0x2b78, 0x2071,
- 0x77cd, 0x7004, 0x1079, 0x3e1c, 0x700c, 0x0079, 0x3dc7, 0x3dcc,
- 0x3dc1, 0x3dc1, 0x3dc1, 0x3dc1, 0x007c, 0x700c, 0x0079, 0x3dd0,
- 0x3dd5, 0x3e1a, 0x3e1a, 0x3e1b, 0x3e1b, 0x7830, 0x7930, 0xa106,
- 0x0040, 0x3ddf, 0x7830, 0x7930, 0xa106, 0x00c0, 0x3e05, 0x7030,
- 0xa10a, 0x0040, 0x3e05, 0x00c8, 0x3de7, 0x712c, 0xa10a, 0xa18a,
- 0x0002, 0x00c8, 0x3e06, 0x1078, 0x130c, 0x0040, 0x3e05, 0x2d00,
- 0x705a, 0x7063, 0x0040, 0x2001, 0x0003, 0x7057, 0x0000, 0x127e,
- 0x007e, 0x2091, 0x8000, 0x2009, 0x7959, 0x2104, 0xc085, 0x200a,
- 0x007f, 0x700e, 0x127f, 0x1078, 0x1391, 0x007c, 0x1078, 0x130c,
- 0x0040, 0x3e05, 0x2d00, 0x705a, 0x1078, 0x130c, 0x00c0, 0x3e12,
- 0x0078, 0x3df1, 0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, 0x0004,
- 0x0078, 0x3df5, 0x007c, 0x007c, 0x3e2d, 0x3e2e, 0x3e65, 0x3e66,
- 0x3e1a, 0x3e9c, 0x3ea1, 0x3ed8, 0x3ed9, 0x3ef4, 0x3ef5, 0x3ef6,
- 0x3ef7, 0x3ef8, 0x3ef9, 0x3f62, 0x3f8c, 0x007c, 0x700c, 0x0079,
- 0x3e31, 0x3e36, 0x3e39, 0x3e49, 0x3e64, 0x3e64, 0x1078, 0x3dcd,
- 0x007c, 0x127e, 0x8001, 0x700e, 0x7058, 0x007e, 0x1078, 0x426e,
- 0x0040, 0x3e46, 0x2091, 0x8000, 0x1078, 0x3dcd, 0x0d7f, 0x0078,
- 0x3e52, 0x127e, 0x8001, 0x700e, 0x1078, 0x426e, 0x7058, 0x2068,
- 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084,
- 0x00ff, 0xa08a, 0x0020, 0x00c8, 0x3e61, 0x1079, 0x3e7c, 0x127f,
- 0x007c, 0x127f, 0x1078, 0x3efa, 0x007c, 0x007c, 0x007c, 0x0e7e,
- 0x2071, 0x77cd, 0x700c, 0x0079, 0x3e6d, 0x3e72, 0x3e72, 0x3e72,
- 0x3e74, 0x3e78, 0x0e7f, 0x007c, 0x700f, 0x0001, 0x0078, 0x3e7a,
- 0x700f, 0x0002, 0x0e7f, 0x007c, 0x3efa, 0x3efa, 0x3f16, 0x3efa,
- 0x4001, 0x3efa, 0x3efa, 0x3efa, 0x3efa, 0x3efa, 0x3f16, 0x4040,
- 0x408a, 0x40e3, 0x40f7, 0x3efa, 0x3efa, 0x3f32, 0x3f16, 0x3efa,
- 0x3efa, 0x3f48, 0x4182, 0x41a0, 0x3efa, 0x3f32, 0x3efa, 0x3efa,
- 0x3efa, 0x3efa, 0x3f48, 0x41a0, 0x7020, 0x2068, 0x1078, 0x1340,
- 0x007c, 0x700c, 0x0079, 0x3ea4, 0x3ea9, 0x3eac, 0x3ebc, 0x3ed7,
- 0x3ed7, 0x1078, 0x3dcd, 0x007c, 0x127e, 0x8001, 0x700e, 0x7058,
- 0x007e, 0x1078, 0x426e, 0x0040, 0x3eb9, 0x2091, 0x8000, 0x1078,
- 0x3dcd, 0x0d7f, 0x0078, 0x3ec5, 0x127e, 0x8001, 0x700e, 0x1078,
- 0x426e, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807,
- 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x001a, 0x00c8, 0x3ed4,
- 0x1079, 0x3eda, 0x127f, 0x007c, 0x127f, 0x1078, 0x3efa, 0x007c,
- 0x007c, 0x007c, 0x3efa, 0x3f16, 0x3feb, 0x3efa, 0x3f16, 0x3efa,
- 0x3f16, 0x3f16, 0x3efa, 0x3f16, 0x3feb, 0x3f16, 0x3f16, 0x3f16,
- 0x3f16, 0x3f16, 0x3efa, 0x3f16, 0x3feb, 0x3efa, 0x3efa, 0x3f16,
- 0x3efa, 0x3efa, 0x3efa, 0x3f16, 0x007c, 0x007c, 0x007c, 0x007c,
- 0x007c, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0d5,
- 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x3b92, 0x127f, 0x007c,
- 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5, 0x683a, 0x127e,
- 0x2091, 0x8000, 0x1078, 0x3b92, 0x127f, 0x007c, 0x7007, 0x0001,
- 0x6838, 0xa084, 0x00ff, 0xc0ed, 0x683a, 0x127e, 0x2091, 0x8000,
- 0x1078, 0x3b92, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084,
- 0x00ff, 0xc0dd, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x3b92,
- 0x127f, 0x007c, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0040, 0x3f08,
- 0x8001, 0x00c0, 0x3f3f, 0x7007, 0x0001, 0x0078, 0x3fc8, 0x7007,
- 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x3fc8, 0x007c,
- 0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098,
- 0x20a1, 0x77f8, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x00c8,
- 0x3f24, 0x6884, 0xa08a, 0x0003, 0x00c8, 0x3f24, 0xa080, 0x3fb9,
- 0x2004, 0x70c6, 0x7010, 0xa015, 0x0040, 0x3fac, 0x1078, 0x130c,
- 0x00c0, 0x3f6d, 0x7007, 0x000f, 0x007c, 0x2d00, 0x7022, 0x70c4,
- 0x2060, 0x6000, 0x6836, 0x6004, 0xad00, 0x7096, 0x6008, 0xa20a,
- 0x00c8, 0x3f7c, 0xa00e, 0x2200, 0x7112, 0x620c, 0x8003, 0x800b,
- 0xa296, 0x0004, 0x0040, 0x3f85, 0xa108, 0x719a, 0x810b, 0x719e,
- 0xae90, 0x0022, 0x1078, 0x1377, 0x7090, 0xa08e, 0x0100, 0x0040,
- 0x3fa0, 0xa086, 0x0200, 0x0040, 0x3f98, 0x7007, 0x0010, 0x007c,
- 0x7020, 0x2068, 0x1078, 0x1340, 0x7014, 0x2068, 0x0078, 0x3f24,
- 0x7020, 0x2068, 0x7018, 0x6802, 0x6807, 0x0000, 0x2d08, 0x2068,
- 0x6906, 0x711a, 0x0078, 0x3f62, 0x7014, 0x2068, 0x7007, 0x0001,
- 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x0040, 0x41bd, 0x0078,
- 0x3fc8, 0x3fbc, 0x3fc0, 0x3fc4, 0x0002, 0x0011, 0x0007, 0x0004,
- 0x000a, 0x000f, 0x0005, 0x0006, 0x0012, 0x000f, 0x0005, 0x0006,
- 0x2009, 0x772c, 0x210c, 0x81ff, 0x00c0, 0x3fe5, 0x6838, 0xa084,
- 0x00ff, 0x683a, 0x6853, 0x0000, 0x1078, 0x3691, 0x00c0, 0x3fd9,
- 0x007c, 0x1078, 0x3c22, 0x127e, 0x2091, 0x8000, 0x1078, 0x6c54,
- 0x1078, 0x3b92, 0x127f, 0x0078, 0x3fd8, 0x2001, 0x0028, 0x2009,
- 0x0000, 0x0078, 0x3fd9, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906,
- 0x711a, 0x7010, 0x8001, 0x7012, 0x0040, 0x3ffa, 0x7007, 0x0006,
- 0x0078, 0x4000, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x107a,
- 0x007c, 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848,
- 0xa084, 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x0040, 0x402a,
- 0x2009, 0x0000, 0x20a9, 0x007e, 0xa096, 0x0002, 0x0040, 0x402a,
- 0xa005, 0x00c0, 0x403d, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x1078,
- 0x384c, 0x00c0, 0x403d, 0x067e, 0x6e50, 0x1078, 0x3915, 0x067f,
- 0x0078, 0x403d, 0x047e, 0x2011, 0x770c, 0x2224, 0xc484, 0xc48c,
- 0x2412, 0x047f, 0x0c7e, 0x1078, 0x384c, 0x00c0, 0x4039, 0x1078,
- 0x3a94, 0x8108, 0x00f0, 0x4033, 0x0c7f, 0x1078, 0x1340, 0x007c,
- 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0x7752, 0x2004,
- 0xd0a4, 0x0040, 0x4081, 0x2009, 0x0000, 0x1078, 0x428a, 0x6100,
- 0xd184, 0x0040, 0x4066, 0x6858, 0xa084, 0x00ff, 0x00c0, 0x4084,
- 0x6000, 0xd084, 0x0040, 0x4081, 0x6004, 0xa005, 0x00c0, 0x4087,
- 0x6003, 0x0000, 0x600b, 0x0000, 0x0078, 0x407e, 0x2011, 0x0001,
- 0x6860, 0xa005, 0x00c0, 0x406e, 0x2001, 0x001e, 0x8000, 0x6016,
- 0x6858, 0xa084, 0x00ff, 0x0040, 0x4081, 0x6006, 0x6858, 0x8007,
- 0xa084, 0x00ff, 0x0040, 0x4081, 0x600a, 0x6202, 0x127f, 0x0078,
- 0x425d, 0x127f, 0x0078, 0x4255, 0x127f, 0x0078, 0x424d, 0x127f,
- 0x0078, 0x4251, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001,
- 0x7752, 0x2004, 0xd0a4, 0x0040, 0x40e0, 0x2009, 0x0000, 0x1078,
- 0x428a, 0x6000, 0xa084, 0x0001, 0x0040, 0x40e0, 0x6204, 0x6308,
- 0x6c48, 0xa484, 0x0003, 0x0040, 0x40b8, 0x6958, 0xa18c, 0x00ff,
- 0x8001, 0x00c0, 0x40b1, 0x2100, 0xa210, 0x0048, 0x40dd, 0x0078,
- 0x40b8, 0x8001, 0x00c0, 0x40dd, 0x2100, 0xa212, 0x0048, 0x40dd,
- 0xa484, 0x000c, 0x0040, 0x40d2, 0x6958, 0x810f, 0xa18c, 0x00ff,
- 0xa082, 0x0004, 0x00c0, 0x40ca, 0x2100, 0xa318, 0x0048, 0x40dd,
- 0x0078, 0x40d2, 0xa082, 0x0004, 0x00c0, 0x40dd, 0x2100, 0xa31a,
- 0x0048, 0x40dd, 0x6860, 0xa005, 0x0040, 0x40d8, 0x8000, 0x6016,
- 0x6206, 0x630a, 0x127f, 0x0078, 0x425d, 0x127f, 0x0078, 0x4259,
- 0x127f, 0x0078, 0x4255, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001,
- 0x2009, 0x0000, 0x1078, 0x428a, 0x6308, 0x8318, 0x0048, 0x40f4,
- 0x630a, 0x127f, 0x0078, 0x426b, 0x127f, 0x0078, 0x4259, 0x127e,
- 0x0c7e, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0040,
- 0x410d, 0x2009, 0x0000, 0x0c7e, 0x1078, 0x4727, 0x6000, 0x2001,
- 0xfcff, 0x6002, 0x0c7f, 0x0078, 0x4144, 0x6858, 0xa005, 0x0040,
- 0x4159, 0x685c, 0xa065, 0x0040, 0x4155, 0x2001, 0x772c, 0x2004,
- 0xa005, 0x0040, 0x411f, 0x1078, 0x6bb6, 0x0078, 0x4125, 0x6013,
- 0x0400, 0x2009, 0x0041, 0x1078, 0x5d41, 0x6958, 0xa18c, 0xe600,
- 0xa186, 0x2000, 0x0040, 0x413c, 0xa186, 0x0400, 0x0040, 0x413c,
- 0x2009, 0x0000, 0x0c7e, 0x1078, 0x4727, 0x6000, 0xa084, 0xfdff,
- 0x6002, 0x0c7f, 0x0078, 0x4144, 0x027e, 0x2009, 0x0000, 0x2011,
- 0xfdff, 0x1078, 0x47d0, 0x027f, 0x684c, 0xd0c4, 0x0040, 0x4151,
- 0x2009, 0x0000, 0x1078, 0x4727, 0x6008, 0x8000, 0x0048, 0x4151,
- 0x600a, 0x0c7f, 0x127f, 0x0078, 0x425d, 0x0c7f, 0x127f, 0x0078,
- 0x4255, 0x6954, 0xa186, 0x002a, 0x00c0, 0x4165, 0x2001, 0x770c,
- 0x200c, 0xc194, 0x2102, 0x0078, 0x4144, 0xa186, 0x0020, 0x0040,
- 0x417a, 0xa186, 0x0029, 0x00c0, 0x4155, 0x6944, 0xa18c, 0xff00,
- 0x810f, 0x1078, 0x384c, 0x00c0, 0x4144, 0x6000, 0xc0e4, 0x6002,
- 0x0078, 0x4144, 0x685c, 0xa065, 0x0040, 0x4155, 0x6017, 0x0014,
- 0x0078, 0x4144, 0x2009, 0x0000, 0x1078, 0x428a, 0x6000, 0xa084,
- 0x0001, 0x0040, 0x419c, 0x2091, 0x8000, 0x6204, 0x8210, 0x0048,
- 0x4196, 0x6206, 0x2091, 0x8001, 0x0078, 0x426b, 0x2091, 0x8001,
- 0x6853, 0x0016, 0x0078, 0x4264, 0x6853, 0x0007, 0x0078, 0x4264,
- 0x6834, 0x8007, 0xa084, 0x00ff, 0x00c0, 0x41aa, 0x1078, 0x3f08,
- 0x0078, 0x41bc, 0x2030, 0x8001, 0x00c0, 0x41b4, 0x7007, 0x0001,
- 0x1078, 0x41bd, 0x0078, 0x41bc, 0x7007, 0x0006, 0x7012, 0x2d00,
- 0x7016, 0x701a, 0x704b, 0x41bd, 0x007c, 0x0e7e, 0x2009, 0x772c,
- 0x210c, 0x81ff, 0x00c0, 0x423f, 0x2009, 0x770c, 0x210c, 0xd194,
- 0x00c0, 0x4249, 0x6848, 0x2070, 0xae82, 0x7e00, 0x0048, 0x422e,
- 0x2001, 0x7715, 0x2004, 0xae02, 0x00c8, 0x422e, 0x2009, 0x0000,
- 0x1078, 0x428a, 0x6100, 0xa184, 0x0001, 0x0040, 0x4214, 0xa184,
- 0x0100, 0x00c0, 0x4232, 0xa184, 0x0200, 0x00c0, 0x4236, 0x601c,
- 0xa005, 0x00c0, 0x423a, 0x711c, 0xa186, 0x0006, 0x00c0, 0x4219,
- 0x6853, 0x0000, 0x6803, 0x0000, 0x2d08, 0x127e, 0x2091, 0x8000,
- 0x7010, 0xa005, 0x00c0, 0x420b, 0x7112, 0x7018, 0xa065, 0x0040,
- 0x423e, 0x6000, 0xd0e4, 0x00c0, 0x4243, 0x2e60, 0x1078, 0x4730,
- 0x127f, 0x0e7f, 0x007c, 0x2068, 0x6800, 0xa005, 0x00c0, 0x420b,
- 0x6902, 0x127f, 0x0e7f, 0x007c, 0x0e7f, 0x6853, 0x0006, 0x0078,
- 0x4264, 0x6944, 0xa18c, 0xff00, 0x810f, 0x1078, 0x384c, 0x00c0,
- 0x4244, 0x6000, 0xd0e4, 0x00c0, 0x4244, 0x711c, 0xa186, 0x0007,
- 0x00c0, 0x422e, 0x6853, 0x0002, 0x0078, 0x4246, 0x6853, 0x0008,
- 0x0078, 0x4246, 0x6853, 0x000e, 0x0078, 0x4246, 0x6853, 0x0017,
- 0x0078, 0x4246, 0x6853, 0x0035, 0x0078, 0x4246, 0x127f, 0x6853,
- 0x0028, 0x0078, 0x4246, 0x127f, 0x6853, 0x0029, 0x0e7f, 0x0078,
- 0x4264, 0x6853, 0x002a, 0x0078, 0x4246, 0x2009, 0x003e, 0x0078,
- 0x425f, 0x2009, 0x0004, 0x0078, 0x425f, 0x2009, 0x0006, 0x0078,
- 0x425f, 0x2009, 0x0016, 0x0078, 0x425f, 0x2009, 0x0001, 0x6854,
- 0xa084, 0xff00, 0xa105, 0x6856, 0x2091, 0x8000, 0x1078, 0x3b92,
- 0x2091, 0x8001, 0x007c, 0x1078, 0x1340, 0x007c, 0x702c, 0x7130,
- 0x8108, 0xa102, 0x0048, 0x427b, 0xa00e, 0x7034, 0x7072, 0x7038,
- 0x7076, 0x0078, 0x4287, 0x7070, 0xa080, 0x0040, 0x7072, 0x00c8,
- 0x4287, 0x7074, 0xa081, 0x0000, 0x7076, 0xa085, 0x0001, 0x7932,
- 0x7132, 0x007c, 0x0d7e, 0x1078, 0x4727, 0x0d7f, 0x007c, 0x0d7e,
+ 0x00f0, 0x41dd, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006,
+ 0x0078, 0x41e4, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d,
+ 0x0040, 0x41f8, 0x60a7, 0x0000, 0x1078, 0x1344, 0xa085, 0x0001,
+ 0x127f, 0x0d7f, 0x007c, 0x60a8, 0xa00d, 0x00c0, 0x4202, 0xa085,
+ 0x0001, 0x007c, 0x0e7e, 0x2170, 0x7050, 0xa005, 0x00c0, 0x4215,
+ 0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0040, 0x4215,
+ 0x8108, 0x00f0, 0x420c, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x127e,
+ 0x2091, 0x8000, 0x1078, 0x41fb, 0x00c0, 0x4231, 0x200b, 0xffff,
+ 0x0d7e, 0x60a8, 0x2068, 0x6854, 0xa08a, 0x0002, 0x0048, 0x422c,
+ 0x8001, 0x6856, 0x0078, 0x4230, 0x1078, 0x1344, 0x60ab, 0x0000,
+ 0x0d7f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c, 0x0f7e, 0x2079,
+ 0x8851, 0x7804, 0xd0a4, 0x0040, 0x4263, 0x157e, 0x0c7e, 0x20a9,
+ 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x3f8e, 0x00c0, 0x4257,
+ 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004, 0x0040, 0x4254,
+ 0xa086, 0x0006, 0x00c0, 0x4257, 0x6000, 0xc0ed, 0x6002, 0x017f,
+ 0x8108, 0x00f0, 0x4243, 0x0c7f, 0x157f, 0x2009, 0x07d0, 0x2011,
+ 0x4265, 0x1078, 0x5181, 0x0f7f, 0x007c, 0x2011, 0x4265, 0x1078,
+ 0x50f2, 0x157e, 0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e,
+ 0x1078, 0x3f8e, 0x00c0, 0x429b, 0x6000, 0xd0ec, 0x0040, 0x429b,
+ 0x047e, 0x62a0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0x0029,
+ 0x1078, 0x86f5, 0x6000, 0xc0e5, 0xc0ec, 0x6002, 0x6004, 0xa084,
+ 0x00ff, 0xa085, 0x0700, 0x6006, 0x2019, 0x0029, 0x1078, 0x54f0,
+ 0x087e, 0x2041, 0x0000, 0x1078, 0x5419, 0x2009, 0x0000, 0x1078,
+ 0x84d2, 0x087f, 0x047f, 0x017f, 0x8108, 0x00f0, 0x426f, 0x0c7f,
+ 0x157f, 0x007c, 0x0c7e, 0x6018, 0x2060, 0x6000, 0xc0ec, 0x6002,
+ 0x0c7f, 0x007c, 0x2071, 0x8913, 0x7003, 0x0001, 0x7007, 0x0000,
+ 0x7013, 0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000,
+ 0x704b, 0x0001, 0x704f, 0x0000, 0x705b, 0x0020, 0x705f, 0x0040,
+ 0x707f, 0x0000, 0x2071, 0x8a7c, 0x7003, 0x8913, 0x7007, 0x0000,
+ 0x700b, 0x0000, 0x700f, 0x8a5c, 0x7013, 0x0020, 0x7017, 0x0040,
+ 0x7037, 0x0000, 0x007c, 0x017e, 0x0e7e, 0x2071, 0x8a34, 0xa00e,
+ 0x7186, 0x718a, 0x7097, 0x0001, 0x2001, 0x8852, 0x2004, 0xd0fc,
+ 0x00c0, 0x42ed, 0x2001, 0x8852, 0x2004, 0xa00e, 0xd09c, 0x0040,
+ 0x42ea, 0x8108, 0x7102, 0x0078, 0x4340, 0x2001, 0x8871, 0x200c,
+ 0xa184, 0x000f, 0x2009, 0x8872, 0x210c, 0x0079, 0x42f7, 0x42e2,
+ 0x4318, 0x4320, 0x432b, 0x4331, 0x42e2, 0x42e2, 0x42e2, 0x4307,
+ 0x42e2, 0x42e2, 0x42e2, 0x42e2, 0x42e2, 0x42e2, 0x42e2, 0x7003,
+ 0x0004, 0x137e, 0x147e, 0x157e, 0x2099, 0x8875, 0x20a1, 0x8a85,
+ 0x20a9, 0x0004, 0x53a3, 0x157f, 0x147f, 0x137f, 0x0078, 0x4340,
+ 0x708f, 0x0005, 0x7007, 0x0122, 0x2001, 0x0002, 0x0078, 0x4326,
+ 0x708f, 0x0002, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002, 0x7097,
+ 0x0001, 0x0078, 0x433d, 0x7007, 0x0122, 0x2001, 0x0002, 0x0078,
+ 0x4335, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002, 0xa006, 0x7096,
+ 0x708e, 0xa184, 0xff00, 0x8007, 0x709a, 0xa184, 0x00ff, 0x7092,
+ 0x0e7f, 0x017f, 0x007c, 0x0e7e, 0x2071, 0x8913, 0x684c, 0xa005,
+ 0x00c0, 0x4351, 0x7028, 0xc085, 0x702a, 0xa085, 0x0001, 0x0078,
+ 0x4374, 0x6a60, 0x7236, 0x6b64, 0x733a, 0x6868, 0x703e, 0x7076,
+ 0x686c, 0x7042, 0x707a, 0x684c, 0x702e, 0x6844, 0x7032, 0x2009,
+ 0x000d, 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084,
+ 0xffc0, 0xa210, 0x2100, 0xa319, 0x726e, 0x7372, 0x7028, 0xc084,
+ 0x702a, 0x7007, 0x0001, 0xa006, 0x0e7f, 0x007c, 0x0e7e, 0x027e,
+ 0x6838, 0xd0fc, 0x00c0, 0x43cc, 0x6804, 0xa00d, 0x0040, 0x4392,
+ 0x0d7e, 0x2071, 0x8800, 0xa016, 0x702c, 0x2168, 0x6904, 0x206a,
+ 0x8210, 0x2d00, 0x81ff, 0x00c0, 0x4385, 0x702e, 0x70a4, 0xa200,
+ 0x70a6, 0x0d7f, 0x2071, 0x8913, 0x701c, 0xa005, 0x00c0, 0x43de,
+ 0x0068, 0x43dc, 0x2071, 0x8a34, 0x7200, 0x82ff, 0x0040, 0x43dc,
+ 0x6934, 0xa186, 0x0103, 0x00c0, 0x43ef, 0x6948, 0x6844, 0xa105,
+ 0x00c0, 0x43cf, 0x2009, 0x8020, 0x2200, 0x0079, 0x43af, 0x43dc,
+ 0x43b4, 0x440c, 0x441a, 0x43dc, 0x2071, 0x0000, 0x7018, 0xd084,
+ 0x00c0, 0x43dc, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b,
+ 0x0001, 0x2091, 0x4080, 0x2071, 0x8800, 0x702c, 0x206a, 0x2d00,
+ 0x702e, 0x70a4, 0x8000, 0x70a6, 0x027f, 0x0e7f, 0x007c, 0x6844,
+ 0xa086, 0x0100, 0x00c0, 0x43dc, 0x6868, 0xa005, 0x00c0, 0x43dc,
+ 0x2009, 0x8020, 0x0078, 0x43ac, 0x2071, 0x8913, 0x2d08, 0x206b,
+ 0x0000, 0x7010, 0x8000, 0x7012, 0x7018, 0xa06d, 0x711a, 0x0040,
+ 0x43ec, 0x6902, 0x0078, 0x43ed, 0x711e, 0x0078, 0x43cc, 0xa18c,
+ 0x00ff, 0xa186, 0x0017, 0x0040, 0x43fd, 0xa186, 0x001e, 0x0040,
+ 0x43fd, 0xa18e, 0x001f, 0x00c0, 0x43dc, 0x684c, 0xd0cc, 0x0040,
+ 0x43dc, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, 0x43dc,
+ 0x2009, 0x8021, 0x0078, 0x43ac, 0x7084, 0x8008, 0xa092, 0x001e,
+ 0x00c8, 0x43dc, 0x7186, 0xae90, 0x0003, 0xa210, 0x683c, 0x2012,
+ 0x0078, 0x442a, 0x7084, 0x8008, 0xa092, 0x000f, 0x00c8, 0x43dc,
+ 0x7186, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210,
+ 0x6840, 0x2012, 0x7088, 0xa10a, 0x0048, 0x43c3, 0x718c, 0x7084,
+ 0xa10a, 0x0048, 0x43c3, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0,
+ 0x43c3, 0x2071, 0x8a34, 0x7000, 0xa086, 0x0002, 0x00c0, 0x444a,
+ 0x1078, 0x46a6, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
+ 0x0078, 0x43c3, 0x1078, 0x46d1, 0x2071, 0x0000, 0x701b, 0x0001,
+ 0x2091, 0x4080, 0x0078, 0x43c3, 0x007e, 0x684c, 0x007e, 0x6837,
+ 0x0103, 0x20a9, 0x001c, 0xad80, 0x0011, 0x20a0, 0x2001, 0x0000,
+ 0x40a4, 0x007f, 0xa084, 0x00ff, 0x684e, 0x007f, 0x684a, 0x6952,
+ 0x007c, 0x2071, 0x8913, 0x7004, 0x0079, 0x446e, 0x4478, 0x4487,
+ 0x4677, 0x4678, 0x469f, 0x46a5, 0x4479, 0x4665, 0x4608, 0x4688,
+ 0x007c, 0x127e, 0x2091, 0x8000, 0x0068, 0x4486, 0x2009, 0x000d,
+ 0x7030, 0x200a, 0x2091, 0x4080, 0x7007, 0x0001, 0x127f, 0x2069,
+ 0x8ab5, 0x6844, 0xa005, 0x0050, 0x44af, 0x00c0, 0x44af, 0x127e,
+ 0x2091, 0x8000, 0x2069, 0x0000, 0x6934, 0x2001, 0x891f, 0x2004,
+ 0xa10a, 0x0040, 0x44aa, 0x0068, 0x44af, 0x2069, 0x0000, 0x6818,
+ 0xd084, 0x00c0, 0x44ae, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001,
+ 0x2091, 0x4080, 0x2069, 0x8ab5, 0x6847, 0xffff, 0x127f, 0x2069,
+ 0x8800, 0x6844, 0x6960, 0xa102, 0x2069, 0x8a34, 0x688a, 0x6984,
+ 0x701c, 0xa06d, 0x0040, 0x44c1, 0x81ff, 0x0040, 0x4509, 0x0078,
+ 0x44d7, 0x81ff, 0x0040, 0x45db, 0x2071, 0x8a34, 0x7184, 0x7088,
+ 0xa10a, 0x00c8, 0x44d7, 0x7190, 0x2071, 0x8ab5, 0x7040, 0xa005,
+ 0x0040, 0x44d7, 0x00d0, 0x45db, 0x7142, 0x0078, 0x45db, 0x2071,
+ 0x8a34, 0x718c, 0x127e, 0x2091, 0x8000, 0x7084, 0xa10a, 0x0048,
+ 0x45dc, 0x0068, 0x458d, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0,
+ 0x458d, 0x2001, 0xffff, 0x2071, 0x8ab5, 0x7042, 0x2071, 0x8a34,
+ 0x7000, 0xa086, 0x0002, 0x00c0, 0x44ff, 0x1078, 0x46a6, 0x2071,
+ 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x458d, 0x1078,
+ 0x46d1, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078,
+ 0x458d, 0x2071, 0x8a34, 0x7000, 0xa005, 0x0040, 0x45ba, 0x6934,
+ 0xa186, 0x0103, 0x00c0, 0x4590, 0x684c, 0xd0bc, 0x00c0, 0x45ba,
+ 0x6948, 0x6844, 0xa105, 0x00c0, 0x45ad, 0x2071, 0x8a34, 0x7000,
+ 0x0079, 0x4522, 0x45ba, 0x4570, 0x4548, 0x455a, 0x4527, 0x137e,
+ 0x147e, 0x157e, 0x2099, 0x8875, 0x20a1, 0x8a85, 0x20a9, 0x0004,
+ 0x53a3, 0x157f, 0x147f, 0x137f, 0x2071, 0x8a7c, 0xad80, 0x000f,
+ 0x700e, 0x7013, 0x0002, 0x7007, 0x0002, 0x700b, 0x0000, 0x2e10,
+ 0x1078, 0x137b, 0x2071, 0x8913, 0x7007, 0x0009, 0x0078, 0x45db,
+ 0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x45db, 0xae90, 0x0003,
+ 0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0x8913, 0x1078, 0x4731,
+ 0x0078, 0x45db, 0x7084, 0x8008, 0xa092, 0x000f, 0x00c8, 0x45db,
+ 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, 0x6840,
+ 0x2012, 0x7186, 0x2071, 0x8913, 0x1078, 0x4731, 0x0078, 0x45db,
+ 0x2009, 0x8020, 0x127e, 0x2091, 0x8000, 0x0068, 0x458d, 0x2071,
+ 0x0000, 0x7018, 0xd084, 0x00c0, 0x458d, 0x7122, 0x683c, 0x7026,
+ 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x127f, 0x2071,
+ 0x8913, 0x1078, 0x4731, 0x0078, 0x45db, 0x127f, 0x0078, 0x45db,
+ 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0040, 0x459e, 0xa186, 0x001e,
+ 0x0040, 0x459e, 0xa18e, 0x001f, 0x00c0, 0x45ba, 0x684c, 0xd0cc,
+ 0x0040, 0x45ba, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0,
+ 0x45ba, 0x2009, 0x8021, 0x0078, 0x4572, 0x6844, 0xa086, 0x0100,
+ 0x00c0, 0x45ba, 0x6868, 0xa005, 0x00c0, 0x45ba, 0x2009, 0x8020,
+ 0x0078, 0x4572, 0x2071, 0x8913, 0x1078, 0x4745, 0x0040, 0x45db,
+ 0x2071, 0x8913, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086,
+ 0x0003, 0x00c0, 0x45d2, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040,
+ 0x45d2, 0x710e, 0x7007, 0x0003, 0x1078, 0x4765, 0x7050, 0xa086,
+ 0x0100, 0x0040, 0x4678, 0x007c, 0x2071, 0x8913, 0x1078, 0x4745,
+ 0x0040, 0x4605, 0x2071, 0x8a34, 0x7084, 0x700a, 0x20a9, 0x0020,
+ 0x2099, 0x8a35, 0x20a1, 0x8a5c, 0x53a3, 0x7087, 0x0000, 0x2071,
+ 0x8913, 0x2069, 0x8a7c, 0x706c, 0x6826, 0x7070, 0x682a, 0x7074,
+ 0x682e, 0x7078, 0x6832, 0x2d10, 0x1078, 0x137b, 0x7007, 0x0008,
+ 0x2001, 0xffff, 0x2071, 0x8ab5, 0x7042, 0x127f, 0x0078, 0x45db,
+ 0x2069, 0x8a7c, 0x6808, 0xa08e, 0x0000, 0x0040, 0x4664, 0xa08e,
+ 0x0200, 0x0040, 0x4662, 0xa08e, 0x0100, 0x00c0, 0x4664, 0x127e,
+ 0x2091, 0x8000, 0x0068, 0x465f, 0x2069, 0x0000, 0x6818, 0xd084,
+ 0x00c0, 0x465f, 0x702c, 0x7130, 0x8108, 0xa102, 0x0048, 0x462f,
+ 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0078, 0x4639, 0x706c,
+ 0xa080, 0x0040, 0x706e, 0x00c8, 0x4639, 0x7070, 0xa081, 0x0000,
+ 0x7072, 0x7132, 0x6936, 0x2001, 0x8a59, 0x2004, 0xa005, 0x00c0,
+ 0x4656, 0x6934, 0x2069, 0x8a34, 0x689c, 0x699e, 0x2069, 0x8ab5,
+ 0xa102, 0x00c0, 0x464f, 0x6844, 0xa005, 0x00d0, 0x465d, 0x2001,
+ 0x8a5a, 0x200c, 0x810d, 0x6946, 0x0078, 0x465d, 0x2009, 0x8040,
+ 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x127f,
+ 0x0078, 0x4664, 0x7007, 0x0005, 0x007c, 0x701c, 0xa06d, 0x0040,
+ 0x4676, 0x1078, 0x4745, 0x0040, 0x4676, 0x7007, 0x0003, 0x1078,
+ 0x4765, 0x7050, 0xa086, 0x0100, 0x0040, 0x4678, 0x007c, 0x007c,
+ 0x7050, 0xa09e, 0x0100, 0x00c0, 0x4681, 0x7007, 0x0004, 0x0078,
+ 0x469f, 0xa086, 0x0200, 0x00c0, 0x4687, 0x7007, 0x0005, 0x007c,
+ 0x2001, 0x8a7e, 0x2004, 0xa08e, 0x0100, 0x00c0, 0x4694, 0x7007,
+ 0x0001, 0x1078, 0x4731, 0x007c, 0xa08e, 0x0000, 0x0040, 0x4693,
+ 0xa08e, 0x0200, 0x00c0, 0x4693, 0x7007, 0x0005, 0x007c, 0x1078,
+ 0x46f9, 0x7006, 0x1078, 0x4731, 0x007c, 0x007c, 0x0e7e, 0x157e,
+ 0x2071, 0x8a34, 0x7184, 0x81ff, 0x0040, 0x46ce, 0xa006, 0x7086,
+ 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000,
+ 0x0070, 0x46cb, 0x2014, 0x722a, 0x8000, 0x0070, 0x46cb, 0x2014,
+ 0x722e, 0x8000, 0x0070, 0x46cb, 0x2014, 0x723a, 0x8000, 0x0070,
+ 0x46cb, 0x2014, 0x723e, 0xa180, 0x8030, 0x7022, 0x157f, 0x0e7f,
+ 0x007c, 0x0e7e, 0x157e, 0x2071, 0x8a34, 0x7184, 0x81ff, 0x0040,
+ 0x46f6, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8,
+ 0x2014, 0x7226, 0x8000, 0x2014, 0x722a, 0x8000, 0x0070, 0x46ef,
+ 0x2014, 0x723a, 0x8000, 0x2014, 0x723e, 0x0078, 0x46f3, 0x2001,
+ 0x8020, 0x0078, 0x46f5, 0xa180, 0x8042, 0x7022, 0x157f, 0x0e7f,
+ 0x007c, 0x702c, 0x7130, 0x8108, 0xa102, 0x0048, 0x4706, 0xa00e,
+ 0x7034, 0x706e, 0x7038, 0x7072, 0x0078, 0x4710, 0x706c, 0xa080,
+ 0x0040, 0x706e, 0x00c8, 0x4710, 0x7070, 0xa081, 0x0000, 0x7072,
+ 0x7132, 0x700c, 0x8001, 0x700e, 0x00c0, 0x472a, 0x127e, 0x2091,
+ 0x8000, 0x0068, 0x472d, 0x2001, 0x000d, 0x2102, 0x2091, 0x4080,
+ 0x2001, 0x0001, 0x127f, 0x007c, 0x2001, 0x000d, 0x2102, 0x2001,
+ 0x0001, 0x007c, 0x2001, 0x0007, 0x007c, 0x2001, 0x0006, 0x127f,
+ 0x007c, 0x701c, 0xa06d, 0x0040, 0x4744, 0x127e, 0x2091, 0x8000,
+ 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, 0xa005, 0x00c0, 0x4741,
+ 0x701a, 0x127f, 0x1078, 0x1344, 0x007c, 0x2019, 0x000d, 0x2304,
+ 0x230c, 0xa10e, 0x0040, 0x4754, 0x2304, 0x230c, 0xa10e, 0x0040,
+ 0x4754, 0xa006, 0x0078, 0x4764, 0x732c, 0x8319, 0x7130, 0xa102,
+ 0x00c0, 0x475e, 0x2300, 0xa005, 0x0078, 0x4764, 0x0048, 0x4763,
+ 0xa302, 0x0078, 0x4764, 0x8002, 0x007c, 0x2d00, 0x7026, 0xa080,
+ 0x000d, 0x7056, 0x7053, 0x0000, 0x127e, 0x2091, 0x8000, 0x2009,
+ 0x8ac7, 0x2104, 0xc08d, 0x200a, 0x127f, 0x1078, 0x1395, 0x007c,
+ 0x2071, 0x88e1, 0x7003, 0x0000, 0x7007, 0x0000, 0x700f, 0x0000,
+ 0x702b, 0x0001, 0x704f, 0x0000, 0x7053, 0x0001, 0x705f, 0x0020,
+ 0x7063, 0x0040, 0x7083, 0x0000, 0x708b, 0x0000, 0x708f, 0x0001,
+ 0x70bf, 0x0000, 0x007c, 0x0e7e, 0x2071, 0x88e1, 0x6848, 0xa005,
+ 0x00c0, 0x47a1, 0x7028, 0xc085, 0x702a, 0xa085, 0x0001, 0x0078,
+ 0x47c6, 0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858, 0x703e, 0x707a,
+ 0x685c, 0x7042, 0x707e, 0x6848, 0x702e, 0x6840, 0x7032, 0x2009,
+ 0x000c, 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084,
+ 0xffc0, 0xa210, 0x2100, 0xa319, 0x7272, 0x7376, 0x7028, 0xc084,
+ 0x702a, 0x7007, 0x0001, 0x700f, 0x0000, 0xa006, 0x0e7f, 0x007c,
+ 0x2b78, 0x2071, 0x88e1, 0x7004, 0x1079, 0x4826, 0x700c, 0x0079,
+ 0x47d1, 0x47d6, 0x47cb, 0x47cb, 0x47cb, 0x47cb, 0x007c, 0x700c,
+ 0x0079, 0x47da, 0x47df, 0x4824, 0x4824, 0x4825, 0x4825, 0x7830,
+ 0x7930, 0xa106, 0x0040, 0x47e9, 0x7830, 0x7930, 0xa106, 0x00c0,
+ 0x480f, 0x7030, 0xa10a, 0x0040, 0x480f, 0x00c8, 0x47f1, 0x712c,
+ 0xa10a, 0xa18a, 0x0002, 0x00c8, 0x4810, 0x1078, 0x1310, 0x0040,
+ 0x480f, 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001, 0x0003, 0x7057,
+ 0x0000, 0x127e, 0x007e, 0x2091, 0x8000, 0x2009, 0x8ac7, 0x2104,
+ 0xc085, 0x200a, 0x007f, 0x700e, 0x127f, 0x1078, 0x1395, 0x007c,
+ 0x1078, 0x1310, 0x0040, 0x480f, 0x2d00, 0x705a, 0x1078, 0x1310,
+ 0x00c0, 0x481c, 0x0078, 0x47fb, 0x2d00, 0x7086, 0x7063, 0x0080,
+ 0x2001, 0x0004, 0x0078, 0x47ff, 0x007c, 0x007c, 0x4837, 0x4838,
+ 0x486f, 0x4870, 0x4824, 0x48a6, 0x48ab, 0x48e2, 0x48e3, 0x48fe,
+ 0x48ff, 0x4900, 0x4901, 0x4902, 0x4903, 0x496c, 0x4996, 0x007c,
+ 0x700c, 0x0079, 0x483b, 0x4840, 0x4843, 0x4853, 0x486e, 0x486e,
+ 0x1078, 0x47d7, 0x007c, 0x127e, 0x8001, 0x700e, 0x7058, 0x007e,
+ 0x1078, 0x4c96, 0x0040, 0x4850, 0x2091, 0x8000, 0x1078, 0x47d7,
+ 0x0d7f, 0x0078, 0x485c, 0x127e, 0x8001, 0x700e, 0x1078, 0x4c96,
+ 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000,
+ 0x6834, 0xa084, 0x00ff, 0xa08a, 0x0020, 0x00c8, 0x486b, 0x1079,
+ 0x4886, 0x127f, 0x007c, 0x127f, 0x1078, 0x4904, 0x007c, 0x007c,
+ 0x007c, 0x0e7e, 0x2071, 0x88e1, 0x700c, 0x0079, 0x4877, 0x487c,
+ 0x487c, 0x487c, 0x487e, 0x4882, 0x0e7f, 0x007c, 0x700f, 0x0001,
+ 0x0078, 0x4884, 0x700f, 0x0002, 0x0e7f, 0x007c, 0x4904, 0x4904,
+ 0x4920, 0x4904, 0x4a0b, 0x4904, 0x4904, 0x4904, 0x4904, 0x4904,
+ 0x4920, 0x4a55, 0x4aa2, 0x4afb, 0x4b11, 0x4904, 0x4904, 0x493c,
+ 0x4920, 0x4904, 0x4904, 0x4952, 0x4bac, 0x4bca, 0x4904, 0x493c,
+ 0x4904, 0x4904, 0x4904, 0x4904, 0x4952, 0x4bca, 0x7020, 0x2068,
+ 0x1078, 0x1344, 0x007c, 0x700c, 0x0079, 0x48ae, 0x48b3, 0x48b6,
+ 0x48c6, 0x48e1, 0x48e1, 0x1078, 0x47d7, 0x007c, 0x127e, 0x8001,
+ 0x700e, 0x7058, 0x007e, 0x1078, 0x4c96, 0x0040, 0x48c3, 0x2091,
+ 0x8000, 0x1078, 0x47d7, 0x0d7f, 0x0078, 0x48cf, 0x127e, 0x8001,
+ 0x700e, 0x1078, 0x4c96, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803,
+ 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x001a,
+ 0x00c8, 0x48de, 0x1079, 0x48e4, 0x127f, 0x007c, 0x127f, 0x1078,
+ 0x4904, 0x007c, 0x007c, 0x007c, 0x4904, 0x4920, 0x49f5, 0x4904,
+ 0x4920, 0x4904, 0x4920, 0x4920, 0x4904, 0x4920, 0x49f5, 0x4920,
+ 0x4920, 0x4920, 0x4920, 0x4920, 0x4904, 0x4920, 0x49f5, 0x4904,
+ 0x4904, 0x4920, 0x4904, 0x4904, 0x4904, 0x4920, 0x007c, 0x007c,
+ 0x007c, 0x007c, 0x007c, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084,
+ 0x00ff, 0xc0d5, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4376,
+ 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5,
+ 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4376, 0x127f, 0x007c,
+ 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed, 0x683a, 0x127e,
+ 0x2091, 0x8000, 0x1078, 0x4376, 0x127f, 0x007c, 0x7007, 0x0001,
+ 0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x127e, 0x2091, 0x8000,
+ 0x1078, 0x4376, 0x127f, 0x007c, 0x6834, 0x8007, 0xa084, 0x00ff,
+ 0x0040, 0x4912, 0x8001, 0x00c0, 0x4949, 0x7007, 0x0001, 0x0078,
+ 0x49d2, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b,
+ 0x49d2, 0x007c, 0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080,
+ 0x0024, 0x2098, 0x20a1, 0x890c, 0x53a3, 0x6858, 0x7012, 0xa082,
+ 0x0401, 0x00c8, 0x492e, 0x6884, 0xa08a, 0x0003, 0x00c8, 0x492e,
+ 0xa080, 0x49c3, 0x2004, 0x70c6, 0x7010, 0xa015, 0x0040, 0x49b6,
+ 0x1078, 0x1310, 0x00c0, 0x4977, 0x7007, 0x000f, 0x007c, 0x2d00,
+ 0x7022, 0x70c4, 0x2060, 0x6000, 0x6836, 0x6004, 0xad00, 0x7096,
+ 0x6008, 0xa20a, 0x00c8, 0x4986, 0xa00e, 0x2200, 0x7112, 0x620c,
+ 0x8003, 0x800b, 0xa296, 0x0004, 0x0040, 0x498f, 0xa108, 0x719a,
+ 0x810b, 0x719e, 0xae90, 0x0022, 0x1078, 0x137b, 0x7090, 0xa08e,
+ 0x0100, 0x0040, 0x49aa, 0xa086, 0x0200, 0x0040, 0x49a2, 0x7007,
+ 0x0010, 0x007c, 0x7020, 0x2068, 0x1078, 0x1344, 0x7014, 0x2068,
+ 0x0078, 0x492e, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807, 0x0000,
+ 0x2d08, 0x2068, 0x6906, 0x711a, 0x0078, 0x496c, 0x7014, 0x2068,
+ 0x7007, 0x0001, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x0040,
+ 0x4be7, 0x0078, 0x49d2, 0x49c6, 0x49ca, 0x49ce, 0x0002, 0x0011,
+ 0x0007, 0x0004, 0x000a, 0x000f, 0x0005, 0x0006, 0x0012, 0x000f,
+ 0x0005, 0x0006, 0x2009, 0x882d, 0x210c, 0x81ff, 0x00c0, 0x49ef,
+ 0x6838, 0xa084, 0x00ff, 0x683a, 0x6853, 0x0000, 0x1078, 0x3d8b,
+ 0x00c0, 0x49e3, 0x007c, 0x1078, 0x4454, 0x127e, 0x2091, 0x8000,
+ 0x1078, 0x7a46, 0x1078, 0x4376, 0x127f, 0x0078, 0x49e2, 0x2001,
+ 0x0028, 0x2009, 0x0000, 0x0078, 0x49e3, 0x7018, 0x6802, 0x2d08,
+ 0x2068, 0x6906, 0x711a, 0x7010, 0x8001, 0x7012, 0x0040, 0x4a04,
+ 0x7007, 0x0006, 0x0078, 0x4a0a, 0x7014, 0x2068, 0x7007, 0x0001,
+ 0x7048, 0x107a, 0x007c, 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c,
+ 0x00ff, 0x6848, 0xa084, 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001,
+ 0x0040, 0x4a34, 0x2009, 0x0000, 0x20a9, 0x007e, 0xa096, 0x0002,
+ 0x0040, 0x4a34, 0xa005, 0x00c0, 0x4a47, 0x6944, 0x810f, 0xa18c,
+ 0x00ff, 0x1078, 0x3f8e, 0x00c0, 0x4a47, 0x067e, 0x6e50, 0x1078,
+ 0x4057, 0x067f, 0x0078, 0x4a47, 0x047e, 0x2011, 0x880c, 0x2224,
+ 0xc484, 0xc48c, 0x2412, 0x047f, 0x0c7e, 0x1078, 0x3f8e, 0x00c0,
+ 0x4a43, 0x1078, 0x41ea, 0x8108, 0x00f0, 0x4a3d, 0x0c7f, 0x684c,
+ 0xd084, 0x00c0, 0x4a4e, 0x1078, 0x1344, 0x007c, 0x127e, 0x2091,
+ 0x8000, 0x1078, 0x4376, 0x127f, 0x007c, 0x127e, 0x2091, 0x8000,
+ 0x7007, 0x0001, 0x2001, 0x8852, 0x2004, 0xd0a4, 0x0040, 0x4a99,
+ 0x2061, 0x8b24, 0x6100, 0xd184, 0x0040, 0x4a79, 0x6858, 0xa084,
+ 0x00ff, 0x00c0, 0x4a9c, 0x6000, 0xd084, 0x0040, 0x4a99, 0x6004,
+ 0xa005, 0x00c0, 0x4a9f, 0x6003, 0x0000, 0x600b, 0x0000, 0x0078,
+ 0x4a96, 0x2011, 0x0001, 0x6860, 0xa005, 0x00c0, 0x4a81, 0x2001,
+ 0x001e, 0x8000, 0x6016, 0x6858, 0xa084, 0x00ff, 0x0040, 0x4a99,
+ 0x6006, 0x6858, 0x8007, 0xa084, 0x00ff, 0x0040, 0x4a99, 0x600a,
+ 0x6858, 0x8000, 0x00c0, 0x4a95, 0xc28d, 0x6202, 0x127f, 0x0078,
+ 0x4c85, 0x127f, 0x0078, 0x4c7d, 0x127f, 0x0078, 0x4c75, 0x127f,
+ 0x0078, 0x4c79, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001,
+ 0x8852, 0x2004, 0xd0a4, 0x0040, 0x4af8, 0x2061, 0x8b24, 0x6000,
+ 0xd084, 0x0040, 0x4af8, 0x6204, 0x6308, 0xd08c, 0x00c0, 0x4aea,
+ 0x6c48, 0xa484, 0x0003, 0x0040, 0x4ad0, 0x6958, 0xa18c, 0x00ff,
+ 0x8001, 0x00c0, 0x4ac9, 0x2100, 0xa210, 0x0048, 0x4af5, 0x0078,
+ 0x4ad0, 0x8001, 0x00c0, 0x4af5, 0x2100, 0xa212, 0x0048, 0x4af5,
+ 0xa484, 0x000c, 0x0040, 0x4aea, 0x6958, 0x810f, 0xa18c, 0x00ff,
+ 0xa082, 0x0004, 0x00c0, 0x4ae2, 0x2100, 0xa318, 0x0048, 0x4af5,
+ 0x0078, 0x4aea, 0xa082, 0x0004, 0x00c0, 0x4af5, 0x2100, 0xa31a,
+ 0x0048, 0x4af5, 0x6860, 0xa005, 0x0040, 0x4af0, 0x8000, 0x6016,
+ 0x6206, 0x630a, 0x127f, 0x0078, 0x4c85, 0x127f, 0x0078, 0x4c81,
+ 0x127f, 0x0078, 0x4c7d, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001,
+ 0x2061, 0x8b24, 0x6300, 0xd38c, 0x00c0, 0x4b0b, 0x6308, 0x8318,
+ 0x0048, 0x4b0e, 0x630a, 0x127f, 0x0078, 0x4c93, 0x127f, 0x0078,
+ 0x4c81, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c,
+ 0xd0ac, 0x0040, 0x4b25, 0x0c7e, 0x2061, 0x8b24, 0x6000, 0xa084,
+ 0xfcff, 0x6002, 0x0c7f, 0x0078, 0x4b68, 0x6858, 0xa005, 0x0040,
+ 0x4b7f, 0x685c, 0xa065, 0x0040, 0x4b7b, 0x2001, 0x882d, 0x2004,
+ 0xa005, 0x0040, 0x4b37, 0x1078, 0x79a8, 0x0078, 0x4b45, 0x6013,
+ 0x0400, 0x6027, 0x0000, 0x694c, 0xd1a4, 0x0040, 0x4b41, 0x6950,
+ 0x6126, 0x2009, 0x0041, 0x1078, 0x6939, 0x6958, 0xa18c, 0xff00,
+ 0xa186, 0x2000, 0x0040, 0x4b60, 0xa186, 0x0400, 0x0040, 0x4b60,
+ 0xa186, 0x1000, 0x0040, 0x4b56, 0x0078, 0x4b68, 0x0c7e, 0x2061,
+ 0x8b24, 0x6000, 0xa084, 0xfdff, 0x6002, 0x0c7f, 0x0078, 0x4b68,
+ 0x027e, 0x2009, 0x0000, 0x2011, 0xfdff, 0x1078, 0x5243, 0x027f,
+ 0x684c, 0xd0c4, 0x0040, 0x4b77, 0x2061, 0x8b24, 0x6000, 0xd08c,
+ 0x00c0, 0x4b77, 0x6008, 0x8000, 0x0048, 0x4b7b, 0x600a, 0x0c7f,
+ 0x127f, 0x0078, 0x4c85, 0x0c7f, 0x127f, 0x0078, 0x4c7d, 0x6954,
+ 0xa186, 0x002a, 0x00c0, 0x4b8b, 0x2001, 0x880c, 0x200c, 0xc194,
+ 0x2102, 0x0078, 0x4b68, 0xa186, 0x0020, 0x0040, 0x4ba4, 0xa186,
+ 0x0029, 0x0040, 0x4b97, 0xa186, 0x002d, 0x00c0, 0x4b7b, 0x6944,
+ 0xa18c, 0xff00, 0x810f, 0x1078, 0x3f8e, 0x00c0, 0x4b68, 0x6000,
+ 0xc0e4, 0x6002, 0x0078, 0x4b68, 0x685c, 0xa065, 0x0040, 0x4b7b,
+ 0x6017, 0x0014, 0x0078, 0x4b68, 0x2061, 0x8b24, 0x6000, 0xd084,
+ 0x0040, 0x4bc6, 0xd08c, 0x00c0, 0x4c93, 0x2091, 0x8000, 0x6204,
+ 0x8210, 0x0048, 0x4bc0, 0x6206, 0x2091, 0x8001, 0x0078, 0x4c93,
+ 0x2091, 0x8001, 0x6853, 0x0016, 0x0078, 0x4c8c, 0x6853, 0x0007,
+ 0x0078, 0x4c8c, 0x6834, 0x8007, 0xa084, 0x00ff, 0x00c0, 0x4bd4,
+ 0x1078, 0x4912, 0x0078, 0x4be6, 0x2030, 0x8001, 0x00c0, 0x4bde,
+ 0x7007, 0x0001, 0x1078, 0x4be7, 0x0078, 0x4be6, 0x7007, 0x0006,
+ 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x4be7, 0x007c, 0x0e7e,
+ 0x127e, 0x2091, 0x8000, 0x2009, 0x882d, 0x210c, 0x81ff, 0x00c0,
+ 0x4c67, 0x2009, 0x880c, 0x210c, 0xd194, 0x00c0, 0x4c71, 0x6848,
+ 0x2070, 0xae82, 0x8f00, 0x0048, 0x4c57, 0x2001, 0x8815, 0x2004,
+ 0xae02, 0x00c8, 0x4c57, 0x2061, 0x8b24, 0x6100, 0xa184, 0x0001,
+ 0x0040, 0x4c3c, 0xa184, 0x0100, 0x00c0, 0x4c5b, 0xa184, 0x0200,
+ 0x00c0, 0x4c5f, 0x601c, 0xa005, 0x00c0, 0x4c63, 0x711c, 0xa186,
+ 0x0006, 0x00c0, 0x4c42, 0x7018, 0xa005, 0x0040, 0x4c67, 0x2004,
+ 0xd0e4, 0x00c0, 0x4c6b, 0x6853, 0x0000, 0x6803, 0x0000, 0x2d08,
+ 0x7010, 0xa005, 0x00c0, 0x4c33, 0x7112, 0x2e60, 0x1078, 0x5198,
+ 0x127f, 0x0e7f, 0x007c, 0x2068, 0x6800, 0xa005, 0x00c0, 0x4c33,
+ 0x6902, 0x127f, 0x0e7f, 0x007c, 0x127f, 0x0e7f, 0x6853, 0x0006,
+ 0x0078, 0x4c8c, 0x6944, 0xa18c, 0xff00, 0x810f, 0x1078, 0x3f8e,
+ 0x00c0, 0x4c6b, 0x6000, 0xd0e4, 0x00c0, 0x4c6b, 0x711c, 0xa186,
+ 0x0007, 0x00c0, 0x4c57, 0x6853, 0x0002, 0x0078, 0x4c6d, 0x6853,
+ 0x0008, 0x0078, 0x4c6d, 0x6853, 0x000e, 0x0078, 0x4c6d, 0x6853,
+ 0x0017, 0x0078, 0x4c6d, 0x6853, 0x0035, 0x0078, 0x4c6d, 0x6853,
+ 0x0028, 0x0078, 0x4c6d, 0x6853, 0x0029, 0x127f, 0x0e7f, 0x0078,
+ 0x4c8c, 0x6853, 0x002a, 0x0078, 0x4c6d, 0x2009, 0x003e, 0x0078,
+ 0x4c87, 0x2009, 0x0004, 0x0078, 0x4c87, 0x2009, 0x0006, 0x0078,
+ 0x4c87, 0x2009, 0x0016, 0x0078, 0x4c87, 0x2009, 0x0001, 0x6854,
+ 0xa084, 0xff00, 0xa105, 0x6856, 0x2091, 0x8000, 0x1078, 0x4376,
+ 0x2091, 0x8001, 0x007c, 0x1078, 0x1344, 0x007c, 0x702c, 0x7130,
+ 0x8108, 0xa102, 0x0048, 0x4ca3, 0xa00e, 0x7034, 0x7072, 0x7038,
+ 0x7076, 0x0078, 0x4caf, 0x7070, 0xa080, 0x0040, 0x7072, 0x00c8,
+ 0x4caf, 0x7074, 0xa081, 0x0000, 0x7076, 0xa085, 0x0001, 0x7932,
+ 0x7132, 0x007c, 0x0d7e, 0x1078, 0x518f, 0x0d7f, 0x007c, 0x0d7e,
0x2011, 0x0004, 0x2204, 0xa085, 0x8002, 0x2012, 0x0d7f, 0x007c,
0x20e1, 0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000,
- 0x0040, 0x42a6, 0xa086, 0x1000, 0x00c0, 0x42c2, 0x20e1, 0x0004,
- 0x3d60, 0xd1bc, 0x00c0, 0x42ad, 0x3e60, 0xac84, 0x0007, 0x00c0,
- 0x42c2, 0xac82, 0x7e00, 0x0048, 0x42c2, 0x6854, 0xac02, 0x00c8,
- 0x42c2, 0x2009, 0x0047, 0x1078, 0x5d41, 0x7a1c, 0xd284, 0x00c0,
- 0x4298, 0x007c, 0xa016, 0x1078, 0x156a, 0x0078, 0x42bd, 0x157e,
+ 0x0040, 0x4cce, 0xa086, 0x1000, 0x00c0, 0x4cea, 0x20e1, 0x0004,
+ 0x3d60, 0xd1bc, 0x00c0, 0x4cd5, 0x3e60, 0xac84, 0x0003, 0x00c0,
+ 0x4cea, 0xac82, 0x8f00, 0x0048, 0x4cea, 0x6854, 0xac02, 0x00c8,
+ 0x4cea, 0x2009, 0x0047, 0x1078, 0x6939, 0x7a1c, 0xd284, 0x00c0,
+ 0x4cc0, 0x007c, 0xa016, 0x1078, 0x1594, 0x0078, 0x4ce5, 0x157e,
0x137e, 0x147e, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0070,
- 0x00c0, 0x42f0, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0, 0x42f0,
- 0x1078, 0x42fd, 0x0040, 0x42f0, 0x20e1, 0x3000, 0x7828, 0x7828,
- 0x1078, 0x431b, 0x147f, 0x137f, 0x157f, 0x2009, 0x793e, 0x2104,
- 0xa005, 0x00c0, 0x42ec, 0x007c, 0x1078, 0x4d96, 0x0078, 0x42eb,
- 0x1078, 0x7674, 0x1078, 0x42fd, 0x20e1, 0x3000, 0x7828, 0x7828,
- 0x147f, 0x137f, 0x157f, 0x0078, 0x42eb, 0xa484, 0x01ff, 0x687a,
- 0xa005, 0x0040, 0x430f, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac,
- 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x007c, 0x20a9,
- 0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085,
- 0x0001, 0x0078, 0x430e, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000,
- 0x8007, 0xa196, 0x0000, 0x00c0, 0x4328, 0x0078, 0x449c, 0x007c,
- 0xa196, 0x2000, 0x00c0, 0x4339, 0x6900, 0xa18e, 0x0001, 0x00c0,
- 0x4335, 0x1078, 0x2ec1, 0x0078, 0x4327, 0x1078, 0x4341, 0x0078,
- 0x4327, 0xa196, 0x8000, 0x00c0, 0x4327, 0x1078, 0x4522, 0x0078,
- 0x4327, 0x0c7e, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa196, 0x0001,
- 0x0040, 0x434e, 0xa196, 0x0023, 0x00c0, 0x4443, 0xa08e, 0x0023,
- 0x00c0, 0x437f, 0x1078, 0x4599, 0x0040, 0x4443, 0x7124, 0x610a,
- 0x7030, 0xa08e, 0x0200, 0x00c0, 0x4367, 0x7034, 0xa005, 0x00c0,
- 0x4443, 0x2009, 0x0015, 0x1078, 0x5d41, 0x0078, 0x4443, 0xa08e,
- 0x0210, 0x00c0, 0x4371, 0x2009, 0x0015, 0x1078, 0x5d41, 0x0078,
- 0x4443, 0xa08e, 0x0100, 0x00c0, 0x4443, 0x7034, 0xa005, 0x00c0,
- 0x4443, 0x2009, 0x0016, 0x1078, 0x5d41, 0x0078, 0x4443, 0xa08e,
- 0x0022, 0x00c0, 0x4443, 0x7030, 0xa08e, 0x0300, 0x00c0, 0x4390,
- 0x7034, 0xa005, 0x00c0, 0x4443, 0x2009, 0x0017, 0x0078, 0x440f,
- 0xa08e, 0x0500, 0x00c0, 0x439c, 0x7034, 0xa005, 0x00c0, 0x4443,
- 0x2009, 0x0018, 0x0078, 0x440f, 0xa08e, 0x2010, 0x00c0, 0x43a4,
- 0x2009, 0x0019, 0x0078, 0x440f, 0xa08e, 0x2110, 0x00c0, 0x43ac,
- 0x2009, 0x001a, 0x0078, 0x440f, 0xa08e, 0x5200, 0x00c0, 0x43b8,
- 0x7034, 0xa005, 0x00c0, 0x4443, 0x2009, 0x001b, 0x0078, 0x440f,
- 0xa08e, 0x5000, 0x00c0, 0x43c4, 0x7034, 0xa005, 0x00c0, 0x4443,
- 0x2009, 0x001c, 0x0078, 0x440f, 0xa08e, 0x1200, 0x00c0, 0x43d0,
- 0x7034, 0xa005, 0x00c0, 0x4443, 0x2009, 0x0024, 0x0078, 0x440f,
- 0xa08c, 0xff00, 0xa18e, 0x2400, 0x00c0, 0x43da, 0x2009, 0x002d,
- 0x0078, 0x440f, 0xa08c, 0xff00, 0xa18e, 0x5300, 0x00c0, 0x43e4,
- 0x2009, 0x002a, 0x0078, 0x440f, 0xa08e, 0x0f00, 0x00c0, 0x43ec,
- 0x2009, 0x0020, 0x0078, 0x440f, 0xa08e, 0x5300, 0x00c0, 0x43f2,
- 0x0078, 0x440d, 0xa08e, 0x6104, 0x00c0, 0x440d, 0x2011, 0x7c8d,
- 0x8208, 0x2204, 0xa082, 0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011,
- 0x8015, 0x211c, 0x8108, 0x2124, 0x1078, 0x2d59, 0x8108, 0x00f0,
- 0x43ff, 0x2009, 0x0023, 0x0078, 0x440f, 0x2009, 0x001d, 0x017e,
- 0x2011, 0x7c83, 0x2204, 0x8211, 0x220c, 0x1078, 0x207f, 0x00c0,
- 0x4445, 0x1078, 0x3811, 0x00c0, 0x4445, 0x6612, 0x6516, 0x86ff,
- 0x0040, 0x4435, 0x017f, 0x017e, 0xa186, 0x0017, 0x00c0, 0x4435,
- 0x6864, 0xa606, 0x00c0, 0x4435, 0x6868, 0xa506, 0xa084, 0xff00,
- 0x00c0, 0x4435, 0x6000, 0xc0f5, 0x6002, 0x0c7e, 0x1078, 0x5cb4,
- 0x0040, 0x4448, 0x017f, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a,
- 0x017f, 0x1078, 0x5d41, 0x0c7f, 0x007c, 0x017f, 0x0078, 0x4443,
- 0x0c7f, 0x0078, 0x4445, 0x0e7e, 0x0d7e, 0x2028, 0x2130, 0xa696,
- 0x00ff, 0x00c0, 0x446b, 0xa596, 0xfffd, 0x00c0, 0x445b, 0x2009,
- 0x007f, 0x0078, 0x4498, 0xa596, 0xfffe, 0x00c0, 0x4463, 0x2009,
- 0x007e, 0x0078, 0x4498, 0xa596, 0xfffc, 0x00c0, 0x446b, 0x2009,
- 0x0080, 0x0078, 0x4498, 0x2011, 0x0000, 0x2021, 0x007e, 0x20a9,
- 0x0082, 0x2071, 0x789e, 0x2e1c, 0x83ff, 0x00c0, 0x447d, 0x82ff,
- 0x00c0, 0x448c, 0x2410, 0x0078, 0x448c, 0x2368, 0x6b10, 0x007e,
- 0x2100, 0xa31e, 0x007f, 0x00c0, 0x448c, 0x6b14, 0xa31e, 0x00c0,
- 0x448c, 0x2408, 0x0078, 0x4498, 0x8420, 0x8e70, 0x00f0, 0x4473,
- 0x82ff, 0x00c0, 0x4497, 0xa085, 0x0001, 0x0078, 0x4499, 0x2208,
- 0xa006, 0x0d7f, 0x0e7f, 0x007c, 0xa084, 0x0007, 0x0079, 0x44a1,
- 0x007c, 0x44a9, 0x44a9, 0x44a9, 0x44a9, 0x44a9, 0x44aa, 0x44c3,
- 0x450b, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x44c2, 0x7120, 0x2160,
- 0xac8c, 0x0007, 0x00c0, 0x44c2, 0xac8a, 0x7e00, 0x0048, 0x44c2,
- 0x6854, 0xac02, 0x00c8, 0x44c2, 0x7124, 0x610a, 0x2009, 0x0046,
- 0x1078, 0x5d41, 0x007c, 0x0c7e, 0x7110, 0xd1bc, 0x00c0, 0x4509,
- 0x2011, 0x7c83, 0x2204, 0x8211, 0x220c, 0x1078, 0x207f, 0x00c0,
- 0x4509, 0x1078, 0x384c, 0x00c0, 0x4509, 0x6204, 0xa294, 0xff00,
- 0x8217, 0xa286, 0x0006, 0x00c0, 0x44ee, 0x0c7e, 0x1078, 0x5cb4,
- 0x017f, 0x0040, 0x4509, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a,
- 0x2009, 0x0044, 0x1078, 0x5d41, 0x0078, 0x4509, 0x0c7e, 0x1078,
- 0x5cb4, 0x017f, 0x0040, 0x4509, 0x611a, 0x601f, 0x0004, 0x7120,
- 0x610a, 0xa286, 0x0004, 0x00c0, 0x4501, 0x6007, 0x0005, 0x0078,
- 0x4503, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x498e, 0x1078,
- 0x4d96, 0x0c7f, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x4521, 0x7020,
- 0x2060, 0xac84, 0x0007, 0x00c0, 0x4521, 0xac82, 0x7e00, 0x0048,
- 0x4521, 0x6854, 0xac02, 0x00c8, 0x4521, 0x2009, 0x0045, 0x1078,
- 0x5d41, 0x007c, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000,
- 0x00c0, 0x4532, 0xa084, 0x000f, 0xa08a, 0x0006, 0x10c8, 0x12cd,
- 0x1079, 0x4533, 0x007c, 0x4539, 0x453a, 0x4539, 0x4539, 0x457b,
- 0x458a, 0x007c, 0x7110, 0xd1bc, 0x00c0, 0x457a, 0x700c, 0x7108,
- 0x1078, 0x207f, 0x00c0, 0x457a, 0x1078, 0x3811, 0x00c0, 0x457a,
- 0x6612, 0x6516, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006,
- 0x00c0, 0x4563, 0x0c7e, 0x1078, 0x5cb4, 0x017f, 0x0040, 0x457a,
- 0x611a, 0x601f, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x1078,
- 0x5d41, 0x0078, 0x457a, 0x0c7e, 0x1078, 0x5cb4, 0x017f, 0x0040,
- 0x457a, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0xa286, 0x0004,
- 0x00c0, 0x4576, 0x2009, 0x0005, 0x0078, 0x4578, 0x2009, 0x0001,
- 0x1078, 0x5d41, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x4589, 0x1078,
- 0x4599, 0x0040, 0x4589, 0x7124, 0x610a, 0x2009, 0x0089, 0x1078,
- 0x5d41, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x4598, 0x1078, 0x4599,
- 0x0040, 0x4598, 0x7124, 0x610a, 0x2009, 0x008a, 0x1078, 0x5d41,
- 0x007c, 0x7020, 0x2060, 0xac84, 0x0007, 0x00c0, 0x45ac, 0xac82,
- 0x7e00, 0x0048, 0x45ac, 0x2001, 0x7715, 0x2004, 0xac02, 0x00c8,
- 0x45ac, 0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x45ab, 0x2071,
- 0x7949, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, 0x7012,
- 0x7017, 0x7e00, 0x7007, 0x0000, 0x7026, 0x702b, 0x56a9, 0x7032,
- 0x7037, 0x56ea, 0x703b, 0x0002, 0x703f, 0x0000, 0x007c, 0x2071,
- 0x7949, 0x00e0, 0x4676, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e,
- 0x00c0, 0x463f, 0x700f, 0x0361, 0x7007, 0x0001, 0x127e, 0x2091,
- 0x8000, 0x7138, 0x8109, 0x713a, 0x00c0, 0x463d, 0x703b, 0x0002,
- 0x2009, 0x0100, 0x2104, 0xa082, 0x0003, 0x00c8, 0x463d, 0x703c,
- 0xa086, 0x0001, 0x00c0, 0x461a, 0x0d7e, 0x2069, 0x0140, 0x6804,
- 0xa084, 0x4000, 0x0040, 0x45f8, 0x6803, 0x1000, 0x0078, 0x45ff,
- 0x6804, 0xa084, 0x1000, 0x0040, 0x45ff, 0x6803, 0x0100, 0x6803,
- 0x0000, 0x703f, 0x0000, 0x2069, 0x7936, 0x6804, 0xa082, 0x0006,
- 0x00c0, 0x460c, 0x6807, 0x0000, 0x6830, 0xa082, 0x0003, 0x00c0,
- 0x4613, 0x6833, 0x0000, 0x1078, 0x4d96, 0x1078, 0x4e56, 0x0d7f,
- 0x0078, 0x463d, 0x0d7e, 0x2069, 0x7700, 0x6944, 0x6860, 0xa102,
- 0x00c8, 0x463c, 0x2069, 0x7936, 0x6804, 0xa086, 0x0000, 0x00c0,
- 0x463c, 0x6830, 0xa086, 0x0000, 0x00c0, 0x463c, 0x703f, 0x0001,
- 0x6807, 0x0006, 0x6833, 0x0003, 0x2069, 0x0100, 0x6830, 0x689e,
- 0x2069, 0x0140, 0x6803, 0x0600, 0x0d7f, 0x0078, 0x4642, 0x127e,
- 0x2091, 0x8000, 0x7024, 0xa00d, 0x0040, 0x4653, 0x7020, 0x8001,
- 0x7022, 0x00c0, 0x4653, 0x7023, 0x0009, 0x8109, 0x7126, 0x00c0,
- 0x4653, 0x7028, 0x107a, 0x7030, 0xa00d, 0x0040, 0x4664, 0x702c,
- 0x8001, 0x702e, 0x00c0, 0x4664, 0x702f, 0x0009, 0x8109, 0x7132,
- 0x00c0, 0x4664, 0x7034, 0x107a, 0x7018, 0xa00d, 0x0040, 0x4675,
- 0x7008, 0x8001, 0x700a, 0x00c0, 0x4675, 0x700b, 0x0009, 0x8109,
- 0x711a, 0x00c0, 0x4675, 0x701c, 0x107a, 0x127f, 0x7004, 0x0079,
- 0x4679, 0x46a0, 0x46a1, 0x46bd, 0x0e7e, 0x2071, 0x7949, 0x7018,
- 0xa005, 0x00c0, 0x4687, 0x711a, 0x721e, 0x700b, 0x0009, 0x0e7f,
- 0x007c, 0x0e7e, 0x007e, 0x2071, 0x7949, 0x701c, 0xa206, 0x00c0,
- 0x4693, 0x701a, 0x701e, 0x007f, 0x0e7f, 0x007c, 0x0e7e, 0x2071,
- 0x7949, 0x6088, 0xa102, 0x0048, 0x469e, 0x618a, 0x0e7f, 0x007c,
- 0x007c, 0x7110, 0x1078, 0x384c, 0x00c0, 0x46b3, 0x6088, 0x8001,
- 0x0048, 0x46b3, 0x608a, 0x00c0, 0x46b3, 0x127e, 0x2091, 0x8000,
- 0x1078, 0x4d96, 0x127f, 0x8108, 0xa182, 0x00ff, 0x0048, 0x46bb,
- 0xa00e, 0x7007, 0x0002, 0x7112, 0x007c, 0x7014, 0x2060, 0x127e,
- 0x2091, 0x8000, 0x6014, 0xa005, 0x0040, 0x46ec, 0x8001, 0x6016,
- 0x00c0, 0x46ec, 0x611c, 0xa186, 0x0003, 0x0040, 0x46d3, 0xa186,
- 0x0006, 0x00c0, 0x46ea, 0x6010, 0x2068, 0x6854, 0xa08a, 0x199a,
- 0x0048, 0x46ea, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a, 0x0048,
- 0x46e3, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116,
- 0x0078, 0x46ec, 0x1078, 0x68e3, 0x127f, 0xac88, 0x0008, 0x7116,
- 0x2001, 0x7716, 0x2004, 0xa102, 0x0048, 0x46fa, 0x7017, 0x7e00,
- 0x7007, 0x0000, 0x007c, 0x0e7e, 0x2071, 0x7949, 0x7027, 0x07d0,
- 0x7023, 0x0009, 0x703b, 0x0002, 0x0e7f, 0x007c, 0x2001, 0x7952,
- 0x2003, 0x0000, 0x007c, 0x0e7e, 0x2071, 0x7949, 0x7033, 0x07d0,
- 0x702f, 0x0009, 0x0e7f, 0x007c, 0x2011, 0x7955, 0x2013, 0x0000,
- 0x007c, 0x0e7e, 0x2071, 0x7949, 0x711a, 0x721e, 0x700b, 0x0009,
- 0x0e7f, 0x007c, 0x0c7e, 0x2061, 0x79da, 0x0c7f, 0x007c, 0xa184,
- 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x79da, 0x2060, 0x007c,
- 0x6854, 0xa08a, 0x199a, 0x0048, 0x4737, 0x2001, 0x1999, 0xa005,
- 0x00c0, 0x4747, 0x6944, 0x0c7e, 0x1078, 0x4727, 0x6014, 0x0c7f,
- 0xa005, 0x00c0, 0x474c, 0x2001, 0x001e, 0x0078, 0x474c, 0xa08e,
- 0xffff, 0x00c0, 0x474c, 0xa006, 0x8003, 0x800b, 0x810b, 0xa108,
- 0x6116, 0x684c, 0xa08c, 0x00c0, 0xa18e, 0x00c0, 0x0040, 0x4787,
- 0xd0b4, 0x00c0, 0x4763, 0xd0bc, 0x00c0, 0x4775, 0x2009, 0x0006,
- 0x1078, 0x47aa, 0x007c, 0xd0fc, 0x0040, 0x4770, 0xa084, 0x0003,
- 0xa08e, 0x0003, 0x0040, 0x47a3, 0xa08e, 0x0000, 0x00c0, 0x47a3,
- 0x2009, 0x0043, 0x1078, 0x5d41, 0x007c, 0xd0fc, 0x0040, 0x4782,
- 0xa084, 0x0003, 0xa08e, 0x0003, 0x0040, 0x47a3, 0xa08e, 0x0000,
- 0x00c0, 0x47a3, 0x2009, 0x0042, 0x1078, 0x5d41, 0x007c, 0xd0fc,
- 0x0040, 0x4799, 0xa084, 0x0003, 0xa08e, 0x0003, 0x0040, 0x47a3,
- 0xa08e, 0x0002, 0x0040, 0x479d, 0x2009, 0x0041, 0x1078, 0x5d41,
- 0x007c, 0x1078, 0x47a8, 0x0078, 0x4798, 0x2009, 0x0043, 0x1078,
- 0x5d41, 0x0078, 0x4798, 0x2009, 0x0004, 0x1078, 0x47aa, 0x007c,
- 0x2009, 0x0001, 0x6010, 0xa0ec, 0xf000, 0x0040, 0x47cf, 0x2068,
- 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x00c0, 0x47c9, 0x694c,
- 0xa18c, 0x8100, 0xa18e, 0x8100, 0x00c0, 0x47c9, 0x0c7e, 0x2009,
- 0x0000, 0x1078, 0x4727, 0x6204, 0x8210, 0x0048, 0x47c8, 0x6206,
- 0x0c7f, 0x1078, 0x3b92, 0x6010, 0xa06d, 0x10c0, 0x4730, 0x007c,
- 0x157e, 0x0c7e, 0x20a9, 0x0010, 0x2061, 0x79da, 0x6000, 0x81ff,
- 0x0040, 0x47dd, 0xa205, 0x0078, 0x47de, 0xa204, 0x6002, 0xace0,
- 0x0008, 0x00f0, 0x47d6, 0x0c7f, 0x157f, 0x007c, 0x6808, 0xa005,
- 0x0040, 0x47ee, 0x8001, 0x680a, 0xa085, 0x0001, 0x007c, 0x127e,
- 0x2091, 0x2200, 0x2079, 0x7936, 0x127f, 0x0d7e, 0x2069, 0x7936,
- 0x6803, 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, 0x206a,
- 0x0d7f, 0x007c, 0x0c7e, 0x6027, 0x0001, 0x7804, 0xa084, 0x0007,
- 0x0079, 0x480a, 0x4814, 0x4839, 0x4894, 0x481a, 0x4839, 0x4812,
- 0x4812, 0x4812, 0x1078, 0x12cd, 0x1078, 0x4706, 0x1078, 0x4d96,
- 0x0c7f, 0x007c, 0x62c0, 0x82ff, 0x00c0, 0x4820, 0x0c7f, 0x007c,
- 0x2011, 0x3558, 0x1078, 0x4689, 0x7828, 0xa092, 0x0002, 0x00c8,
- 0x482f, 0x8000, 0x782a, 0x1078, 0x3588, 0x0078, 0x481e, 0x1078,
- 0x3558, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0078,
- 0x481e, 0x1078, 0x4706, 0x3c00, 0x007e, 0x2011, 0x0209, 0x20e1,
- 0x4000, 0x2214, 0x007f, 0x20e0, 0x82ff, 0x0040, 0x4857, 0x62c0,
- 0x82ff, 0x00c0, 0x4857, 0x782b, 0x0000, 0x7824, 0xa065, 0x1040,
- 0x12cd, 0x2009, 0x0013, 0x1078, 0x5d41, 0x0c7f, 0x007c, 0x3900,
- 0xa082, 0x7a7a, 0x00c8, 0x485e, 0x1078, 0x5c44, 0x0c7e, 0x7824,
- 0xa065, 0x1040, 0x12cd, 0x7804, 0xa086, 0x0004, 0x0040, 0x48d9,
- 0x7828, 0xa092, 0x2710, 0x00c8, 0x4874, 0x8000, 0x782a, 0x0c7f,
- 0x1078, 0x568e, 0x0078, 0x4855, 0x6104, 0xa186, 0x0003, 0x00c0,
- 0x488b, 0x0e7e, 0x2071, 0x7700, 0x70c8, 0x0e7f, 0xd08c, 0x0040,
- 0x488b, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0x7700, 0x1078,
- 0x3591, 0x0e7f, 0x0c7f, 0x1078, 0x76c7, 0x2009, 0x0014, 0x1078,
- 0x5d41, 0x0c7f, 0x0078, 0x4855, 0x2001, 0x7952, 0x2003, 0x0000,
- 0x62c0, 0x82ff, 0x00c0, 0x48a8, 0x782b, 0x0000, 0x7824, 0xa065,
- 0x1040, 0x12cd, 0x2009, 0x0013, 0x1078, 0x5d8f, 0x0c7f, 0x007c,
- 0x0c7e, 0x0d7e, 0x3900, 0xa082, 0x7a7a, 0x00c8, 0x48b1, 0x1078,
- 0x5c44, 0x7824, 0xa005, 0x1040, 0x12cd, 0x781c, 0xa06d, 0x1040,
- 0x12cd, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x1078, 0x5d1a,
- 0x693c, 0x81ff, 0x1040, 0x12cd, 0x8109, 0x693e, 0x6854, 0xa015,
- 0x0040, 0x48cd, 0x7a1e, 0x0078, 0x48cf, 0x7918, 0x791e, 0x7807,
- 0x0000, 0x7827, 0x0000, 0x0d7f, 0x0c7f, 0x1078, 0x4d96, 0x0078,
- 0x48a6, 0x6104, 0xa186, 0x0002, 0x0040, 0x48e4, 0xa186, 0x0004,
- 0x0040, 0x48e4, 0x0078, 0x4868, 0x7808, 0xac06, 0x0040, 0x4868,
- 0x1078, 0x4c9d, 0x1078, 0x498e, 0x0c7f, 0x1078, 0x4d96, 0x0078,
- 0x4855, 0x0c7e, 0x6027, 0x0002, 0x2011, 0x7955, 0x2013, 0x0000,
- 0x62c8, 0x82ff, 0x00c0, 0x490b, 0x62c4, 0x82ff, 0x00c0, 0x490b,
- 0x793c, 0xa1e5, 0x0000, 0x0040, 0x4909, 0x2009, 0x0049, 0x1078,
- 0x5d41, 0x0c7f, 0x007c, 0x3908, 0xa192, 0x7a7a, 0x00c8, 0x4912,
- 0x1078, 0x5c44, 0x6017, 0x0010, 0x793c, 0x81ff, 0x0040, 0x4909,
- 0x7944, 0xa192, 0x7530, 0x00c8, 0x4931, 0x8108, 0x7946, 0x1078,
- 0x470b, 0x793c, 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0,
- 0x492d, 0x6017, 0x0012, 0x0078, 0x4909, 0x6017, 0x0016, 0x0078,
- 0x4909, 0x037e, 0x2019, 0x0001, 0x1078, 0x5880, 0x037f, 0x1078,
- 0x76c7, 0x793c, 0x2160, 0x2009, 0x004a, 0x1078, 0x5d41, 0x0078,
- 0x4909, 0x007e, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f,
- 0x0000, 0x2c08, 0x2061, 0x7936, 0x6020, 0x8000, 0x6022, 0x6010,
- 0xa005, 0x0040, 0x495c, 0xa080, 0x0003, 0x2102, 0x6112, 0x127f,
- 0x0c7f, 0x017f, 0x007f, 0x007c, 0x6116, 0x6112, 0x0078, 0x4957,
- 0x0d7e, 0x2069, 0x7936, 0x6000, 0xd0d4, 0x0040, 0x4975, 0x6820,
- 0x8000, 0x6822, 0xa086, 0x0001, 0x00c0, 0x4970, 0x2c00, 0x681e,
- 0x6804, 0xa084, 0x0007, 0x0079, 0x4d9e, 0xc0d5, 0x6002, 0x6818,
- 0xa005, 0x0040, 0x4987, 0x6056, 0x605b, 0x0000, 0x007e, 0x2c00,
- 0x681a, 0x0d7f, 0x685a, 0x2069, 0x7936, 0x0078, 0x4967, 0x6056,
- 0x605a, 0x2c00, 0x681a, 0x681e, 0x0078, 0x4967, 0x007e, 0x017e,
+ 0x00c0, 0x4d31, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0, 0x4d20,
+ 0xa584, 0x0007, 0xd094, 0x00c0, 0x4d31, 0xd09c, 0x00c0, 0x4d31,
+ 0x1078, 0x4d4a, 0x0040, 0x4d31, 0x20e1, 0x3000, 0x7828, 0x7828,
+ 0x1078, 0x4d68, 0x147f, 0x137f, 0x157f, 0x2009, 0x8aaa, 0x2104,
+ 0xa005, 0x00c0, 0x4d1c, 0x007c, 0x1078, 0x5888, 0x0078, 0x4d1b,
+ 0xa484, 0x7000, 0x00c0, 0x4d31, 0x1078, 0x4d4a, 0x0040, 0x4d41,
+ 0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x0040, 0x4d0c, 0x0078,
+ 0x4d41, 0x1078, 0x872e, 0xd5a4, 0x0040, 0x4d3f, 0x1078, 0x19e5,
+ 0x20e1, 0x9010, 0x2001, 0x0138, 0x2202, 0x0078, 0x4d45, 0x1078,
+ 0x4d4a, 0x20e1, 0x3000, 0x7828, 0x7828, 0x147f, 0x137f, 0x157f,
+ 0x0078, 0x4d1b, 0xa484, 0x01ff, 0x687e, 0xa005, 0x0040, 0x4d5c,
+ 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac, 0x20e1, 0x1000, 0x2ea0,
+ 0x2099, 0x020a, 0x53a5, 0x007c, 0x20a9, 0x000c, 0x20e1, 0x1000,
+ 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085, 0x0001, 0x0078, 0x4d5b,
+ 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, 0x8007, 0xa196, 0x0000,
+ 0x00c0, 0x4d75, 0x0078, 0x4eef, 0x007c, 0xa196, 0x2000, 0x00c0,
+ 0x4d86, 0x6900, 0xa18e, 0x0001, 0x00c0, 0x4d82, 0x1078, 0x3541,
+ 0x0078, 0x4d74, 0x1078, 0x4d8e, 0x0078, 0x4d74, 0xa196, 0x8000,
+ 0x00c0, 0x4d74, 0x1078, 0x4f7b, 0x0078, 0x4d74, 0x0c7e, 0x7110,
+ 0xa18c, 0xff00, 0x810f, 0xa196, 0x0001, 0x0040, 0x4d9b, 0xa196,
+ 0x0023, 0x00c0, 0x4e90, 0xa08e, 0x0023, 0x00c0, 0x4dcc, 0x1078,
+ 0x4fee, 0x0040, 0x4e90, 0x7124, 0x610a, 0x7030, 0xa08e, 0x0200,
+ 0x00c0, 0x4db4, 0x7034, 0xa005, 0x00c0, 0x4e90, 0x2009, 0x0015,
+ 0x1078, 0x6939, 0x0078, 0x4e90, 0xa08e, 0x0210, 0x00c0, 0x4dbe,
+ 0x2009, 0x0015, 0x1078, 0x6939, 0x0078, 0x4e90, 0xa08e, 0x0100,
+ 0x00c0, 0x4e90, 0x7034, 0xa005, 0x00c0, 0x4e90, 0x2009, 0x0016,
+ 0x1078, 0x6939, 0x0078, 0x4e90, 0xa08e, 0x0022, 0x00c0, 0x4e90,
+ 0x7030, 0xa08e, 0x0300, 0x00c0, 0x4ddd, 0x7034, 0xa005, 0x00c0,
+ 0x4e90, 0x2009, 0x0017, 0x0078, 0x4e5c, 0xa08e, 0x0500, 0x00c0,
+ 0x4de9, 0x7034, 0xa005, 0x00c0, 0x4e90, 0x2009, 0x0018, 0x0078,
+ 0x4e5c, 0xa08e, 0x2010, 0x00c0, 0x4df1, 0x2009, 0x0019, 0x0078,
+ 0x4e5c, 0xa08e, 0x2110, 0x00c0, 0x4df9, 0x2009, 0x001a, 0x0078,
+ 0x4e5c, 0xa08e, 0x5200, 0x00c0, 0x4e05, 0x7034, 0xa005, 0x00c0,
+ 0x4e90, 0x2009, 0x001b, 0x0078, 0x4e5c, 0xa08e, 0x5000, 0x00c0,
+ 0x4e11, 0x7034, 0xa005, 0x00c0, 0x4e90, 0x2009, 0x001c, 0x0078,
+ 0x4e5c, 0xa08e, 0x1200, 0x00c0, 0x4e1d, 0x7034, 0xa005, 0x00c0,
+ 0x4e90, 0x2009, 0x0024, 0x0078, 0x4e5c, 0xa08c, 0xff00, 0xa18e,
+ 0x2400, 0x00c0, 0x4e27, 0x2009, 0x002d, 0x0078, 0x4e5c, 0xa08c,
+ 0xff00, 0xa18e, 0x5300, 0x00c0, 0x4e31, 0x2009, 0x002a, 0x0078,
+ 0x4e5c, 0xa08e, 0x0f00, 0x00c0, 0x4e39, 0x2009, 0x0020, 0x0078,
+ 0x4e5c, 0xa08e, 0x5300, 0x00c0, 0x4e3f, 0x0078, 0x4e5a, 0xa08e,
+ 0x6104, 0x00c0, 0x4e5a, 0x2011, 0x8d8d, 0x8208, 0x2204, 0xa082,
+ 0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011, 0x8015, 0x211c, 0x8108,
+ 0x2124, 0x1078, 0x317a, 0x8108, 0x00f0, 0x4e4c, 0x2009, 0x0023,
+ 0x0078, 0x4e5c, 0x2009, 0x001d, 0x017e, 0x2011, 0x8d83, 0x2204,
+ 0x8211, 0x220c, 0x1078, 0x2245, 0x00c0, 0x4e92, 0x1078, 0x3f53,
+ 0x00c0, 0x4e92, 0x6612, 0x6516, 0x86ff, 0x0040, 0x4e82, 0x017f,
+ 0x017e, 0xa186, 0x0017, 0x00c0, 0x4e82, 0x6868, 0xa606, 0x00c0,
+ 0x4e82, 0x686c, 0xa506, 0xa084, 0xff00, 0x00c0, 0x4e82, 0x6000,
+ 0xc0f5, 0x6002, 0x0c7e, 0x1078, 0x68a8, 0x0040, 0x4e95, 0x017f,
+ 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x017f, 0x1078, 0x6939,
+ 0x0c7f, 0x007c, 0x017f, 0x0078, 0x4e90, 0x0c7f, 0x0078, 0x4e92,
+ 0x0e7e, 0x0d7e, 0x2028, 0x2130, 0xa696, 0x00ff, 0x00c0, 0x4eb8,
+ 0xa596, 0xfffd, 0x00c0, 0x4ea8, 0x2009, 0x007f, 0x0078, 0x4eeb,
+ 0xa596, 0xfffe, 0x00c0, 0x4eb0, 0x2009, 0x007e, 0x0078, 0x4eeb,
+ 0xa596, 0xfffc, 0x00c0, 0x4eb8, 0x2009, 0x0080, 0x0078, 0x4eeb,
+ 0x2011, 0x0000, 0x2021, 0x0081, 0x20a9, 0x007e, 0x2071, 0x89b5,
+ 0x2e1c, 0x83ff, 0x00c0, 0x4eca, 0x82ff, 0x00c0, 0x4edf, 0x2410,
+ 0x0078, 0x4edf, 0x2368, 0x6f10, 0x007e, 0x2100, 0xa706, 0x007f,
+ 0x6b14, 0x00c0, 0x4ed9, 0xa346, 0x00c0, 0x4ed9, 0x2408, 0x0078,
+ 0x4eeb, 0x87ff, 0x00c0, 0x4edf, 0x83ff, 0x0040, 0x4ec4, 0x8420,
+ 0x8e70, 0x00f0, 0x4ec0, 0x82ff, 0x00c0, 0x4eea, 0xa085, 0x0001,
+ 0x0078, 0x4eec, 0x2208, 0xa006, 0x0d7f, 0x0e7f, 0x007c, 0xa084,
+ 0x0007, 0x0079, 0x4ef4, 0x007c, 0x4efc, 0x4efc, 0x4efc, 0x4efc,
+ 0x4efc, 0x4efd, 0x4f16, 0x4f64, 0x007c, 0x7110, 0xd1bc, 0x0040,
+ 0x4f15, 0x7120, 0x2160, 0xac8c, 0x0003, 0x00c0, 0x4f15, 0xac8a,
+ 0x8f00, 0x0048, 0x4f15, 0x6854, 0xac02, 0x00c8, 0x4f15, 0x7124,
+ 0x610a, 0x2009, 0x0046, 0x1078, 0x6939, 0x007c, 0x0c7e, 0x7110,
+ 0xd1bc, 0x00c0, 0x4f62, 0x2011, 0x8d83, 0x2204, 0x8211, 0x220c,
+ 0x1078, 0x2245, 0x00c0, 0x4f62, 0x1078, 0x3f8e, 0x00c0, 0x4f62,
+ 0x6000, 0xd0ec, 0x00c0, 0x4f62, 0x6204, 0xa294, 0xff00, 0x8217,
+ 0xa286, 0x0006, 0x00c0, 0x4f47, 0x0c7e, 0x1078, 0x68a8, 0x017f,
+ 0x0040, 0x4f62, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130,
+ 0x6122, 0x2009, 0x0044, 0x1078, 0x6939, 0x0078, 0x4f62, 0x0c7e,
+ 0x1078, 0x68a8, 0x017f, 0x0040, 0x4f62, 0x611a, 0x601f, 0x0004,
+ 0x7120, 0x610a, 0xa286, 0x0004, 0x00c0, 0x4f5a, 0x6007, 0x0005,
+ 0x0078, 0x4f5c, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x53e6,
+ 0x1078, 0x5888, 0x0c7f, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x4f7a,
+ 0x7020, 0x2060, 0xac84, 0x0003, 0x00c0, 0x4f7a, 0xac82, 0x8f00,
+ 0x0048, 0x4f7a, 0x6854, 0xac02, 0x00c8, 0x4f7a, 0x2009, 0x0045,
+ 0x1078, 0x6939, 0x007c, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e,
+ 0x0000, 0x00c0, 0x4f8b, 0xa084, 0x000f, 0xa08a, 0x0006, 0x10c8,
+ 0x12d2, 0x1079, 0x4f8c, 0x007c, 0x4f92, 0x4f93, 0x4f92, 0x4f92,
+ 0x4fd0, 0x4fdf, 0x007c, 0x7110, 0xd1bc, 0x00c0, 0x4fcf, 0x700c,
+ 0x7108, 0x1078, 0x2245, 0x00c0, 0x4fcf, 0x1078, 0x3f53, 0x00c0,
+ 0x4fcf, 0x6612, 0x6516, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286,
+ 0x0004, 0x0040, 0x4faf, 0xa286, 0x0006, 0x00c0, 0x4fc0, 0x0c7e,
+ 0x1078, 0x68a8, 0x017f, 0x0040, 0x4fcf, 0x611a, 0x601f, 0x0005,
+ 0x7120, 0x610a, 0x2009, 0x0088, 0x1078, 0x6939, 0x0078, 0x4fcf,
+ 0x0c7e, 0x1078, 0x68a8, 0x017f, 0x0040, 0x4fcf, 0x611a, 0x601f,
+ 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x1078, 0x6939, 0x007c,
+ 0x7110, 0xd1bc, 0x0040, 0x4fde, 0x1078, 0x4fee, 0x0040, 0x4fde,
+ 0x7124, 0x610a, 0x2009, 0x0089, 0x1078, 0x6939, 0x007c, 0x7110,
+ 0xd1bc, 0x0040, 0x4fed, 0x1078, 0x4fee, 0x0040, 0x4fed, 0x7124,
+ 0x610a, 0x2009, 0x008a, 0x1078, 0x6939, 0x007c, 0x7020, 0x2060,
+ 0xac84, 0x0003, 0x00c0, 0x5001, 0xac82, 0x8f00, 0x0048, 0x5001,
+ 0x2001, 0x8815, 0x2004, 0xac02, 0x00c8, 0x5001, 0xa085, 0x0001,
+ 0x007c, 0xa006, 0x0078, 0x5000, 0x2071, 0x8ab5, 0x7003, 0x0003,
+ 0x700f, 0x0361, 0xa006, 0x701a, 0x7012, 0x7017, 0x8f00, 0x7007,
+ 0x0000, 0x7026, 0x702b, 0x623f, 0x7032, 0x7037, 0x6280, 0x703b,
+ 0x0002, 0x703f, 0x0000, 0x7043, 0xffff, 0x7047, 0xffff, 0x007c,
+ 0x2071, 0x8ab5, 0x00e0, 0x50df, 0x2091, 0x6000, 0x700c, 0x8001,
+ 0x700e, 0x00c0, 0x5098, 0x700f, 0x0361, 0x7007, 0x0001, 0x127e,
+ 0x2091, 0x8000, 0x7138, 0x8109, 0x713a, 0x00c0, 0x5096, 0x703b,
+ 0x0002, 0x2009, 0x0100, 0x2104, 0xa082, 0x0003, 0x00c8, 0x5096,
+ 0x703c, 0xa086, 0x0001, 0x00c0, 0x5073, 0x0d7e, 0x2069, 0x0140,
+ 0x6804, 0xa084, 0x4000, 0x0040, 0x5051, 0x6803, 0x1000, 0x0078,
+ 0x5058, 0x6804, 0xa084, 0x1000, 0x0040, 0x5058, 0x6803, 0x0100,
+ 0x6803, 0x0000, 0x703f, 0x0000, 0x2069, 0x8aa2, 0x6804, 0xa082,
+ 0x0006, 0x00c0, 0x5065, 0x6807, 0x0000, 0x6830, 0xa082, 0x0003,
+ 0x00c0, 0x506c, 0x6833, 0x0000, 0x1078, 0x5888, 0x1078, 0x5948,
+ 0x0d7f, 0x0078, 0x5096, 0x0d7e, 0x2069, 0x8800, 0x6944, 0x6860,
+ 0xa102, 0x00c8, 0x5095, 0x2069, 0x8aa2, 0x6804, 0xa086, 0x0000,
+ 0x00c0, 0x5095, 0x6830, 0xa086, 0x0000, 0x00c0, 0x5095, 0x703f,
+ 0x0001, 0x6807, 0x0006, 0x6833, 0x0003, 0x2069, 0x0100, 0x6830,
+ 0x689e, 0x2069, 0x0140, 0x6803, 0x0600, 0x0d7f, 0x0078, 0x509b,
+ 0x127e, 0x2091, 0x8000, 0x7024, 0xa00d, 0x0040, 0x50ac, 0x7020,
+ 0x8001, 0x7022, 0x00c0, 0x50ac, 0x7023, 0x0009, 0x8109, 0x7126,
+ 0x00c0, 0x50ac, 0x7028, 0x107a, 0x7030, 0xa00d, 0x0040, 0x50bd,
+ 0x702c, 0x8001, 0x702e, 0x00c0, 0x50bd, 0x702f, 0x0009, 0x8109,
+ 0x7132, 0x00c0, 0x50bd, 0x7034, 0x107a, 0x7040, 0xa005, 0x0040,
+ 0x50c5, 0x0050, 0x50c5, 0x8001, 0x7042, 0x7044, 0xa005, 0x0040,
+ 0x50cd, 0x0050, 0x50cd, 0x8001, 0x7046, 0x7018, 0xa00d, 0x0040,
+ 0x50de, 0x7008, 0x8001, 0x700a, 0x00c0, 0x50de, 0x700b, 0x0009,
+ 0x8109, 0x711a, 0x00c0, 0x50de, 0x701c, 0x107a, 0x127f, 0x7004,
+ 0x0079, 0x50e2, 0x5109, 0x510a, 0x5126, 0x0e7e, 0x2071, 0x8ab5,
+ 0x7018, 0xa005, 0x00c0, 0x50f0, 0x711a, 0x721e, 0x700b, 0x0009,
+ 0x0e7f, 0x007c, 0x0e7e, 0x007e, 0x2071, 0x8ab5, 0x701c, 0xa206,
+ 0x00c0, 0x50fc, 0x701a, 0x701e, 0x007f, 0x0e7f, 0x007c, 0x0e7e,
+ 0x2071, 0x8ab5, 0x6088, 0xa102, 0x0048, 0x5107, 0x618a, 0x0e7f,
+ 0x007c, 0x007c, 0x7110, 0x1078, 0x3f8e, 0x00c0, 0x511c, 0x6088,
+ 0x8001, 0x0048, 0x511c, 0x608a, 0x00c0, 0x511c, 0x127e, 0x2091,
+ 0x8000, 0x1078, 0x5888, 0x127f, 0x8108, 0xa182, 0x00ff, 0x0048,
+ 0x5124, 0xa00e, 0x7007, 0x0002, 0x7112, 0x007c, 0x7014, 0x2060,
+ 0x127e, 0x2091, 0x8000, 0x6014, 0xa005, 0x0040, 0x5155, 0x8001,
+ 0x6016, 0x00c0, 0x5155, 0x611c, 0xa186, 0x0003, 0x0040, 0x513c,
+ 0xa186, 0x0006, 0x00c0, 0x5153, 0x6010, 0x2068, 0x6854, 0xa08a,
+ 0x199a, 0x0048, 0x5153, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a,
+ 0x0048, 0x514c, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108,
+ 0x6116, 0x0078, 0x5155, 0x1078, 0x7632, 0x127f, 0xac88, 0x000c,
+ 0x7116, 0x2001, 0x8816, 0x2004, 0xa102, 0x0048, 0x5163, 0x7017,
+ 0x8f00, 0x7007, 0x0000, 0x007c, 0x0e7e, 0x2071, 0x8ab5, 0x7027,
+ 0x07d0, 0x7023, 0x0009, 0x703b, 0x0002, 0x0e7f, 0x007c, 0x2001,
+ 0x8abe, 0x2003, 0x0000, 0x007c, 0x0e7e, 0x2071, 0x8ab5, 0x7132,
+ 0x702f, 0x0009, 0x0e7f, 0x007c, 0x2011, 0x8ac1, 0x2013, 0x0000,
+ 0x007c, 0x0e7e, 0x2071, 0x8ab5, 0x711a, 0x721e, 0x700b, 0x0009,
+ 0x0e7f, 0x007c, 0x0c7e, 0x2061, 0x8b24, 0x0c7f, 0x007c, 0xa184,
+ 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x8b24, 0x2060, 0x007c,
+ 0x6854, 0xa08a, 0x199a, 0x0048, 0x519f, 0x2001, 0x1999, 0xa005,
+ 0x00c0, 0x51ae, 0x0c7e, 0x2061, 0x8b24, 0x6014, 0x0c7f, 0xa005,
+ 0x00c0, 0x51b3, 0x2001, 0x001e, 0x0078, 0x51b3, 0xa08e, 0xffff,
+ 0x00c0, 0x51b3, 0xa006, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116,
+ 0x684c, 0xa08c, 0x00c0, 0xa18e, 0x00c0, 0x0040, 0x51fc, 0xd0b4,
+ 0x00c0, 0x51ca, 0xd0bc, 0x00c0, 0x51ec, 0x2009, 0x0006, 0x1078,
+ 0x521b, 0x007c, 0xd0fc, 0x0040, 0x51d5, 0xa084, 0x0003, 0x0040,
+ 0x51d5, 0xa086, 0x0003, 0x00c0, 0x5214, 0x2009, 0x8873, 0x2104,
+ 0xd084, 0x0040, 0x51e7, 0x6118, 0xa188, 0x0027, 0x2104, 0xd08c,
+ 0x00c0, 0x51e7, 0x2009, 0x0042, 0x1078, 0x6939, 0x007c, 0x2009,
+ 0x0043, 0x1078, 0x6939, 0x007c, 0xd0fc, 0x0040, 0x51f7, 0xa084,
+ 0x0003, 0x0040, 0x51f7, 0xa086, 0x0003, 0x00c0, 0x5214, 0x2009,
+ 0x0042, 0x1078, 0x6939, 0x007c, 0xd0fc, 0x0040, 0x520a, 0xa084,
+ 0x0003, 0xa08e, 0x0002, 0x0040, 0x520e, 0x2009, 0x0041, 0x1078,
+ 0x6939, 0x007c, 0x1078, 0x5219, 0x0078, 0x5209, 0x2009, 0x0043,
+ 0x1078, 0x6939, 0x0078, 0x5209, 0x2009, 0x0004, 0x1078, 0x521b,
+ 0x007c, 0x2009, 0x0001, 0x6010, 0xa0ec, 0xf000, 0x0040, 0x5242,
+ 0x2068, 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x00c0, 0x523c,
+ 0x694c, 0xa18c, 0x8100, 0xa18e, 0x8100, 0x00c0, 0x523c, 0x0c7e,
+ 0x2061, 0x8b24, 0x6200, 0xd28c, 0x00c0, 0x523b, 0x6204, 0x8210,
+ 0x0048, 0x523b, 0x6206, 0x0c7f, 0x1078, 0x4376, 0x6010, 0xa06d,
+ 0x10c0, 0x5198, 0x007c, 0x157e, 0x0c7e, 0x2061, 0x8b24, 0x6000,
+ 0x81ff, 0x0040, 0x524e, 0xa205, 0x0078, 0x524f, 0xa204, 0x6002,
+ 0x0c7f, 0x157f, 0x007c, 0x6800, 0xd08c, 0x00c0, 0x525f, 0x6808,
+ 0xa005, 0x0040, 0x525f, 0x8001, 0x680a, 0xa085, 0x0001, 0x007c,
+ 0x127e, 0x2091, 0x2200, 0x2079, 0x8aa2, 0x127f, 0x0d7e, 0x2069,
+ 0x8aa2, 0x6803, 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001,
+ 0x206a, 0x0d7f, 0x007c, 0x0c7e, 0x6027, 0x0001, 0x7804, 0xa084,
+ 0x0007, 0x0079, 0x527b, 0x5285, 0x52aa, 0x5305, 0x528b, 0x52aa,
+ 0x5285, 0x5283, 0x5283, 0x1078, 0x12d2, 0x1078, 0x516f, 0x1078,
+ 0x5888, 0x0c7f, 0x007c, 0x62c0, 0x82ff, 0x00c0, 0x5291, 0x0c7f,
+ 0x007c, 0x2011, 0x3c35, 0x1078, 0x50f2, 0x7828, 0xa092, 0x0002,
+ 0x00c8, 0x52a0, 0x8000, 0x782a, 0x1078, 0x3c6a, 0x0078, 0x528f,
+ 0x1078, 0x3c35, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000,
+ 0x0078, 0x528f, 0x1078, 0x516f, 0x3c00, 0x007e, 0x2011, 0x0209,
+ 0x20e1, 0x4000, 0x2214, 0x007f, 0x20e0, 0x82ff, 0x0040, 0x52c8,
+ 0x62c0, 0x82ff, 0x00c0, 0x52c8, 0x782b, 0x0000, 0x7824, 0xa065,
+ 0x1040, 0x12d2, 0x2009, 0x0013, 0x1078, 0x6939, 0x0c7f, 0x007c,
+ 0x3900, 0xa082, 0x8bc4, 0x00c8, 0x52cf, 0x1078, 0x683b, 0x0c7e,
+ 0x7824, 0xa065, 0x1040, 0x12d2, 0x7804, 0xa086, 0x0004, 0x0040,
+ 0x534a, 0x7828, 0xa092, 0x2710, 0x00c8, 0x52e5, 0x8000, 0x782a,
+ 0x0c7f, 0x1078, 0x6224, 0x0078, 0x52c6, 0x6104, 0xa186, 0x0003,
+ 0x00c0, 0x52fc, 0x0e7e, 0x2071, 0x8800, 0x70cc, 0x0e7f, 0xd08c,
+ 0x0040, 0x52fc, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0x8800,
+ 0x1078, 0x3c73, 0x0e7f, 0x0c7f, 0x1078, 0x8781, 0x2009, 0x0014,
+ 0x1078, 0x6939, 0x0c7f, 0x0078, 0x52c6, 0x2001, 0x8abe, 0x2003,
+ 0x0000, 0x62c0, 0x82ff, 0x00c0, 0x5319, 0x782b, 0x0000, 0x7824,
+ 0xa065, 0x1040, 0x12d2, 0x2009, 0x0013, 0x1078, 0x6990, 0x0c7f,
+ 0x007c, 0x0c7e, 0x0d7e, 0x3900, 0xa082, 0x8bc4, 0x00c8, 0x5322,
+ 0x1078, 0x683b, 0x7824, 0xa005, 0x1040, 0x12d2, 0x781c, 0xa06d,
+ 0x1040, 0x12d2, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x1078,
+ 0x690e, 0x693c, 0x81ff, 0x1040, 0x12d2, 0x8109, 0x693e, 0x6854,
+ 0xa015, 0x0040, 0x533e, 0x7a1e, 0x0078, 0x5340, 0x7918, 0x791e,
+ 0x7807, 0x0000, 0x7827, 0x0000, 0x0d7f, 0x0c7f, 0x1078, 0x5888,
+ 0x0078, 0x5317, 0x6104, 0xa186, 0x0002, 0x0040, 0x5355, 0xa186,
+ 0x0004, 0x0040, 0x5355, 0x0078, 0x52d9, 0x7808, 0xac06, 0x0040,
+ 0x52d9, 0x1078, 0x578f, 0x1078, 0x53e6, 0x0c7f, 0x1078, 0x5888,
+ 0x0078, 0x52c6, 0x0c7e, 0x6027, 0x0002, 0x62c8, 0x82ff, 0x00c0,
+ 0x537c, 0x62c4, 0x82ff, 0x00c0, 0x537c, 0x793c, 0xa1e5, 0x0000,
+ 0x0040, 0x5376, 0x2009, 0x0049, 0x1078, 0x6939, 0x2011, 0x8ac1,
+ 0x2013, 0x0000, 0x0c7f, 0x007c, 0x3908, 0xa192, 0x8bc4, 0x00c8,
+ 0x5383, 0x1078, 0x683b, 0x6017, 0x0010, 0x793c, 0x81ff, 0x0040,
+ 0x5376, 0x793c, 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0,
+ 0x5395, 0x6017, 0x0012, 0x0078, 0x537a, 0x6017, 0x0016, 0x0078,
+ 0x537a, 0x007e, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f,
+ 0x0000, 0x2c08, 0x2061, 0x8aa2, 0x6020, 0x8000, 0x6022, 0x6010,
+ 0xa005, 0x0040, 0x53b4, 0xa080, 0x0003, 0x2102, 0x6112, 0x127f,
+ 0x0c7f, 0x017f, 0x007f, 0x007c, 0x6116, 0x6112, 0x0078, 0x53af,
+ 0x0d7e, 0x2069, 0x8aa2, 0x6000, 0xd0d4, 0x0040, 0x53cd, 0x6820,
+ 0x8000, 0x6822, 0xa086, 0x0001, 0x00c0, 0x53c8, 0x2c00, 0x681e,
+ 0x6804, 0xa084, 0x0007, 0x0079, 0x5890, 0xc0d5, 0x6002, 0x6818,
+ 0xa005, 0x0040, 0x53df, 0x6056, 0x605b, 0x0000, 0x007e, 0x2c00,
+ 0x681a, 0x0d7f, 0x685a, 0x2069, 0x8aa2, 0x0078, 0x53bf, 0x6056,
+ 0x605a, 0x2c00, 0x681a, 0x681e, 0x0078, 0x53bf, 0x007e, 0x017e,
0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061,
- 0x7936, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040, 0x49a9,
+ 0x8aa2, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040, 0x5401,
0xa080, 0x0003, 0x2102, 0x610a, 0x127f, 0x0c7f, 0x017f, 0x007f,
- 0x007c, 0x610e, 0x610a, 0x0078, 0x49a4, 0x0c7e, 0x600f, 0x0000,
- 0x2c08, 0x2061, 0x7936, 0x6034, 0xa005, 0x0040, 0x49bd, 0xa080,
+ 0x007c, 0x610e, 0x610a, 0x0078, 0x53fc, 0x0c7e, 0x600f, 0x0000,
+ 0x2c08, 0x2061, 0x8aa2, 0x6034, 0xa005, 0x0040, 0x5415, 0xa080,
0x0003, 0x2102, 0x6136, 0x0c7f, 0x007c, 0x613a, 0x6136, 0x0078,
- 0x49bb, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x007e,
- 0x127e, 0x2071, 0x7936, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000,
- 0x8cff, 0x0040, 0x4a23, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206,
- 0x00c0, 0x4a1e, 0x703c, 0xac06, 0x00c0, 0x49e3, 0x6003, 0x000a,
- 0x630a, 0x0078, 0x4a1e, 0x7038, 0xac36, 0x00c0, 0x49e9, 0x660c,
- 0x763a, 0x7034, 0xac36, 0x00c0, 0x49f7, 0x2c00, 0xaf36, 0x0040,
- 0x49f5, 0x2f00, 0x7036, 0x0078, 0x49f7, 0x7037, 0x0000, 0x660c,
- 0x067e, 0x2c00, 0xaf06, 0x0040, 0x4a00, 0x7e0e, 0x0078, 0x4a01,
- 0x2678, 0x600f, 0x0000, 0x1078, 0x6a58, 0x0040, 0x4a19, 0x6010,
- 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x4a2c, 0x6837, 0x0103,
- 0x6b4a, 0x6847, 0x0000, 0x1078, 0x6c54, 0x1078, 0x3b92, 0x1078,
- 0x6ba9, 0x1078, 0x6bb6, 0x0c7f, 0x0078, 0x49d0, 0x2c78, 0x600c,
- 0x2060, 0x0078, 0x49d0, 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f,
- 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0,
- 0x4a0e, 0x1078, 0x75fd, 0x0078, 0x4a19, 0x007e, 0x067e, 0x0c7e,
- 0x0d7e, 0x0f7e, 0x2031, 0x0000, 0x127e, 0x2091, 0x8000, 0x2079,
- 0x7936, 0x7838, 0xa065, 0x0040, 0x4a6c, 0x600c, 0x007e, 0x600f,
- 0x0000, 0x783c, 0xac06, 0x00c0, 0x4a53, 0x6003, 0x000a, 0x630a,
- 0x2c30, 0x0078, 0x4a69, 0x1078, 0x6a58, 0x0040, 0x4a67, 0x6010,
- 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x4a75, 0x6837, 0x0103,
- 0x6b4a, 0x6847, 0x0000, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x1078,
- 0x6bb6, 0x007f, 0x0078, 0x4a42, 0x7e3a, 0x7e36, 0x127f, 0x0f7f,
- 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x601c, 0xa086, 0x0006,
- 0x00c0, 0x4a5e, 0x1078, 0x75fd, 0x0078, 0x4a67, 0x027e, 0x1078,
- 0x4a92, 0x1078, 0x4b2b, 0x027f, 0x007c, 0x0f7e, 0x127e, 0x2079,
- 0x7936, 0x2091, 0x8000, 0x1078, 0x4bc2, 0x1078, 0x4c2a, 0x127f,
- 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e,
- 0x127e, 0x2091, 0x8000, 0x2071, 0x7936, 0x7614, 0x2660, 0x2678,
- 0x8cff, 0x0040, 0x4b1a, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206,
- 0x00c0, 0x4b15, 0x7024, 0xac06, 0x00c0, 0x4ad8, 0x2069, 0x0100,
- 0x68c0, 0xa005, 0x0040, 0x4ad3, 0x1078, 0x569c, 0x68c3, 0x0000,
- 0x1078, 0x5b4a, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04,
- 0xa384, 0x1000, 0x0040, 0x4ac8, 0x6803, 0x0100, 0x6803, 0x0000,
- 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x4ad0, 0x6827, 0x0001,
- 0x037f, 0x0078, 0x4ad8, 0x6003, 0x0009, 0x630a, 0x0078, 0x4b15,
- 0x7014, 0xac36, 0x00c0, 0x4ade, 0x660c, 0x7616, 0x7010, 0xac36,
- 0x00c0, 0x4aec, 0x2c00, 0xaf36, 0x0040, 0x4aea, 0x2f00, 0x7012,
- 0x0078, 0x4aec, 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06,
- 0x0040, 0x4af5, 0x7e0e, 0x0078, 0x4af6, 0x2678, 0x600f, 0x0000,
- 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x4b0e, 0x601c, 0xa086,
- 0x0003, 0x00c0, 0x4b22, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
- 0x1078, 0x6c54, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x1078, 0x6bb6,
- 0x1078, 0x5a1a, 0x0c7f, 0x0078, 0x4aa0, 0x2c78, 0x600c, 0x2060,
- 0x0078, 0x4aa0, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f,
- 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x4b03, 0x1078,
- 0x75fd, 0x0078, 0x4b0e, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000,
- 0xa280, 0x7820, 0x2004, 0xa065, 0x0040, 0x4bbe, 0x0f7e, 0x0e7e,
- 0x0d7e, 0x067e, 0x2071, 0x7936, 0x6654, 0x7018, 0xac06, 0x00c0,
- 0x4b42, 0x761a, 0x701c, 0xac06, 0x00c0, 0x4b4e, 0x86ff, 0x00c0,
- 0x4b4d, 0x7018, 0x701e, 0x0078, 0x4b4e, 0x761e, 0x6058, 0xa07d,
- 0x0040, 0x4b53, 0x7e56, 0xa6ed, 0x0000, 0x0040, 0x4b59, 0x2f00,
- 0x685a, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc,
- 0x6002, 0x1078, 0x37c5, 0x0040, 0x4bba, 0x7624, 0x86ff, 0x0040,
- 0x4baa, 0xa680, 0x0004, 0x2004, 0xad06, 0x00c0, 0x4baa, 0x0d7e,
- 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x4ba1, 0x1078, 0x569c,
- 0x68c3, 0x0000, 0x1078, 0x5b4a, 0x7027, 0x0000, 0x037e, 0x2069,
- 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x4b8a, 0x6803, 0x0100,
- 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x4b92,
- 0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040,
- 0x4b9b, 0x8001, 0x603e, 0x2660, 0x1078, 0x6bb6, 0x0c7f, 0x0078,
- 0x4baa, 0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f,
- 0x0078, 0x4b61, 0x8dff, 0x0040, 0x4bb6, 0x6837, 0x0103, 0x6b4a,
- 0x6847, 0x0000, 0x1078, 0x6c54, 0x1078, 0x3b92, 0x1078, 0x5a1a,
- 0x0078, 0x4b61, 0x067f, 0x0d7f, 0x0e7f, 0x0f7f, 0x127f, 0x007f,
- 0x0c7f, 0x007c, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x2031, 0x0000,
- 0x7814, 0xa065, 0x0040, 0x4c1a, 0x600c, 0x007e, 0x600f, 0x0000,
- 0x7824, 0xac06, 0x00c0, 0x4bff, 0x2069, 0x0100, 0x68c0, 0xa005,
- 0x0040, 0x4bf9, 0x1078, 0x569c, 0x68c3, 0x0000, 0x1078, 0x5b4a,
- 0x7827, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
- 0x0040, 0x4bee, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
- 0x6824, 0xd084, 0x0040, 0x4bf6, 0x6827, 0x0001, 0x037f, 0x0078,
- 0x4bff, 0x6003, 0x0009, 0x630a, 0x2c30, 0x0078, 0x4c17, 0x6010,
- 0x2068, 0x1078, 0x6a58, 0x0040, 0x4c13, 0x601c, 0xa086, 0x0003,
- 0x00c0, 0x4c21, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078,
- 0x3b92, 0x1078, 0x6ba9, 0x1078, 0x6bb6, 0x1078, 0x5a1a, 0x007f,
- 0x0078, 0x4bc9, 0x7e16, 0x7e12, 0x0d7f, 0x0c7f, 0x067f, 0x007f,
- 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x4c0a, 0x1078, 0x75fd,
- 0x0078, 0x4c13, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x7818, 0xa065,
- 0x0040, 0x4c96, 0x6054, 0x007e, 0x6057, 0x0000, 0x605b, 0x0000,
- 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x37c5, 0x0040, 0x4c93,
- 0x7e24, 0x86ff, 0x0040, 0x4c85, 0xa680, 0x0004, 0x2004, 0xad06,
- 0x00c0, 0x4c85, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040,
- 0x4c7c, 0x1078, 0x569c, 0x68c3, 0x0000, 0x1078, 0x5b4a, 0x7827,
+ 0x5413, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x017e,
+ 0x007e, 0x127e, 0x2071, 0x8aa2, 0x7638, 0x2660, 0x2678, 0x2091,
+ 0x8000, 0x8cff, 0x0040, 0x548c, 0x6018, 0xa080, 0x0028, 0x2004,
+ 0xa206, 0x00c0, 0x5487, 0x88ff, 0x0040, 0x543a, 0x6020, 0xa106,
+ 0x00c0, 0x5487, 0x703c, 0xac06, 0x00c0, 0x544c, 0x037e, 0x2019,
+ 0x0001, 0x1078, 0x642d, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043,
+ 0x0000, 0x7047, 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x5452,
+ 0x660c, 0x763a, 0x7034, 0xac36, 0x00c0, 0x5460, 0x2c00, 0xaf36,
+ 0x0040, 0x545e, 0x2f00, 0x7036, 0x0078, 0x5460, 0x7037, 0x0000,
+ 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5469, 0x7e0e, 0x0078,
+ 0x546a, 0x2678, 0x600f, 0x0000, 0x1078, 0x77ed, 0x0040, 0x5482,
+ 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5496, 0x6837,
+ 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x7a46, 0x1078, 0x4376,
+ 0x1078, 0x799b, 0x1078, 0x79a8, 0x0c7f, 0x0078, 0x5429, 0x2c78,
+ 0x600c, 0x2060, 0x0078, 0x5429, 0x127f, 0x007f, 0x017f, 0x027f,
+ 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086,
+ 0x0006, 0x00c0, 0x5477, 0x1078, 0x86aa, 0x0078, 0x5482, 0x007e,
+ 0x067e, 0x0c7e, 0x0d7e, 0x0f7e, 0x2031, 0x0000, 0x127e, 0x2091,
+ 0x8000, 0x2079, 0x8aa2, 0x7838, 0xa065, 0x0040, 0x54de, 0x600c,
+ 0x007e, 0x600f, 0x0000, 0x783c, 0xac06, 0x00c0, 0x54c5, 0x037e,
+ 0x2019, 0x0001, 0x1078, 0x642d, 0x7833, 0x0000, 0x783f, 0x0000,
+ 0x7843, 0x0000, 0x7847, 0x0000, 0x037f, 0x1078, 0x77ed, 0x0040,
+ 0x54d9, 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x54e7,
+ 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4376, 0x1078,
+ 0x799b, 0x1078, 0x79a8, 0x007f, 0x0078, 0x54ac, 0x7e3a, 0x7e36,
+ 0x127f, 0x0f7f, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x601c,
+ 0xa086, 0x0006, 0x00c0, 0x54d0, 0x1078, 0x86aa, 0x0078, 0x54d9,
+ 0x017e, 0x027e, 0x087e, 0x2041, 0x0000, 0x1078, 0x550a, 0x1078,
+ 0x55ae, 0x087f, 0x027f, 0x017f, 0x007c, 0x0f7e, 0x127e, 0x2079,
+ 0x8aa2, 0x2091, 0x8000, 0x1078, 0x5647, 0x1078, 0x56b1, 0x127f,
+ 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x017e,
+ 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x8aa2, 0x7614, 0x2660,
+ 0x2678, 0x8cff, 0x0040, 0x559c, 0x6018, 0xa080, 0x0028, 0x2004,
+ 0xa206, 0x00c0, 0x5597, 0x88ff, 0x0040, 0x552a, 0x6020, 0xa106,
+ 0x00c0, 0x5597, 0x7024, 0xac06, 0x00c0, 0x555a, 0x2069, 0x0100,
+ 0x68c0, 0xa005, 0x0040, 0x5555, 0x1078, 0x516f, 0x1078, 0x6232,
+ 0x68c3, 0x0000, 0x1078, 0x6741, 0x7027, 0x0000, 0x037e, 0x2069,
+ 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x554a, 0x6803, 0x0100,
+ 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5552,
+ 0x6827, 0x0001, 0x037f, 0x0078, 0x555a, 0x6003, 0x0009, 0x630a,
+ 0x0078, 0x5597, 0x7014, 0xac36, 0x00c0, 0x5560, 0x660c, 0x7616,
+ 0x7010, 0xac36, 0x00c0, 0x556e, 0x2c00, 0xaf36, 0x0040, 0x556c,
+ 0x2f00, 0x7012, 0x0078, 0x556e, 0x7013, 0x0000, 0x660c, 0x067e,
+ 0x2c00, 0xaf06, 0x0040, 0x5577, 0x7e0e, 0x0078, 0x5578, 0x2678,
+ 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, 0x5590,
+ 0x601c, 0xa086, 0x0003, 0x00c0, 0x55a5, 0x6837, 0x0103, 0x6b4a,
+ 0x6847, 0x0000, 0x1078, 0x7a46, 0x1078, 0x4376, 0x1078, 0x799b,
+ 0x1078, 0x79a8, 0x1078, 0x6601, 0x0c7f, 0x0078, 0x5519, 0x2c78,
+ 0x600c, 0x2060, 0x0078, 0x5519, 0x127f, 0x007f, 0x017f, 0x067f,
+ 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006,
+ 0x00c0, 0x5585, 0x1078, 0x86aa, 0x0078, 0x5590, 0x0c7e, 0x007e,
+ 0x127e, 0x2091, 0x8000, 0xa280, 0x8934, 0x2004, 0xa065, 0x0040,
+ 0x5643, 0x0f7e, 0x0e7e, 0x0d7e, 0x067e, 0x2071, 0x8aa2, 0x6654,
+ 0x7018, 0xac06, 0x00c0, 0x55c5, 0x761a, 0x701c, 0xac06, 0x00c0,
+ 0x55d1, 0x86ff, 0x00c0, 0x55d0, 0x7018, 0x701e, 0x0078, 0x55d1,
+ 0x761e, 0x6058, 0xa07d, 0x0040, 0x55d6, 0x7e56, 0xa6ed, 0x0000,
+ 0x0040, 0x55dc, 0x2f00, 0x685a, 0x6057, 0x0000, 0x605b, 0x0000,
+ 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x3ed6, 0x0040, 0x563f,
+ 0x7624, 0x86ff, 0x0040, 0x562f, 0xa680, 0x0004, 0x2004, 0xad06,
+ 0x00c0, 0x562f, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040,
+ 0x5626, 0x1078, 0x516f, 0x1078, 0x6232, 0x68c3, 0x0000, 0x1078,
+ 0x6741, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384,
+ 0x1000, 0x0040, 0x560f, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069,
+ 0x0100, 0x6824, 0xd084, 0x0040, 0x5617, 0x6827, 0x0001, 0x037f,
+ 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040, 0x5620, 0x8001, 0x603e,
+ 0x2660, 0x1078, 0x79a8, 0x0c7f, 0x0078, 0x562f, 0x0d7f, 0x0c7e,
+ 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x55e4, 0x8dff,
+ 0x0040, 0x563b, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078,
+ 0x7a46, 0x1078, 0x4376, 0x1078, 0x6601, 0x0078, 0x55e4, 0x067f,
+ 0x0d7f, 0x0e7f, 0x0f7f, 0x127f, 0x007f, 0x0c7f, 0x007c, 0x007e,
+ 0x067e, 0x0c7e, 0x0d7e, 0x2031, 0x0000, 0x7814, 0xa065, 0x0040,
+ 0x56a1, 0x600c, 0x007e, 0x600f, 0x0000, 0x7824, 0xac06, 0x00c0,
+ 0x5686, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x5680, 0x1078,
+ 0x516f, 0x1078, 0x6232, 0x68c3, 0x0000, 0x1078, 0x6741, 0x7827,
0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040,
- 0x4c65, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824,
- 0xd084, 0x0040, 0x4c6d, 0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e,
- 0x603c, 0xa005, 0x0040, 0x4c76, 0x8001, 0x603e, 0x2660, 0x1078,
- 0x6bb6, 0x0c7f, 0x0078, 0x4c85, 0x0d7f, 0x0c7e, 0x2660, 0x6003,
- 0x0009, 0x630a, 0x0c7f, 0x0078, 0x4c3c, 0x8dff, 0x0040, 0x4c8f,
- 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x3b92, 0x1078,
- 0x5a1a, 0x0078, 0x4c3c, 0x007f, 0x0078, 0x4c2f, 0x781e, 0x781a,
- 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x0e7e, 0x0c7e, 0x2071,
- 0x7936, 0x7004, 0xa084, 0x0007, 0x0079, 0x4ca6, 0x4cb0, 0x4cb3,
- 0x4ccc, 0x4ce8, 0x4d2d, 0x4cb0, 0x4cb0, 0x4cae, 0x1078, 0x12cd,
- 0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065, 0x0040, 0x4cc1, 0x7020,
- 0x8001, 0x7022, 0x600c, 0xa015, 0x0040, 0x4cc8, 0x7216, 0x600f,
- 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c,
- 0x7216, 0x7212, 0x0078, 0x4cc1, 0x6018, 0x2060, 0x1078, 0x37c5,
- 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022, 0x0040, 0x4cdd,
- 0x6054, 0xa015, 0x0040, 0x4ce4, 0x721e, 0x7007, 0x0000, 0x7027,
- 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7218, 0x721e, 0x0078, 0x4cdd,
- 0x7024, 0xa065, 0x0040, 0x4d2a, 0x700c, 0xac06, 0x00c0, 0x4cff,
- 0x1078, 0x5a1a, 0x600c, 0xa015, 0x0040, 0x4cfb, 0x720e, 0x600f,
- 0x0000, 0x0078, 0x4d28, 0x720e, 0x720a, 0x0078, 0x4d28, 0x7014,
- 0xac06, 0x00c0, 0x4d12, 0x1078, 0x5a1a, 0x600c, 0xa015, 0x0040,
- 0x4d0e, 0x7216, 0x600f, 0x0000, 0x0078, 0x4d28, 0x7216, 0x7212,
- 0x0078, 0x4d28, 0x6018, 0x2060, 0x1078, 0x37c5, 0x6000, 0xc0dc,
- 0x6002, 0x1078, 0x5a1a, 0x701c, 0xa065, 0x0040, 0x4d28, 0x6054,
- 0xa015, 0x0040, 0x4d26, 0x721e, 0x0078, 0x4d28, 0x7218, 0x721e,
- 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065, 0x0040,
- 0x4d3a, 0x1078, 0x5a1a, 0x600c, 0xa015, 0x0040, 0x4d41, 0x720e,
- 0x600f, 0x0000, 0x1078, 0x5b4a, 0x7027, 0x0000, 0x0c7f, 0x0e7f,
- 0x007c, 0x720e, 0x720a, 0x0078, 0x4d3a, 0x0d7e, 0x2069, 0x7936,
- 0x6830, 0xa084, 0x0003, 0x0079, 0x4d4d, 0x4d53, 0x4d55, 0x4d7b,
- 0x4d53, 0x1078, 0x12cd, 0x0d7f, 0x007c, 0x0c7e, 0x6840, 0xa086,
- 0x0001, 0x0040, 0x4d71, 0x683c, 0xa065, 0x0040, 0x4d66, 0x600c,
- 0xa015, 0x0040, 0x4d6d, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000,
- 0x683f, 0x0000, 0x0c7f, 0x0d7f, 0x007c, 0x683a, 0x6836, 0x0078,
- 0x4d66, 0x6843, 0x0000, 0x6838, 0xa065, 0x0040, 0x4d66, 0x6003,
- 0x0003, 0x0078, 0x4d66, 0x0c7e, 0x6843, 0x0000, 0x6847, 0x0000,
- 0x683c, 0xa065, 0x0040, 0x4d93, 0x600c, 0xa015, 0x0040, 0x4d8f,
- 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000, 0x0078, 0x4d93, 0x683f,
- 0x0000, 0x683a, 0x6836, 0x0c7f, 0x0d7f, 0x007c, 0x0d7e, 0x2069,
- 0x7936, 0x6804, 0xa084, 0x0007, 0x0079, 0x4d9e, 0x4da8, 0x4e45,
- 0x4e45, 0x4e45, 0x4e45, 0x4e47, 0x4e45, 0x4da6, 0x1078, 0x12cd,
- 0x6820, 0xa005, 0x00c0, 0x4dae, 0x0d7f, 0x007c, 0x0c7e, 0x680c,
- 0xa065, 0x0040, 0x4dbd, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000,
- 0x1078, 0x4e8d, 0x0c7f, 0x0d7f, 0x007c, 0x6814, 0xa065, 0x0040,
- 0x4dcb, 0x6807, 0x0001, 0x6826, 0x682b, 0x0000, 0x1078, 0x4e8d,
- 0x0c7f, 0x0d7f, 0x007c, 0x0e7e, 0x037e, 0x6a1c, 0xa2f5, 0x0000,
- 0x0040, 0x4e40, 0x704c, 0xa00d, 0x0040, 0x4dda, 0x7088, 0xa005,
- 0x0040, 0x4df2, 0x7054, 0xa075, 0x0040, 0x4de3, 0xa20e, 0x0040,
- 0x4e40, 0x0078, 0x4de8, 0x6818, 0xa20e, 0x0040, 0x4e40, 0x2070,
- 0x704c, 0xa00d, 0x0040, 0x4dda, 0x7088, 0xa005, 0x00c0, 0x4dda,
- 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, 0x00c8, 0x4dda, 0x1078,
- 0x5ce9, 0x0040, 0x4e40, 0x8318, 0x733e, 0x6112, 0x2e10, 0x621a,
- 0xa180, 0x0015, 0x2004, 0xa08a, 0x199a, 0x0048, 0x4e09, 0x2001,
- 0x1999, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x037f, 0x0f7e,
- 0x2c78, 0x71a0, 0xd1bc, 0x0040, 0x4e22, 0x7100, 0xd1f4, 0x0040,
- 0x4e1e, 0x7114, 0xa18c, 0x00ff, 0x0078, 0x4e27, 0x2009, 0x0000,
- 0x0078, 0x4e27, 0xa1e0, 0x2329, 0x2c0c, 0xa18c, 0x00ff, 0x2061,
- 0x0100, 0x619a, 0x1078, 0x52de, 0x7300, 0xc3dd, 0x7302, 0x6807,
- 0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, 0x781f, 0x0003, 0x7803,
- 0x0001, 0x7807, 0x0040, 0x0f7f, 0x0e7f, 0x0c7f, 0x0d7f, 0x007c,
- 0x037f, 0x0e7f, 0x0c7f, 0x0078, 0x4e3e, 0x0d7f, 0x007c, 0x0c7e,
- 0x680c, 0xa065, 0x0040, 0x4e53, 0x6807, 0x0004, 0x6826, 0x682b,
- 0x0000, 0x1078, 0x4e8d, 0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0d7e,
- 0x2069, 0x7936, 0x6830, 0xa086, 0x0000, 0x00c0, 0x4e74, 0x6838,
- 0xa07d, 0x0040, 0x4e74, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000,
- 0x127e, 0x0f7e, 0x2091, 0x2200, 0x027f, 0x1078, 0x1a44, 0x00c0,
- 0x4e77, 0x127f, 0x1078, 0x5571, 0x0d7f, 0x0f7f, 0x007c, 0x127f,
- 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015, 0x0040, 0x4e89,
- 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0078,
- 0x4e74, 0x683a, 0x6836, 0x0078, 0x4e83, 0x601c, 0xa084, 0x000f,
- 0x1079, 0x4e93, 0x007c, 0x4e9c, 0x4ea1, 0x51a8, 0x529e, 0x4ea1,
- 0x51a8, 0x529e, 0x4e9c, 0x4ea1, 0x1078, 0x4c9d, 0x1078, 0x4d96,
- 0x007c, 0x157e, 0x137e, 0x147e, 0x0c7e, 0x0f7e, 0x6004, 0xa08a,
- 0x0030, 0x10c8, 0x12cd, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040,
- 0x4ebe, 0x7900, 0xd1f4, 0x0040, 0x4eba, 0x7914, 0xa18c, 0x00ff,
- 0x0078, 0x4ec3, 0x2009, 0x0000, 0x0078, 0x4ec3, 0xa1f8, 0x2329,
- 0x2f0c, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0x1079,
- 0x4ecf, 0x0f7f, 0x0c7f, 0x147f, 0x137f, 0x157f, 0x007c, 0x4f01,
- 0x4f39, 0x4f51, 0x4fd0, 0x4ffd, 0x5005, 0x5026, 0x5037, 0x5048,
- 0x5050, 0x5061, 0x5050, 0x50a9, 0x5037, 0x50ca, 0x50d2, 0x5048,
- 0x50d2, 0x50e3, 0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x4eff,
- 0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x4eff, 0x5758, 0x576d,
- 0x5790, 0x57b4, 0x5026, 0x4eff, 0x5026, 0x5050, 0x4eff, 0x4f51,
- 0x4fd0, 0x4eff, 0x5c64, 0x5050, 0x4eff, 0x5c87, 0x5050, 0x1078,
- 0x12cd, 0x20a1, 0x020b, 0x1078, 0x50f8, 0x20a3, 0x5200, 0x20a3,
- 0x0000, 0x0d7e, 0x2069, 0x7751, 0x6804, 0xd084, 0x0040, 0x4f1b,
- 0x6828, 0x20a3, 0x0000, 0x017e, 0x1078, 0x2094, 0x21a2, 0x017f,
- 0x0d7f, 0x0078, 0x4f20, 0x0d7f, 0x20a3, 0x0000, 0x20a3, 0x0000,
- 0x20a9, 0x0004, 0x2099, 0x7705, 0x53a6, 0x20a9, 0x0004, 0x2099,
- 0x7701, 0x53a6, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2,
- 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x5688,
- 0x007c, 0x20a1, 0x020b, 0x1078, 0x50f8, 0x20a3, 0x0500, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a9,
- 0x0004, 0x2099, 0x7705, 0x53a6, 0x60c3, 0x0010, 0x1078, 0x5688,
- 0x007c, 0x20a1, 0x020b, 0x1078, 0x50f8, 0x7818, 0xa080, 0x0028,
- 0x2004, 0xa086, 0x007e, 0x00c0, 0x4f64, 0x20a3, 0x0400, 0x620c,
- 0xc2b4, 0x620e, 0x0078, 0x4f66, 0x20a3, 0x0300, 0x20a3, 0x0000,
- 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x4f9f,
- 0x2099, 0x7920, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0xa084,
- 0x3fff, 0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
- 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x7705,
- 0x53a6, 0x20a9, 0x0004, 0x2099, 0x7701, 0x53a6, 0x20a9, 0x0010,
- 0x20a3, 0x0000, 0x00f0, 0x4f90, 0x2099, 0x7928, 0x33a6, 0x20a9,
- 0x0007, 0x20a3, 0x0000, 0x00f0, 0x4f99, 0x0078, 0x4fbf, 0x2099,
- 0x7920, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004, 0x2099, 0x7705,
- 0x53a6, 0x20a9, 0x0004, 0x2099, 0x7701, 0x53a6, 0x20a9, 0x0008,
- 0x20a3, 0x0000, 0x00f0, 0x4fb0, 0x20a9, 0x0008, 0x20a3, 0x0000,
- 0x00f0, 0x4fb6, 0x2099, 0x7928, 0x20a9, 0x0008, 0x53a6, 0x20a9,
- 0x0008, 0x20a3, 0x0000, 0x00f0, 0x4fc1, 0x20a9, 0x000a, 0x20a3,
- 0x0000, 0x00f0, 0x4fc7, 0x60c3, 0x0074, 0x1078, 0x5688, 0x007c,
- 0x20a1, 0x020b, 0x1078, 0x50f8, 0x20a3, 0x2010, 0x20a3, 0x0014,
- 0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006, 0x20a2, 0x20a2, 0x20a2,
- 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0x7751, 0x7904, 0x0f7f, 0xd1ac,
- 0x00c0, 0x4fec, 0xa085, 0x0020, 0xd1a4, 0x0040, 0x4ff1, 0xa085,
- 0x0010, 0xa085, 0x0002, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
- 0x60c3, 0x0014, 0x1078, 0x5688, 0x007c, 0x20a1, 0x020b, 0x1078,
- 0x50f8, 0x20a3, 0x5000, 0x0078, 0x4f66, 0x20a1, 0x020b, 0x1078,
- 0x50f8, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
- 0x0000, 0x60c3, 0x0014, 0x1078, 0x5688, 0x007c, 0x20a1, 0x020b,
- 0x1078, 0x516f, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000,
- 0x20a3, 0x0000, 0x60c3, 0x0004, 0x1078, 0x5688, 0x007c, 0x20a1,
- 0x020b, 0x1078, 0x516f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3,
- 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x1078, 0x5688, 0x007c,
- 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0200, 0x0078, 0x4f66,
- 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0100, 0x20a3, 0x0000,
- 0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x5688,
- 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0210,
- 0x20a3, 0x0014, 0x20a3, 0x0800, 0x7818, 0x2068, 0x6894, 0xa086,
- 0x0014, 0x00c0, 0x5087, 0x6998, 0xa184, 0xc000, 0x00c0, 0x5083,
- 0xd1ec, 0x0040, 0x507f, 0x20a3, 0x2100, 0x0078, 0x5089, 0x20a3,
- 0x0100, 0x0078, 0x5089, 0x20a3, 0x0400, 0x0078, 0x5089, 0x20a3,
- 0x0700, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e,
- 0x2079, 0x7751, 0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x5099, 0xa085,
- 0x0020, 0xd1a4, 0x0040, 0x509e, 0xa085, 0x0010, 0xa085, 0x0002,
- 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x0014, 0x1078, 0x5688, 0x0d7f,
- 0x007c, 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0210, 0x20a3,
- 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078,
- 0x5688, 0x007c, 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0200,
- 0x0078, 0x4f07, 0x20a1, 0x020b, 0x1078, 0x516f, 0x20a3, 0x0100,
- 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008,
- 0x1078, 0x5688, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1,
- 0x020b, 0x1078, 0x516f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3,
- 0x000b, 0x20a3, 0x0000, 0x60c3, 0x0008, 0x1078, 0x5688, 0x007c,
- 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
- 0x2014, 0xa286, 0x007e, 0x00c0, 0x510b, 0x20a3, 0x22ff, 0x20a3,
- 0xfffe, 0x0078, 0x5139, 0xa286, 0x007f, 0x00c0, 0x5116, 0x0d7e,
- 0x20a3, 0x22ff, 0x20a3, 0xfffd, 0x0078, 0x512d, 0xd2bc, 0x0040,
- 0x5135, 0xa286, 0x0080, 0x0d7e, 0x00c0, 0x5124, 0x20a3, 0x22ff,
- 0x20a3, 0xfffc, 0x0078, 0x512d, 0xa2e8, 0x7820, 0x2d6c, 0x6810,
- 0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6,
- 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x513d, 0x20a3, 0x2200, 0x6298,
- 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0129, 0x20a3,
- 0x0000, 0x1078, 0x5677, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3,
+ 0x5675, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824,
+ 0xd084, 0x0040, 0x567d, 0x6827, 0x0001, 0x037f, 0x0078, 0x5686,
+ 0x6003, 0x0009, 0x630a, 0x2c30, 0x0078, 0x569e, 0x6010, 0x2068,
+ 0x1078, 0x77ed, 0x0040, 0x569a, 0x601c, 0xa086, 0x0003, 0x00c0,
+ 0x56a8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4376,
+ 0x1078, 0x799b, 0x1078, 0x79a8, 0x1078, 0x6601, 0x007f, 0x0078,
+ 0x564e, 0x7e16, 0x7e12, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c,
+ 0x601c, 0xa086, 0x0006, 0x00c0, 0x5691, 0x1078, 0x86aa, 0x0078,
+ 0x569a, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x7818, 0xa065, 0x0040,
+ 0x571f, 0x6054, 0x007e, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000,
+ 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x3ed6, 0x0040, 0x571c, 0x7e24,
+ 0x86ff, 0x0040, 0x570e, 0xa680, 0x0004, 0x2004, 0xad06, 0x00c0,
+ 0x570e, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x5705,
+ 0x1078, 0x516f, 0x1078, 0x6232, 0x68c3, 0x0000, 0x1078, 0x6741,
+ 0x7827, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
+ 0x0040, 0x56ee, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
+ 0x6824, 0xd084, 0x0040, 0x56f6, 0x6827, 0x0001, 0x037f, 0x0d7f,
+ 0x0c7e, 0x603c, 0xa005, 0x0040, 0x56ff, 0x8001, 0x603e, 0x2660,
+ 0x1078, 0x79a8, 0x0c7f, 0x0078, 0x570e, 0x0d7f, 0x0c7e, 0x2660,
+ 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x56c3, 0x8dff, 0x0040,
+ 0x5718, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4376,
+ 0x1078, 0x6601, 0x0078, 0x56c3, 0x007f, 0x0078, 0x56b6, 0x781e,
+ 0x781a, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x0e7e, 0x0d7e,
+ 0x067e, 0x6000, 0xd0dc, 0x0040, 0x5743, 0x604c, 0xa06d, 0x0040,
+ 0x5743, 0x6848, 0xa606, 0x00c0, 0x5743, 0x2071, 0x8aa2, 0x7024,
+ 0xa035, 0x0040, 0x5743, 0xa080, 0x0004, 0x2004, 0xad06, 0x00c0,
+ 0x5743, 0x1078, 0x5747, 0x067f, 0x0d7f, 0x0e7f, 0x007c, 0x0f7e,
+ 0x2079, 0x0100, 0x78c0, 0xa005, 0x00c0, 0x5756, 0x0c7e, 0x2660,
+ 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x578d, 0x1078, 0x6232,
+ 0x78c3, 0x0000, 0x1078, 0x6741, 0x7027, 0x0000, 0x037e, 0x2079,
+ 0x0140, 0x7b04, 0xa384, 0x1000, 0x0040, 0x576a, 0x7803, 0x0100,
+ 0x7803, 0x0000, 0x2079, 0x0100, 0x7824, 0xd084, 0x0040, 0x5772,
+ 0x7827, 0x0001, 0x1078, 0x6741, 0x037f, 0x1078, 0x3ed6, 0x0c7e,
+ 0x603c, 0xa005, 0x0040, 0x577e, 0x8001, 0x603e, 0x2660, 0x1078,
+ 0x690e, 0x0c7f, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078,
+ 0x7a46, 0x1078, 0x4376, 0x1078, 0x6601, 0x0f7f, 0x007c, 0x0e7e,
+ 0x0c7e, 0x2071, 0x8aa2, 0x7004, 0xa084, 0x0007, 0x0079, 0x5798,
+ 0x57a2, 0x57a5, 0x57be, 0x57da, 0x581f, 0x57a2, 0x57a2, 0x57a0,
+ 0x1078, 0x12d2, 0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065, 0x0040,
+ 0x57b3, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015, 0x0040, 0x57ba,
+ 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x0c7f,
+ 0x0e7f, 0x007c, 0x7216, 0x7212, 0x0078, 0x57b3, 0x6018, 0x2060,
+ 0x1078, 0x3ed6, 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022,
+ 0x0040, 0x57cf, 0x6054, 0xa015, 0x0040, 0x57d6, 0x721e, 0x7007,
+ 0x0000, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7218, 0x721e,
+ 0x0078, 0x57cf, 0x7024, 0xa065, 0x0040, 0x581c, 0x700c, 0xac06,
+ 0x00c0, 0x57f1, 0x1078, 0x6601, 0x600c, 0xa015, 0x0040, 0x57ed,
+ 0x720e, 0x600f, 0x0000, 0x0078, 0x581a, 0x720e, 0x720a, 0x0078,
+ 0x581a, 0x7014, 0xac06, 0x00c0, 0x5804, 0x1078, 0x6601, 0x600c,
+ 0xa015, 0x0040, 0x5800, 0x7216, 0x600f, 0x0000, 0x0078, 0x581a,
+ 0x7216, 0x7212, 0x0078, 0x581a, 0x6018, 0x2060, 0x1078, 0x3ed6,
+ 0x6000, 0xc0dc, 0x6002, 0x1078, 0x6601, 0x701c, 0xa065, 0x0040,
+ 0x581a, 0x6054, 0xa015, 0x0040, 0x5818, 0x721e, 0x0078, 0x581a,
+ 0x7218, 0x721e, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7024,
+ 0xa065, 0x0040, 0x582c, 0x1078, 0x6601, 0x600c, 0xa015, 0x0040,
+ 0x5833, 0x720e, 0x600f, 0x0000, 0x1078, 0x6741, 0x7027, 0x0000,
+ 0x0c7f, 0x0e7f, 0x007c, 0x720e, 0x720a, 0x0078, 0x582c, 0x0d7e,
+ 0x2069, 0x8aa2, 0x6830, 0xa084, 0x0003, 0x0079, 0x583f, 0x5845,
+ 0x5847, 0x586d, 0x5845, 0x1078, 0x12d2, 0x0d7f, 0x007c, 0x0c7e,
+ 0x6840, 0xa086, 0x0001, 0x0040, 0x5863, 0x683c, 0xa065, 0x0040,
+ 0x5858, 0x600c, 0xa015, 0x0040, 0x585f, 0x6a3a, 0x600f, 0x0000,
+ 0x6833, 0x0000, 0x683f, 0x0000, 0x0c7f, 0x0d7f, 0x007c, 0x683a,
+ 0x6836, 0x0078, 0x5858, 0x6843, 0x0000, 0x6838, 0xa065, 0x0040,
+ 0x5858, 0x6003, 0x0003, 0x0078, 0x5858, 0x0c7e, 0x6843, 0x0000,
+ 0x6847, 0x0000, 0x683c, 0xa065, 0x0040, 0x5885, 0x600c, 0xa015,
+ 0x0040, 0x5881, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000, 0x0078,
+ 0x5885, 0x683f, 0x0000, 0x683a, 0x6836, 0x0c7f, 0x0d7f, 0x007c,
+ 0x0d7e, 0x2069, 0x8aa2, 0x6804, 0xa084, 0x0007, 0x0079, 0x5890,
+ 0x589a, 0x5937, 0x5937, 0x5937, 0x5937, 0x5939, 0x5937, 0x5898,
+ 0x1078, 0x12d2, 0x6820, 0xa005, 0x00c0, 0x58a0, 0x0d7f, 0x007c,
+ 0x0c7e, 0x680c, 0xa065, 0x0040, 0x58af, 0x6807, 0x0004, 0x6826,
+ 0x682b, 0x0000, 0x1078, 0x597f, 0x0c7f, 0x0d7f, 0x007c, 0x6814,
+ 0xa065, 0x0040, 0x58bd, 0x6807, 0x0001, 0x6826, 0x682b, 0x0000,
+ 0x1078, 0x597f, 0x0c7f, 0x0d7f, 0x007c, 0x0e7e, 0x037e, 0x6a1c,
+ 0xa2f5, 0x0000, 0x0040, 0x5932, 0x704c, 0xa00d, 0x0040, 0x58cc,
+ 0x7088, 0xa005, 0x0040, 0x58e4, 0x7054, 0xa075, 0x0040, 0x58d5,
+ 0xa20e, 0x0040, 0x5932, 0x0078, 0x58da, 0x6818, 0xa20e, 0x0040,
+ 0x5932, 0x2070, 0x704c, 0xa00d, 0x0040, 0x58cc, 0x7088, 0xa005,
+ 0x00c0, 0x58cc, 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, 0x00c8,
+ 0x58cc, 0x1078, 0x68dd, 0x0040, 0x5932, 0x8318, 0x733e, 0x6112,
+ 0x2e10, 0x621a, 0xa180, 0x0015, 0x2004, 0xa08a, 0x199a, 0x0048,
+ 0x58fb, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316,
+ 0x037f, 0x0f7e, 0x2c78, 0x71a0, 0xd1bc, 0x0040, 0x5914, 0x7100,
+ 0xd1f4, 0x0040, 0x5910, 0x7114, 0xa18c, 0x00ff, 0x0078, 0x5919,
+ 0x2009, 0x0000, 0x0078, 0x5919, 0xa1e0, 0x25b2, 0x2c0c, 0xa18c,
+ 0x00ff, 0x2061, 0x0100, 0x619a, 0x1078, 0x5e16, 0x7300, 0xc3dd,
+ 0x7302, 0x6807, 0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, 0x781f,
+ 0x0003, 0x7803, 0x0001, 0x7807, 0x0040, 0x0f7f, 0x0e7f, 0x0c7f,
+ 0x0d7f, 0x007c, 0x037f, 0x0e7f, 0x0c7f, 0x0078, 0x5930, 0x0d7f,
+ 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, 0x5945, 0x6807, 0x0004,
+ 0x6826, 0x682b, 0x0000, 0x1078, 0x597f, 0x0c7f, 0x0d7f, 0x007c,
+ 0x0f7e, 0x0d7e, 0x2069, 0x8aa2, 0x6830, 0xa086, 0x0000, 0x00c0,
+ 0x5966, 0x6838, 0xa07d, 0x0040, 0x5966, 0x6833, 0x0001, 0x683e,
+ 0x6847, 0x0000, 0x127e, 0x0f7e, 0x2091, 0x2200, 0x027f, 0x1078,
+ 0x1b84, 0x00c0, 0x5969, 0x127f, 0x1078, 0x60fc, 0x0d7f, 0x0f7f,
+ 0x007c, 0x127f, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015,
+ 0x0040, 0x597b, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f,
+ 0x0000, 0x0078, 0x5966, 0x683a, 0x6836, 0x0078, 0x5975, 0x601c,
+ 0xa084, 0x000f, 0x1079, 0x5985, 0x007c, 0x598e, 0x5993, 0x5cc7,
+ 0x5dd3, 0x5993, 0x5cc7, 0x5dd3, 0x598e, 0x5993, 0x1078, 0x578f,
+ 0x1078, 0x5888, 0x007c, 0x157e, 0x137e, 0x147e, 0x0c7e, 0x0f7e,
+ 0x6004, 0xa08a, 0x0040, 0x10c8, 0x12d2, 0x6118, 0x2178, 0x79a0,
+ 0xd1bc, 0x0040, 0x59b0, 0x7900, 0xd1f4, 0x0040, 0x59ac, 0x7914,
+ 0xa18c, 0x00ff, 0x0078, 0x59b5, 0x2009, 0x0000, 0x0078, 0x59b5,
+ 0xa1f8, 0x25b2, 0x2f0c, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100,
+ 0x619a, 0x1079, 0x59c1, 0x0f7f, 0x0c7f, 0x147f, 0x137f, 0x157f,
+ 0x007c, 0x5a08, 0x5a40, 0x5a58, 0x5ad7, 0x5b04, 0x5b0c, 0x5b2d,
+ 0x5b3e, 0x5b4f, 0x5b57, 0x5b68, 0x5b57, 0x5bba, 0x5b3e, 0x5bdb,
+ 0x5be3, 0x5b4f, 0x5be3, 0x5bf4, 0x5a01, 0x5a01, 0x5a01, 0x5a01,
+ 0x5a01, 0x5a01, 0x5a01, 0x5a01, 0x5a01, 0x5a01, 0x5a01, 0x5a01,
+ 0x62e5, 0x62fa, 0x631d, 0x6341, 0x5b2d, 0x5a01, 0x5b2d, 0x5b57,
+ 0x5a01, 0x5a58, 0x5ad7, 0x5a01, 0x685b, 0x5b57, 0x5a01, 0x687b,
+ 0x5b57, 0x5a01, 0x5a01, 0x5a03, 0x5a01, 0x5a01, 0x5a01, 0x5a01,
+ 0x5a01, 0x5a01, 0x5a01, 0x5a01, 0x5a01, 0x5a01, 0x6356, 0x5a01,
+ 0x5a01, 0x1078, 0x12d2, 0x6030, 0x609a, 0x1078, 0x621e, 0x007c,
+ 0x20a1, 0x020b, 0x1078, 0x5c09, 0x20a3, 0x5200, 0x20a3, 0x0000,
+ 0x0d7e, 0x2069, 0x8851, 0x6804, 0xd084, 0x0040, 0x5a22, 0x6828,
+ 0x20a3, 0x0000, 0x017e, 0x1078, 0x225c, 0x21a2, 0x017f, 0x0d7f,
+ 0x0078, 0x5a27, 0x0d7f, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9,
+ 0x0004, 0x2099, 0x8805, 0x53a6, 0x20a9, 0x0004, 0x2099, 0x8801,
+ 0x53a6, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x621e, 0x007c,
+ 0x20a1, 0x020b, 0x1078, 0x5c09, 0x20a3, 0x0500, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a9, 0x0004,
+ 0x2099, 0x8805, 0x53a6, 0x60c3, 0x0010, 0x1078, 0x621e, 0x007c,
+ 0x20a1, 0x020b, 0x1078, 0x5c09, 0x7818, 0xa080, 0x0028, 0x2004,
+ 0xa086, 0x007e, 0x00c0, 0x5a6b, 0x20a3, 0x0400, 0x620c, 0xc2b4,
+ 0x620e, 0x0078, 0x5a6d, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x7818,
+ 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x5aa6, 0x2099,
+ 0x8a8c, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0xa084, 0x3fff,
+ 0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x8805, 0x53a6,
+ 0x20a9, 0x0004, 0x2099, 0x8801, 0x53a6, 0x20a9, 0x0010, 0x20a3,
+ 0x0000, 0x00f0, 0x5a97, 0x2099, 0x8a94, 0x33a6, 0x20a9, 0x0007,
+ 0x20a3, 0x0000, 0x00f0, 0x5aa0, 0x0078, 0x5ac6, 0x2099, 0x8a8c,
+ 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004, 0x2099, 0x8805, 0x53a6,
+ 0x20a9, 0x0004, 0x2099, 0x8801, 0x53a6, 0x20a9, 0x0008, 0x20a3,
+ 0x0000, 0x00f0, 0x5ab7, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0,
+ 0x5abd, 0x2099, 0x8a94, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0008,
+ 0x20a3, 0x0000, 0x00f0, 0x5ac8, 0x20a9, 0x000a, 0x20a3, 0x0000,
+ 0x00f0, 0x5ace, 0x60c3, 0x0074, 0x1078, 0x621e, 0x007c, 0x20a1,
+ 0x020b, 0x1078, 0x5c09, 0x20a3, 0x2010, 0x20a3, 0x0014, 0x20a3,
+ 0x0800, 0x20a3, 0x2000, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2,
+ 0x20a2, 0x0f7e, 0x2079, 0x8851, 0x7904, 0x0f7f, 0xd1ac, 0x00c0,
+ 0x5af3, 0xa085, 0x0020, 0xd1a4, 0x0040, 0x5af8, 0xa085, 0x0010,
+ 0xa085, 0x0002, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+ 0x0014, 0x1078, 0x621e, 0x007c, 0x20a1, 0x020b, 0x1078, 0x5c09,
+ 0x20a3, 0x5000, 0x0078, 0x5a6d, 0x20a1, 0x020b, 0x1078, 0x5c09,
+ 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x60c3, 0x0014, 0x1078, 0x621e, 0x007c, 0x20a1, 0x020b, 0x1078,
+ 0x5c87, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x60c3, 0x0004, 0x1078, 0x621e, 0x007c, 0x20a1, 0x020b,
+ 0x1078, 0x5c87, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003,
+ 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x1078, 0x621e, 0x007c, 0x20a1,
+ 0x020b, 0x1078, 0x5c87, 0x20a3, 0x0200, 0x0078, 0x5a6d, 0x20a1,
+ 0x020b, 0x1078, 0x5c87, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3,
+ 0x0003, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x621e, 0x007c,
+ 0x0d7e, 0x20a1, 0x020b, 0x1078, 0x5c87, 0x20a3, 0x0210, 0x20a3,
+ 0x0014, 0x20a3, 0x0800, 0x7818, 0x2068, 0x6894, 0xa086, 0x0014,
+ 0x00c0, 0x5b8e, 0x6998, 0xa184, 0xc000, 0x00c0, 0x5b8a, 0xd1ec,
+ 0x0040, 0x5b86, 0x20a3, 0x2100, 0x0078, 0x5b90, 0x20a3, 0x0100,
+ 0x0078, 0x5b90, 0x20a3, 0x0400, 0x0078, 0x5b90, 0x20a3, 0x0700,
+ 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079,
+ 0x8851, 0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x5ba0, 0xa085, 0x0020,
+ 0xd1a4, 0x0040, 0x5ba5, 0xa085, 0x0010, 0x2009, 0x8873, 0x210c,
+ 0xd184, 0x0040, 0x5baf, 0x699c, 0xd18c, 0x0040, 0x5bb1, 0xa085,
+ 0x0002, 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x0014, 0x1078, 0x621e,
+ 0x0d7f, 0x007c, 0x20a1, 0x020b, 0x1078, 0x5c87, 0x20a3, 0x0210,
+ 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+ 0x1078, 0x621e, 0x007c, 0x20a1, 0x020b, 0x1078, 0x5c87, 0x20a3,
+ 0x0200, 0x0078, 0x5a0e, 0x20a1, 0x020b, 0x1078, 0x5c87, 0x20a3,
+ 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3,
+ 0x0008, 0x1078, 0x621e, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000,
+ 0x20a1, 0x020b, 0x1078, 0x5c87, 0x20a3, 0x0100, 0x20a3, 0x0000,
+ 0x20a3, 0x000b, 0x20a3, 0x0000, 0x60c3, 0x0008, 0x1078, 0x621e,
+ 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080,
+ 0x0028, 0x2014, 0xa286, 0x007e, 0x00c0, 0x5c1c, 0x20a3, 0x22ff,
+ 0x20a3, 0xfffe, 0x0078, 0x5c51, 0xa286, 0x007f, 0x00c0, 0x5c27,
+ 0x0d7e, 0x20a3, 0x22ff, 0x20a3, 0xfffd, 0x0078, 0x5c3e, 0xd2bc,
+ 0x0040, 0x5c46, 0xa286, 0x0080, 0x0d7e, 0x00c0, 0x5c35, 0x20a3,
+ 0x22ff, 0x20a3, 0xfffc, 0x0078, 0x5c3e, 0xa2e8, 0x8934, 0x2d6c,
+ 0x6810, 0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x881a,
+ 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5c55, 0x0d7e, 0xa2e8,
+ 0x8934, 0x2d6c, 0x6810, 0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2,
+ 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0129, 0x20a3,
+ 0x0000, 0x1078, 0x620d, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3,
0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x027e,
0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, 0x2011, 0xfffc,
- 0x22a2, 0x0d7e, 0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
- 0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078, 0x5141, 0x20a3, 0x0100,
+ 0x22a2, 0x0d7e, 0x2069, 0x881a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
+ 0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078, 0x5c59, 0x20a3, 0x0100,
0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x007c, 0x027e,
0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
- 0xa092, 0x007e, 0x0048, 0x518e, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c,
- 0x6810, 0xa085, 0x2300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719,
- 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5196, 0x20a3, 0x2300,
- 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0198,
- 0x20a3, 0x0000, 0x1078, 0x5677, 0x22a2, 0x20a3, 0x0000, 0x7a08,
- 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c,
- 0x0c7e, 0x0f7e, 0x6004, 0xa08a, 0x0085, 0x1048, 0x12cd, 0xa08a,
- 0x008c, 0x10c8, 0x12cd, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040,
- 0x51c6, 0x7900, 0xd1f4, 0x0040, 0x51c2, 0x7914, 0xa18c, 0x00ff,
- 0x0078, 0x51cb, 0x2009, 0x0000, 0x0078, 0x51cb, 0xa1f8, 0x2329,
- 0x2f0c, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082,
- 0x0085, 0x1079, 0x51d6, 0x0f7f, 0x0c7f, 0x007c, 0x51df, 0x51ea,
- 0x5204, 0x51dd, 0x51dd, 0x51dd, 0x51df, 0x1078, 0x12cd, 0x147e,
- 0x20a1, 0x020b, 0x1078, 0x5217, 0x60c3, 0x0000, 0x1078, 0x5688,
- 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, 0x5244, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x2fa2, 0x20a3, 0x0000,
+ 0xa092, 0x007e, 0x0048, 0x5ca6, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c,
+ 0x6810, 0xa085, 0x2300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x881a,
+ 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5cb5, 0x0d7e, 0xa0e8,
+ 0x8934, 0x2d6c, 0x6810, 0xa085, 0x2300, 0x20a2, 0x6814, 0x20a2,
+ 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0198, 0x20a3,
+ 0x0000, 0x1078, 0x620d, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2,
+ 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0c7e,
+ 0x0f7e, 0x6004, 0xa08a, 0x0085, 0x1048, 0x12d2, 0xa08a, 0x008c,
+ 0x10c8, 0x12d2, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, 0x5ce5,
+ 0x7900, 0xd1f4, 0x0040, 0x5ce1, 0x7914, 0xa18c, 0x00ff, 0x0078,
+ 0x5cea, 0x2009, 0x0000, 0x0078, 0x5cea, 0xa1f8, 0x25b2, 0x2f0c,
+ 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082, 0x0085,
+ 0x1079, 0x5cf5, 0x0f7f, 0x0c7f, 0x007c, 0x5cfe, 0x5d09, 0x5d24,
+ 0x5cfc, 0x5cfc, 0x5cfc, 0x5cfe, 0x1078, 0x12d2, 0x147e, 0x20a1,
+ 0x020b, 0x1078, 0x5d37, 0x60c3, 0x0000, 0x1078, 0x621e, 0x147f,
+ 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, 0x5d6b, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000,
0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
- 0x1078, 0x5688, 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078,
- 0x5271, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3,
- 0x0000, 0x60c3, 0x0004, 0x1078, 0x5688, 0x147f, 0x007c, 0x027e,
+ 0x1078, 0x621e, 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078,
+ 0x5d9f, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x60c3, 0x0004, 0x1078, 0x621e, 0x147f, 0x007c, 0x027e,
0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
- 0xa092, 0x007e, 0x0048, 0x5236, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c,
- 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719,
- 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x523e, 0x20a3, 0x8100,
- 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0009,
- 0x20a3, 0x0000, 0x0078, 0x5141, 0x027e, 0x20e1, 0x9080, 0x20e1,
- 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048,
- 0x5263, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c, 0x6810, 0xa085, 0x8400,
- 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6,
- 0x0d7f, 0x0078, 0x526b, 0x20a3, 0x8400, 0x6298, 0x22a2, 0x20a3,
- 0x0000, 0x6230, 0x22a2, 0x20a3, 0x00d1, 0x20a3, 0x0000, 0x0078,
- 0x519a, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080,
- 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x5290, 0x0d7e, 0xa0e8,
- 0x7820, 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2,
- 0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5298,
- 0x20a3, 0x8500, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2,
- 0x20a3, 0x00d1, 0x20a3, 0x0000, 0x0078, 0x519a, 0x0c7e, 0x0f7e,
- 0x2c78, 0x7804, 0xa08a, 0x0040, 0x1048, 0x12cd, 0xa08a, 0x0050,
- 0x10c8, 0x12cd, 0x7918, 0x2160, 0x61a0, 0xd1bc, 0x0040, 0x52bd,
- 0x6100, 0xd1f4, 0x0040, 0x52b9, 0x6114, 0xa18c, 0x00ff, 0x0078,
- 0x52c2, 0x2009, 0x0000, 0x0078, 0x52c2, 0xa1e0, 0x2329, 0x2c0c,
- 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0xa082, 0x0040, 0x1079,
- 0x52cc, 0x0f7f, 0x0c7f, 0x007c, 0x52de, 0x53c4, 0x536c, 0x54ec,
- 0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x52dc, 0x5933,
- 0x5944, 0x5955, 0x5966, 0x52dc, 0x1078, 0x12cd, 0x0d7e, 0x157e,
- 0x147e, 0x20a1, 0x020b, 0x1078, 0x532f, 0x7910, 0x2168, 0x6948,
- 0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184, 0x0006,
- 0x8004, 0x20a2, 0xd1ac, 0x0040, 0x52f9, 0x20a3, 0x0002, 0x0078,
- 0x5305, 0xd1b4, 0x0040, 0x5300, 0x20a3, 0x0001, 0x0078, 0x5305,
- 0x20a3, 0x0000, 0x2230, 0x0078, 0x5307, 0x6a80, 0x6e7c, 0x20a9,
+ 0xa092, 0x007e, 0x0048, 0x5d56, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c,
+ 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x881a,
+ 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5d65, 0x0d7e, 0xa0e8,
+ 0x8934, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2,
+ 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0009, 0x20a3,
+ 0x0000, 0x0078, 0x5c59, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000,
+ 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x5d8a,
+ 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2,
+ 0x6814, 0x20a2, 0x2069, 0x881a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
+ 0x0078, 0x5d99, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085,
+ 0x8400, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230,
+ 0x22a2, 0x20a3, 0x00d1, 0x20a3, 0x0000, 0x0078, 0x5cb9, 0x027e,
+ 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+ 0xa092, 0x007e, 0x0048, 0x5dbe, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c,
+ 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x881a,
+ 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5dcd, 0x0d7e, 0xa0e8,
+ 0x8934, 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2,
+ 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x00d1, 0x20a3,
+ 0x0000, 0x0078, 0x5cb9, 0x0c7e, 0x0f7e, 0x2c78, 0x7804, 0xa08a,
+ 0x0040, 0x1048, 0x12d2, 0xa08a, 0x0053, 0x10c8, 0x12d2, 0x7918,
+ 0x2160, 0x61a0, 0xd1bc, 0x0040, 0x5df2, 0x6100, 0xd1f4, 0x0040,
+ 0x5dee, 0x6114, 0xa18c, 0x00ff, 0x0078, 0x5df7, 0x2009, 0x0000,
+ 0x0078, 0x5df7, 0xa1e0, 0x25b2, 0x2c0c, 0xa18c, 0x00ff, 0x2061,
+ 0x0100, 0x619a, 0xa082, 0x0040, 0x1079, 0x5e01, 0x0f7f, 0x0c7f,
+ 0x007c, 0x5e16, 0x5f1a, 0x5ebb, 0x6070, 0x5e14, 0x5e14, 0x5e14,
+ 0x5e14, 0x5e14, 0x5e14, 0x5e14, 0x651a, 0x652b, 0x653c, 0x654d,
+ 0x5e14, 0x5e14, 0x5e14, 0x6509, 0x1078, 0x12d2, 0x0d7e, 0x157e,
+ 0x147e, 0x20a1, 0x020b, 0x1078, 0x5e77, 0x7910, 0x2168, 0x6948,
+ 0x7922, 0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184,
+ 0x000f, 0x00c0, 0x5e2f, 0x2001, 0x0005, 0x0078, 0x5e39, 0xd184,
+ 0x0040, 0x5e36, 0x2001, 0x0004, 0x0078, 0x5e39, 0xa084, 0x0006,
+ 0x8004, 0x20a2, 0xd1ac, 0x0040, 0x5e41, 0x20a3, 0x0002, 0x0078,
+ 0x5e4d, 0xd1b4, 0x0040, 0x5e48, 0x20a3, 0x0001, 0x0078, 0x5e4d,
+ 0x20a3, 0x0000, 0x2230, 0x0078, 0x5e4f, 0x6a80, 0x6e7c, 0x20a9,
0x0008, 0xad80, 0x0017, 0x200c, 0x810f, 0x21a2, 0x8000, 0x00f0,
- 0x530b, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, 0x6014,
- 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0x7952, 0x2003,
- 0x07d0, 0x2001, 0x7951, 0x2003, 0x0009, 0x2001, 0x7957, 0x2003,
- 0x0002, 0x1078, 0x14fc, 0x147f, 0x157f, 0x0d7f, 0x007c, 0x20e1,
+ 0x5e53, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, 0x6014,
+ 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0x8abe, 0x2003,
+ 0x07d0, 0x2001, 0x8abd, 0x2003, 0x0009, 0x2001, 0x8ac3, 0x2003,
+ 0x0002, 0x1078, 0x1526, 0x147f, 0x157f, 0x0d7f, 0x007c, 0x20e1,
0x9080, 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210,
0xa294, 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004,
- 0xd0bc, 0x0040, 0x5355, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c, 0x6810,
- 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6,
- 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x535d, 0x20a3, 0x0600, 0x6198,
- 0x21a2, 0x20a3, 0x0000, 0x6130, 0x21a2, 0x20a3, 0x0829, 0x20a3,
- 0x0000, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e,
- 0x20a1, 0x020b, 0x1078, 0x538c, 0x7810, 0x2068, 0x6860, 0x20a2,
- 0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2,
- 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c, 0x1078, 0x5688, 0x147f,
- 0x137f, 0x157f, 0x0d7f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1,
- 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x53aa,
- 0x0d7e, 0xa0e8, 0x7820, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2,
- 0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
- 0x0078, 0x53b2, 0x20a3, 0x0500, 0x6298, 0x22a2, 0x20a3, 0x0000,
- 0x6230, 0x22a2, 0x20a3, 0x0889, 0x20a3, 0x0000, 0x1078, 0x5677,
- 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000,
- 0x20a3, 0x0000, 0x027f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e,
- 0x20a1, 0x020b, 0x1078, 0x54b4, 0x7810, 0x2068, 0xa016, 0x22a2,
- 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810, 0xa084, 0xf000, 0x00c0,
- 0x53e1, 0x7810, 0xa084, 0x0700, 0x8007, 0x1079, 0x53e9, 0x0078,
- 0x53e4, 0xa006, 0x1079, 0x53e9, 0x147f, 0x137f, 0x157f, 0x0d7f,
- 0x007c, 0x53f3, 0x5455, 0x5459, 0x547c, 0x5489, 0x549b, 0x549f,
- 0x53f1, 0x1078, 0x12cd, 0x017e, 0x037e, 0x694c, 0xa18c, 0x0003,
- 0xa186, 0x0000, 0x00c0, 0x5406, 0x6b78, 0x23a2, 0x6868, 0x20a2,
- 0x6864, 0x20a2, 0x037f, 0x017f, 0x0078, 0x5480, 0xa186, 0x0001,
- 0x00c0, 0x5450, 0x6b78, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2,
+ 0xd0bc, 0x0040, 0x5e9d, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, 0x6810,
+ 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x881a, 0x2da6,
+ 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x5eac, 0x0d7e, 0xa0e8, 0x8934,
+ 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x0d7f,
+ 0x20a3, 0x0000, 0x6130, 0x21a2, 0x20a3, 0x0829, 0x20a3, 0x0000,
+ 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x20a1,
+ 0x020b, 0x1078, 0x5edb, 0x7810, 0x2068, 0x6860, 0x20a2, 0x685c,
+ 0x20a2, 0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2, 0x20a2,
+ 0x20a2, 0x20a2, 0x60c3, 0x000c, 0x1078, 0x621e, 0x147f, 0x137f,
+ 0x157f, 0x0d7f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000,
+ 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x5ef9, 0x0d7e,
+ 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814,
+ 0x20a2, 0x2069, 0x881a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078,
+ 0x5f08, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, 0x0500,
+ 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2,
+ 0x20a3, 0x0889, 0x20a3, 0x0000, 0x1078, 0x620d, 0x22a2, 0x20a3,
+ 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x027f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x20a1, 0x020b,
+ 0x1078, 0x6031, 0x7810, 0x2068, 0xa016, 0x22a2, 0x22a2, 0x22a2,
+ 0x22a2, 0x22a2, 0x7810, 0xa084, 0xf000, 0x00c0, 0x5f37, 0x7810,
+ 0xa084, 0x0700, 0x8007, 0x1079, 0x5f3f, 0x0078, 0x5f3a, 0xa006,
+ 0x1079, 0x5f3f, 0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c, 0x5f49,
+ 0x5fcf, 0x5fd3, 0x5ff6, 0x6003, 0x6018, 0x601c, 0x5f47, 0x1078,
+ 0x12d2, 0x017e, 0x037e, 0x694c, 0xa18c, 0x0003, 0x0040, 0x5f54,
+ 0xa186, 0x0003, 0x00c0, 0x5f5e, 0x6b78, 0x23a2, 0x6868, 0x20a2,
+ 0x6864, 0x20a2, 0x037f, 0x017f, 0x0078, 0x5ffa, 0xa186, 0x0001,
+ 0x10c0, 0x12d2, 0x6b78, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2,
0x22a2, 0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018,
- 0xa384, 0x0300, 0x0040, 0x544f, 0xd3c4, 0x0040, 0x5421, 0x687c,
- 0xa108, 0xd3cc, 0x0040, 0x5426, 0x6874, 0xa108, 0x157e, 0x20a9,
+ 0xa384, 0x0300, 0x0040, 0x5fc9, 0xd3c4, 0x0040, 0x5f79, 0x687c,
+ 0xa108, 0xd3cc, 0x0040, 0x5f7e, 0x6874, 0xa108, 0x157e, 0x20a9,
0x000d, 0xad80, 0x0020, 0x201c, 0x831f, 0x23a2, 0x8000, 0x00f0,
- 0x542b, 0x157f, 0x22a2, 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0040,
- 0x544f, 0x20a1, 0x020b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3,
- 0x0700, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3,
- 0x0898, 0x20a2, 0x1078, 0x5677, 0x22a2, 0x20a3, 0x0000, 0x61c2,
- 0x037f, 0x017f, 0x1078, 0x5688, 0x007c, 0x20a3, 0x0008, 0x0078,
- 0x547e, 0x20a3, 0x0302, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012,
- 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3,
- 0x7000, 0x20a3, 0x0500, 0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2,
- 0x20a3, 0x2500, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3,
- 0x0032, 0x1078, 0x5688, 0x007c, 0x20a3, 0x0028, 0x22a2, 0x22a2,
- 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0018, 0x1078, 0x5688,
- 0x007c, 0x20a3, 0x0100, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
- 0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0020,
- 0x1078, 0x5688, 0x007c, 0x20a3, 0x0008, 0x0078, 0x547e, 0x037e,
- 0x7b10, 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001, 0x00c0,
- 0x54ad, 0x22a2, 0x037f, 0x0078, 0x547e, 0x20a3, 0x0800, 0x22a2,
- 0x20a2, 0x037f, 0x0078, 0x5480, 0x027e, 0x20e1, 0x9080, 0x20e1,
- 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x54d2,
- 0x0d7e, 0xa0e8, 0x7820, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
- 0x6814, 0x20a2, 0x2069, 0x7719, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
- 0x0078, 0x54da, 0x20a3, 0x0700, 0x6298, 0x22a2, 0x20a3, 0x0000,
- 0x6230, 0x22a2, 0x20a3, 0x0898, 0x20a3, 0x0000, 0x1078, 0x5677,
+ 0x5f83, 0x157f, 0x22a2, 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0040,
+ 0x5fc9, 0x20a1, 0x020b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x007e,
+ 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x5fb1, 0x0d7e,
+ 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814,
+ 0x20a2, 0x2069, 0x881a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078,
+ 0x5fc0, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, 0x0700,
+ 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2,
+ 0x007f, 0x20a3, 0x0898, 0x20a2, 0x1078, 0x620d, 0x22a2, 0x20a3,
+ 0x0000, 0x61c2, 0x037f, 0x017f, 0x1078, 0x621e, 0x007c, 0x20a3,
+ 0x0008, 0x0078, 0x5ff8, 0x20a3, 0x0302, 0x22a2, 0x22a2, 0x22a2,
+ 0x20a3, 0x0012, 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2,
+ 0x22a2, 0x20a3, 0x7000, 0x20a3, 0x0500, 0x22a2, 0x20a3, 0x000a,
+ 0x22a2, 0x22a2, 0x20a3, 0x2500, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
+ 0x22a2, 0x60c3, 0x0032, 0x1078, 0x621e, 0x007c, 0x20a3, 0x0028,
+ 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0018,
+ 0x1078, 0x621e, 0x007c, 0x20a3, 0x0100, 0x22a2, 0x22a2, 0x22a2,
+ 0x22a2, 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x7824, 0xa084, 0x00ff,
+ 0x20a2, 0x22a2, 0x22a2, 0x60c3, 0x0020, 0x1078, 0x621e, 0x007c,
+ 0x20a3, 0x0008, 0x0078, 0x5ff8, 0x037e, 0x7b10, 0xa384, 0xff00,
+ 0x7812, 0xa384, 0x00ff, 0x8001, 0x00c0, 0x602a, 0x22a2, 0x037f,
+ 0x0078, 0x5ff8, 0x20a3, 0x0800, 0x22a2, 0x20a2, 0x037f, 0x0078,
+ 0x5ffa, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080,
+ 0x0028, 0x2004, 0xd0bc, 0x0040, 0x604f, 0x0d7e, 0xa0e8, 0x8934,
+ 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069,
+ 0x881a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x605e, 0x0d7e,
+ 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814,
+ 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0898,
+ 0x20a3, 0x0000, 0x1078, 0x620d, 0x22a2, 0x20a3, 0x0000, 0x7a08,
+ 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c,
+ 0x0d7e, 0x157e, 0x137e, 0x147e, 0x017e, 0x037e, 0x7810, 0xa084,
+ 0x0700, 0x8007, 0x1079, 0x6083, 0x037f, 0x017f, 0x147f, 0x137f,
+ 0x157f, 0x0d7f, 0x007c, 0x608b, 0x608b, 0x608d, 0x608b, 0x608b,
+ 0x608b, 0x60b2, 0x608b, 0x1078, 0x12d2, 0x7910, 0xa18c, 0xf8ff,
+ 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078,
+ 0x60bc, 0x0d7e, 0x2069, 0x8851, 0x6804, 0xd0bc, 0x0040, 0x60a7,
+ 0x682c, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0078, 0x60a9, 0x20a3,
+ 0x3f00, 0x0d7f, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x1078,
+ 0x621e, 0x007c, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078, 0x60bc,
+ 0x20a3, 0x7f00, 0x0078, 0x60aa, 0x027e, 0x20e1, 0x9080, 0x20e1,
+ 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x60da,
+ 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2,
+ 0x6814, 0x20a2, 0x2069, 0x881a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
+ 0x0078, 0x60e9, 0x0d7e, 0xa0e8, 0x8934, 0x2d6c, 0x6810, 0xa085,
+ 0x0100, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230,
+ 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x1078, 0x620d,
0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000,
- 0x20a3, 0x0000, 0x027f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e,
- 0x017e, 0x037e, 0x7810, 0xa084, 0x0700, 0x8007, 0x1079, 0x54ff,
- 0x037f, 0x017f, 0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c, 0x5507,
- 0x5507, 0x5509, 0x5507, 0x5507, 0x5507, 0x552e, 0x5507, 0x1078,
- 0x12cd, 0x7910, 0xa18c, 0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1,
- 0x020b, 0x2009, 0x0003, 0x1078, 0x5538, 0x0d7e, 0x2069, 0x7751,
- 0x6804, 0xd0bc, 0x0040, 0x5523, 0x682c, 0xa084, 0x00ff, 0x8007,
- 0x20a2, 0x0078, 0x5525, 0x20a3, 0x3f00, 0x0d7f, 0x22a2, 0x22a2,
- 0x22a2, 0x60c3, 0x0001, 0x1078, 0x5688, 0x007c, 0x20a1, 0x020b,
- 0x2009, 0x0003, 0x1078, 0x5538, 0x20a3, 0x7f00, 0x0078, 0x5526,
- 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
- 0x2004, 0xd0bc, 0x0040, 0x5556, 0x0d7e, 0xa0e8, 0x7820, 0x2d6c,
- 0x6810, 0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x7719,
- 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x555e, 0x20a3, 0x0100,
- 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0888,
- 0xa18d, 0x0008, 0x21a2, 0x1078, 0x5677, 0x22a2, 0x20a3, 0x0000,
- 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f,
- 0x007c, 0x0e7e, 0x0d7e, 0x0c7e, 0x057e, 0x047e, 0x037e, 0x2061,
- 0x0100, 0x2071, 0x7700, 0x6130, 0x7818, 0x2068, 0x68a0, 0x2028,
- 0xd0bc, 0x00c0, 0x558a, 0xa080, 0x2329, 0x2014, 0xa294, 0x00ff,
- 0x0078, 0x558e, 0x6910, 0x6a14, 0x7364, 0x7468, 0x781c, 0xa086,
- 0x0006, 0x0040, 0x55e2, 0xd5bc, 0x0040, 0x559e, 0xa185, 0x0100,
- 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x55a4, 0x6063, 0x0100,
- 0x6266, 0x606b, 0x0000, 0x616e, 0x6073, 0x0809, 0x6077, 0x0008,
- 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f,
- 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7810, 0x2070, 0x7014,
- 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c,
- 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582,
- 0x0080, 0x0048, 0x55d6, 0x6a00, 0xd2f4, 0x0040, 0x55d4, 0x6a14,
- 0xa294, 0x00ff, 0x0078, 0x55d6, 0x2011, 0x0000, 0x629e, 0x6017,
- 0x0016, 0x1078, 0x470b, 0x037f, 0x047f, 0x057f, 0x0c7f, 0x0d7f,
- 0x0e7f, 0x007c, 0x7810, 0x2070, 0x704c, 0xa084, 0x0003, 0xa086,
- 0x0002, 0x0040, 0x5631, 0xd5bc, 0x0040, 0x55f6, 0xa185, 0x0100,
- 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x55fc, 0x6063, 0x0100,
- 0x6266, 0x606b, 0x0000, 0x616e, 0x6073, 0x0880, 0x6077, 0x0008,
- 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f,
- 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, 0x7060, 0x608a, 0x705c,
- 0x608e, 0x7080, 0x60c6, 0x707c, 0x60ca, 0x686c, 0x60ce, 0x60ab,
- 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048,
- 0x562c, 0x6a00, 0xd2f4, 0x0040, 0x562a, 0x6a14, 0xa294, 0x00ff,
- 0x0078, 0x562c, 0x2011, 0x0000, 0x629e, 0x6017, 0x0012, 0x0078,
- 0x55d9, 0xd5bc, 0x0040, 0x563c, 0xa185, 0x0700, 0x6062, 0x6266,
- 0x636a, 0x646e, 0x0078, 0x5642, 0x6063, 0x0700, 0x6266, 0x606b,
- 0x0000, 0x616e, 0x6073, 0x0898, 0x6077, 0x0000, 0x688c, 0x8000,
- 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00,
- 0x6086, 0x7808, 0x6082, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c,
- 0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af,
- 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x5672, 0x6a00,
- 0xd2f4, 0x0040, 0x5670, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x5672,
- 0x2011, 0x0000, 0x629e, 0x6017, 0x0016, 0x0078, 0x55d9, 0x7a18,
- 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217,
- 0x007c, 0x0d7e, 0x2069, 0x7936, 0x6843, 0x0001, 0x0d7f, 0x007c,
- 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x1078, 0x5693,
- 0x1078, 0x46fb, 0x007c, 0x007e, 0x6014, 0xa084, 0x0004, 0xa085,
- 0x0009, 0x6016, 0x007f, 0x007c, 0x007e, 0x0c7e, 0x2061, 0x0100,
- 0x6014, 0xa084, 0x0004, 0xa085, 0x0008, 0x6016, 0x0c7f, 0x007f,
- 0x007c, 0x0c7e, 0x0d7e, 0x017e, 0x027e, 0x1078, 0x4706, 0x2061,
- 0x0100, 0x2069, 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x56e6,
- 0x1078, 0x569c, 0x6803, 0x1000, 0x6803, 0x0000, 0x0c7e, 0x2061,
- 0x7936, 0x6128, 0xa192, 0x0002, 0x00c8, 0x56d3, 0x8108, 0x612a,
- 0x6124, 0x0c7f, 0x81ff, 0x0040, 0x56e1, 0x1078, 0x46fb, 0x1078,
- 0x5693, 0x0078, 0x56e1, 0x6124, 0xa1e5, 0x0000, 0x0040, 0x56de,
- 0x1078, 0x76c7, 0x2009, 0x0014, 0x1078, 0x5d41, 0x0c7f, 0x0078,
- 0x56e1, 0x027f, 0x017f, 0x0d7f, 0x0c7f, 0x007c, 0x1078, 0x3591,
- 0x0078, 0x56e1, 0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x027e, 0x1078,
- 0x4714, 0x2071, 0x7936, 0x713c, 0x81ff, 0x0040, 0x5714, 0x2061,
- 0x0100, 0x2069, 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x571a,
- 0x6803, 0x1000, 0x6803, 0x0000, 0x037e, 0x2019, 0x0001, 0x1078,
- 0x5880, 0x037f, 0x713c, 0x2160, 0x1078, 0x76c7, 0x2009, 0x004a,
- 0x1078, 0x5d41, 0x0078, 0x5714, 0x027f, 0x017f, 0x0e7f, 0x0d7f,
- 0x0c7f, 0x007c, 0x7144, 0xa192, 0x0002, 0x00c8, 0x5704, 0x8108,
- 0x7146, 0x1078, 0x470b, 0x0078, 0x5714, 0x0e7e, 0x0d7e, 0x0c7e,
- 0x067e, 0x057e, 0x047e, 0x007e, 0x127e, 0x2091, 0x8000, 0x6018,
- 0x2068, 0x6ca0, 0x2071, 0x7936, 0x7018, 0x2068, 0x8dff, 0x0040,
- 0x574f, 0x68a0, 0xa406, 0x0040, 0x5741, 0x6854, 0x2068, 0x0078,
- 0x5736, 0x6010, 0x2060, 0x643c, 0x6540, 0x6e48, 0x2d60, 0x1078,
- 0x3991, 0x0040, 0x574f, 0x1078, 0x5a1a, 0xa085, 0x0001, 0x127f,
- 0x007f, 0x047f, 0x057f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c,
- 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x50f8, 0x20a3, 0x0f00,
- 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x60c3, 0x0008,
- 0x1078, 0x5688, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1,
- 0x020b, 0x1078, 0x516f, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a9,
- 0x0006, 0x2011, 0x7740, 0x2019, 0x7741, 0x23a6, 0x22a6, 0xa398,
- 0x0002, 0xa290, 0x0002, 0x00f0, 0x577d, 0x20a3, 0x0000, 0x20a3,
- 0x0000, 0x60c3, 0x001c, 0x1078, 0x5688, 0x147f, 0x157f, 0x007c,
- 0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b, 0x1078, 0x514f,
- 0x1078, 0x5166, 0x7810, 0x007e, 0xa080, 0x0015, 0x2098, 0x7808,
- 0xa088, 0x0002, 0x21a8, 0x53a6, 0xa080, 0x0004, 0x8003, 0x60c2,
- 0x007f, 0xa080, 0x0001, 0x2004, 0x7812, 0x1078, 0x5688, 0x027f,
- 0x017f, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b,
- 0x1078, 0x50f8, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000,
- 0x7808, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x5688, 0x147f, 0x157f,
- 0x007c, 0x0e7e, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071,
- 0x7936, 0x700c, 0x2060, 0x8cff, 0x0040, 0x57e5, 0x1078, 0x6be3,
- 0x00c0, 0x57dc, 0x1078, 0x5f6d, 0x600c, 0x007e, 0x1078, 0x5d1a,
- 0x1078, 0x5a1a, 0x0c7f, 0x0078, 0x57d3, 0x700f, 0x0000, 0x700b,
- 0x0000, 0x127f, 0x007f, 0x0c7f, 0x0e7f, 0x007c, 0x127e, 0x157e,
- 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x027e, 0x017e, 0x007e, 0x2091,
- 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x7936, 0x7024,
- 0x2060, 0x8cff, 0x0040, 0x583e, 0x1078, 0x569c, 0x68c3, 0x0000,
- 0x1078, 0x4706, 0x2009, 0x0013, 0x1078, 0x5d41, 0x20a9, 0x01f4,
- 0x6824, 0xd094, 0x0040, 0x5821, 0x6827, 0x0004, 0x7804, 0xa084,
- 0x4000, 0x0040, 0x5833, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078,
- 0x5833, 0xd084, 0x0040, 0x5828, 0x6827, 0x0001, 0x0078, 0x582a,
- 0x00f0, 0x5810, 0x7804, 0xa084, 0x1000, 0x0040, 0x5833, 0x7803,
+ 0x20a3, 0x0000, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x0c7e, 0x057e,
+ 0x047e, 0x037e, 0x2061, 0x0100, 0x2071, 0x8800, 0x6130, 0x7818,
+ 0x2068, 0x68a0, 0x2028, 0xd0bc, 0x00c0, 0x6113, 0x6910, 0x6a14,
+ 0x6430, 0x0078, 0x6117, 0x6910, 0x6a14, 0x7368, 0x746c, 0x781c,
+ 0xa086, 0x0006, 0x0040, 0x6176, 0xd5bc, 0x0040, 0x6127, 0xa185,
+ 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x612e, 0xa185,
+ 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x6073, 0x0809,
+ 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007,
+ 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7810,
+ 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008,
+ 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7,
+ 0x0000, 0xa582, 0x0080, 0x0048, 0x6160, 0x6a00, 0xd2f4, 0x0040,
+ 0x615e, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6160, 0x2011, 0x0000,
+ 0x629e, 0x6017, 0x0016, 0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0,
+ 0xa005, 0x0040, 0x616d, 0x2009, 0x1b58, 0x1078, 0x5174, 0x037f,
+ 0x047f, 0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7810, 0x2070,
+ 0x704c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x61c6, 0xd5bc,
+ 0x0040, 0x618a, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e,
+ 0x0078, 0x6191, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000,
+ 0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084,
+ 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086,
+ 0x7808, 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6,
+ 0x707c, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5,
+ 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x61c1, 0x6a00, 0xd2f4,
+ 0x0040, 0x61bf, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x61c1, 0x2011,
+ 0x0000, 0x629e, 0x6017, 0x0012, 0x0078, 0x6163, 0xd5bc, 0x0040,
+ 0x61d1, 0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078,
+ 0x61d8, 0xa185, 0x0700, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e,
+ 0x6073, 0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff,
+ 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808,
+ 0x6082, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008,
+ 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7,
+ 0x0000, 0xa582, 0x0080, 0x0048, 0x6208, 0x6a00, 0xd2f4, 0x0040,
+ 0x6206, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6208, 0x2011, 0x0000,
+ 0x629e, 0x6017, 0x0016, 0x0078, 0x6163, 0x7a18, 0xa280, 0x0023,
+ 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, 0x007c, 0x0d7e,
+ 0x2069, 0x8aa2, 0x6843, 0x0001, 0x0d7f, 0x007c, 0x20e1, 0x9080,
+ 0x60a3, 0x0056, 0x60a7, 0x9575, 0x1078, 0x6229, 0x1078, 0x5164,
+ 0x007c, 0x007e, 0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016,
+ 0x007f, 0x007c, 0x007e, 0x0c7e, 0x2061, 0x0100, 0x6014, 0xa084,
+ 0x0004, 0xa085, 0x0008, 0x6016, 0x0c7f, 0x007f, 0x007c, 0x0c7e,
+ 0x0d7e, 0x017e, 0x027e, 0x1078, 0x516f, 0x2061, 0x0100, 0x2069,
+ 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x627c, 0x1078, 0x6232,
+ 0x6803, 0x1000, 0x6803, 0x0000, 0x0c7e, 0x2061, 0x8aa2, 0x6128,
+ 0xa192, 0x0002, 0x00c8, 0x6269, 0x8108, 0x612a, 0x6124, 0x0c7f,
+ 0x81ff, 0x0040, 0x6277, 0x1078, 0x5164, 0x1078, 0x6229, 0x0078,
+ 0x6277, 0x6124, 0xa1e5, 0x0000, 0x0040, 0x6274, 0x1078, 0x8781,
+ 0x2009, 0x0014, 0x1078, 0x6939, 0x0c7f, 0x0078, 0x6277, 0x027f,
+ 0x017f, 0x0d7f, 0x0c7f, 0x007c, 0x1078, 0x3c73, 0x0078, 0x6277,
+ 0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x027e, 0x1078, 0x517c, 0x2071,
+ 0x8aa2, 0x713c, 0x81ff, 0x0040, 0x62aa, 0x2061, 0x0100, 0x2069,
+ 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x62b0, 0x6803, 0x1000,
+ 0x6803, 0x0000, 0x037e, 0x2019, 0x0001, 0x1078, 0x642d, 0x037f,
+ 0x713c, 0x2160, 0x1078, 0x8781, 0x2009, 0x004a, 0x1078, 0x6939,
+ 0x0078, 0x62aa, 0x027f, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c,
+ 0x0078, 0x629a, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x057e, 0x047e,
+ 0x007e, 0x127e, 0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0, 0x2071,
+ 0x8aa2, 0x7018, 0x2068, 0x8dff, 0x0040, 0x62dc, 0x68a0, 0xa406,
+ 0x0040, 0x62ce, 0x6854, 0x2068, 0x0078, 0x62c3, 0x6010, 0x2060,
+ 0x643c, 0x6540, 0x6e48, 0x2d60, 0x1078, 0x40da, 0x0040, 0x62dc,
+ 0x1078, 0x6601, 0xa085, 0x0001, 0x127f, 0x007f, 0x047f, 0x057f,
+ 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x157e, 0x147e, 0x20a1,
+ 0x020b, 0x1078, 0x5c09, 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x7808, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x621e, 0x147f,
+ 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x5c87,
+ 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a9, 0x0006, 0x2011, 0x8840,
+ 0x2019, 0x8841, 0x23a6, 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002,
+ 0x00f0, 0x630a, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c,
+ 0x1078, 0x621e, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x017e,
+ 0x027e, 0x20a1, 0x020b, 0x1078, 0x5c67, 0x1078, 0x5c7e, 0x7810,
+ 0x007e, 0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8,
+ 0x53a6, 0xa080, 0x0004, 0x8003, 0x60c2, 0x007f, 0xa080, 0x0001,
+ 0x2004, 0x7812, 0x1078, 0x621e, 0x027f, 0x017f, 0x147f, 0x157f,
+ 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x5c09, 0x20a3,
+ 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x60c3,
+ 0x0008, 0x1078, 0x621e, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e,
+ 0x017e, 0x027e, 0x20a1, 0x020b, 0x1078, 0x5c09, 0x7810, 0x007e,
+ 0xa080, 0x0017, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6,
+ 0x8003, 0x60c2, 0x007f, 0xa080, 0x0001, 0x2004, 0x7812, 0x1078,
+ 0x621e, 0x027f, 0x017f, 0x147f, 0x157f, 0x007c, 0x0e7e, 0x0c7e,
+ 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x8aa2, 0x700c, 0x2060,
+ 0x8cff, 0x0040, 0x6392, 0x1078, 0x79d5, 0x00c0, 0x6389, 0x1078,
+ 0x6bc7, 0x600c, 0x007e, 0x1078, 0x690e, 0x1078, 0x6601, 0x0c7f,
+ 0x0078, 0x6380, 0x700f, 0x0000, 0x700b, 0x0000, 0x127f, 0x007f,
+ 0x0c7f, 0x0e7f, 0x007c, 0x127e, 0x157e, 0x0f7e, 0x0e7e, 0x0d7e,
+ 0x0c7e, 0x027e, 0x017e, 0x007e, 0x2091, 0x8000, 0x2069, 0x0100,
+ 0x2079, 0x0140, 0x2071, 0x8aa2, 0x7024, 0x2060, 0x8cff, 0x0040,
+ 0x63eb, 0x1078, 0x6232, 0x68c3, 0x0000, 0x1078, 0x516f, 0x2009,
+ 0x0013, 0x1078, 0x6939, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040,
+ 0x63ce, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x63e0,
+ 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0x63e0, 0xd084, 0x0040,
+ 0x63d5, 0x6827, 0x0001, 0x0078, 0x63d7, 0x00f0, 0x63bd, 0x7804,
+ 0xa084, 0x1000, 0x0040, 0x63e0, 0x7803, 0x0100, 0x7803, 0x0000,
+ 0x6824, 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
+ 0x157f, 0x127f, 0x007c, 0x2001, 0x8800, 0x2004, 0xa096, 0x0001,
+ 0x0040, 0x6423, 0xa096, 0x0004, 0x0040, 0x6423, 0x6817, 0x0008,
+ 0x68c3, 0x0000, 0x2011, 0x3c35, 0x1078, 0x50f2, 0x20a9, 0x01f4,
+ 0x6824, 0xd094, 0x0040, 0x6411, 0x6827, 0x0004, 0x7804, 0xa084,
+ 0x4000, 0x0040, 0x6423, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078,
+ 0x6423, 0xd084, 0x0040, 0x6418, 0x6827, 0x0001, 0x0078, 0x641a,
+ 0x00f0, 0x6400, 0x7804, 0xa084, 0x1000, 0x0040, 0x6423, 0x7803,
+ 0x0100, 0x7803, 0x0000, 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f,
+ 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c, 0x127e, 0x157e, 0x0f7e,
+ 0x0e7e, 0x0d7e, 0x0c7e, 0x027e, 0x017e, 0x007e, 0x2091, 0x8000,
+ 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x8aa2, 0x703c, 0x2060,
+ 0x8cff, 0x0040, 0x64a4, 0x6817, 0x0010, 0x68c7, 0x0000, 0x68cb,
+ 0x0000, 0x1078, 0x517c, 0x1078, 0x1d84, 0x047e, 0x057e, 0x2009,
+ 0x017f, 0x212c, 0x200b, 0x00a5, 0x2021, 0x0169, 0x2404, 0xa084,
+ 0x000f, 0xa086, 0x0004, 0x00c0, 0x6473, 0x68c7, 0x0000, 0x68cb,
+ 0x0008, 0x0e7e, 0x0f7e, 0x2079, 0x0020, 0x2071, 0x8af9, 0x6814,
+ 0xa084, 0x0004, 0xa085, 0x0012, 0x6816, 0x7803, 0x0008, 0x7003,
+ 0x0000, 0x0f7f, 0x0e7f, 0x250a, 0x057f, 0x047f, 0xa39d, 0x0000,
+ 0x00c0, 0x647e, 0x2009, 0x0049, 0x1078, 0x6939, 0x20a9, 0x03e8,
+ 0x6824, 0xd094, 0x0040, 0x6491, 0x6827, 0x0004, 0x7804, 0xa084,
+ 0x4000, 0x0040, 0x64a3, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078,
+ 0x64a3, 0xd094, 0x0040, 0x6498, 0x6827, 0x0002, 0x0078, 0x649a,
+ 0x00f0, 0x6480, 0x7804, 0xa084, 0x1000, 0x0040, 0x64a3, 0x7803,
0x0100, 0x7803, 0x0000, 0x6824, 0x007f, 0x017f, 0x027f, 0x0c7f,
- 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c, 0x2001, 0x7700,
- 0x2004, 0xa096, 0x0001, 0x0040, 0x5876, 0xa096, 0x0004, 0x0040,
- 0x5876, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, 0x3558, 0x1078,
- 0x4689, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, 0x5864, 0x6827,
- 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x5876, 0x7803, 0x1000,
- 0x7803, 0x0000, 0x0078, 0x5876, 0xd084, 0x0040, 0x586b, 0x6827,
- 0x0001, 0x0078, 0x586d, 0x00f0, 0x5853, 0x7804, 0xa084, 0x1000,
- 0x0040, 0x5876, 0x7803, 0x0100, 0x7803, 0x0000, 0x007f, 0x017f,
- 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c,
- 0x127e, 0x157e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x027e, 0x017e,
- 0x007e, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071,
- 0x7936, 0x703c, 0x2060, 0x8cff, 0x0040, 0x58ce, 0x6817, 0x0010,
- 0x68cb, 0x0000, 0x68c7, 0x0000, 0x1078, 0x4714, 0x1078, 0x1c13,
- 0xa39d, 0x0000, 0x00c0, 0x58a8, 0x2009, 0x0049, 0x1078, 0x5d41,
- 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0040, 0x58bb, 0x6827, 0x0004,
- 0x7804, 0xa084, 0x4000, 0x0040, 0x58cd, 0x7803, 0x1000, 0x7803,
- 0x0000, 0x0078, 0x58cd, 0xd094, 0x0040, 0x58c2, 0x6827, 0x0002,
- 0x0078, 0x58c4, 0x00f0, 0x58aa, 0x7804, 0xa084, 0x1000, 0x0040,
- 0x58cd, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x007f, 0x017f,
- 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c,
- 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0x7936, 0x6a06, 0x127f,
- 0x0d7f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0x7936,
- 0x6a32, 0x127f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e,
- 0x007e, 0x127e, 0x2071, 0x7936, 0x7614, 0x2660, 0x2678, 0x2091,
- 0x8000, 0x8cff, 0x0040, 0x592c, 0x601c, 0xa206, 0x00c0, 0x5927,
- 0x7014, 0xac36, 0x00c0, 0x5906, 0x660c, 0x7616, 0x7010, 0xac36,
- 0x00c0, 0x5914, 0x2c00, 0xaf36, 0x0040, 0x5912, 0x2f00, 0x7012,
- 0x0078, 0x5914, 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06,
- 0x0040, 0x591d, 0x7e0e, 0x0078, 0x591e, 0x2678, 0x600f, 0x0000,
- 0x1078, 0x6bb6, 0x1078, 0x5a1a, 0x0c7f, 0x0078, 0x58f9, 0x2c78,
- 0x600c, 0x2060, 0x0078, 0x58f9, 0x127f, 0x007f, 0x067f, 0x0c7f,
- 0x0e7f, 0x0f7f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078,
- 0x532f, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2,
- 0x20a3, 0x4000, 0x0078, 0x5975, 0x157e, 0x147e, 0x20a1, 0x020b,
- 0x1078, 0x532f, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2,
- 0x20a2, 0x20a3, 0x2000, 0x0078, 0x5975, 0x157e, 0x147e, 0x20a1,
- 0x020b, 0x1078, 0x532f, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2,
- 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078, 0x5975, 0x157e, 0x147e,
- 0x20a1, 0x020b, 0x1078, 0x532f, 0x7810, 0x20a2, 0xa006, 0x20a2,
- 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, 0x1078, 0x5a25, 0x60c3,
- 0x0020, 0x1078, 0x5688, 0x147f, 0x157f, 0x007c, 0x127e, 0x0c7e,
- 0x2091, 0x8000, 0x2061, 0x0100, 0x6120, 0xd1b4, 0x00c0, 0x598d,
- 0xd1bc, 0x00c0, 0x59d7, 0x0078, 0x5a17, 0x2009, 0x017f, 0x200b,
- 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069, 0x0140, 0x20a9, 0x001e,
- 0x2009, 0x0169, 0x6804, 0xa084, 0x4000, 0x0040, 0x59ce, 0x6020,
- 0xd0b4, 0x0040, 0x59ce, 0x6024, 0xd094, 0x00c0, 0x59ce, 0x2104,
- 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x59ce, 0x00f0, 0x599a,
- 0x027e, 0x6198, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c, 0x00ff,
- 0xa10d, 0x6088, 0x628c, 0x618e, 0x608b, 0xbc91, 0x6043, 0x0001,
- 0x6043, 0x0000, 0x608a, 0x628e, 0x6024, 0xd094, 0x00c0, 0x59cd,
- 0x6a04, 0xa294, 0x4000, 0x00c0, 0x59c4, 0x027f, 0x0d7f, 0x007f,
- 0x157f, 0x2009, 0x017f, 0x200b, 0x0000, 0x0078, 0x5a17, 0x2009,
- 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069, 0x0140,
- 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000, 0x0040,
- 0x5a10, 0x6020, 0xd0bc, 0x0040, 0x5a10, 0x2104, 0xa084, 0x000f,
- 0xa086, 0x0004, 0x00c0, 0x5a10, 0x00f0, 0x59e4, 0x027e, 0x6164,
- 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c, 0x00ff, 0xa10d, 0x6088,
- 0x628c, 0x608b, 0xbc91, 0x618e, 0x6043, 0x0001, 0x6043, 0x0000,
- 0x608a, 0x628e, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x5a0a, 0x027f,
- 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000, 0x0c7f,
- 0x127f, 0x007c, 0x0e7e, 0x2071, 0x7936, 0x7020, 0xa005, 0x0040,
- 0x5a23, 0x8001, 0x7022, 0x0e7f, 0x007c, 0x20a9, 0x0008, 0x20a2,
- 0x00f0, 0x5a27, 0x20a2, 0x20a2, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e,
- 0x0c7e, 0x077e, 0x067e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071,
- 0x7936, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff, 0x0040,
- 0x5abd, 0x8cff, 0x0040, 0x5abd, 0x601c, 0xa086, 0x0006, 0x00c0,
- 0x5ab8, 0x88ff, 0x0040, 0x5a54, 0x2800, 0xac06, 0x00c0, 0x5ab8,
- 0x2039, 0x0000, 0x0078, 0x5a58, 0x6018, 0xa206, 0x00c0, 0x5ab8,
- 0x7024, 0xac06, 0x00c0, 0x5a86, 0x2069, 0x0100, 0x68c0, 0xa005,
- 0x0040, 0x5a81, 0x6817, 0x0008, 0x68c3, 0x0000, 0x1078, 0x5b4a,
+ 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c, 0x0d7e, 0x127e,
+ 0x2091, 0x8000, 0x2069, 0x8aa2, 0x6a06, 0x127f, 0x0d7f, 0x007c,
+ 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0x8aa2, 0x6a32, 0x127f,
+ 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, 0x007e, 0x127e,
+ 0x2071, 0x8aa2, 0x7614, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff,
+ 0x0040, 0x6502, 0x601c, 0xa206, 0x00c0, 0x64fd, 0x7014, 0xac36,
+ 0x00c0, 0x64dc, 0x660c, 0x7616, 0x7010, 0xac36, 0x00c0, 0x64ea,
+ 0x2c00, 0xaf36, 0x0040, 0x64e8, 0x2f00, 0x7012, 0x0078, 0x64ea,
+ 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x64f3,
+ 0x7e0e, 0x0078, 0x64f4, 0x2678, 0x600f, 0x0000, 0x1078, 0x79a8,
+ 0x1078, 0x6601, 0x0c7f, 0x0078, 0x64cf, 0x2c78, 0x600c, 0x2060,
+ 0x0078, 0x64cf, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0e7f, 0x0f7f,
+ 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x5e77, 0x7810,
+ 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x1000,
+ 0x0078, 0x655c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x5e77,
+ 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3,
+ 0x4000, 0x0078, 0x655c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078,
+ 0x5e77, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2,
+ 0x20a3, 0x2000, 0x0078, 0x655c, 0x157e, 0x147e, 0x20a1, 0x020b,
+ 0x1078, 0x5e77, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2,
+ 0x20a2, 0x20a3, 0x0400, 0x0078, 0x655c, 0x157e, 0x147e, 0x20a1,
+ 0x020b, 0x1078, 0x5e77, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2,
+ 0x20a2, 0x20a2, 0x20a3, 0x0200, 0x1078, 0x660c, 0x60c3, 0x0020,
+ 0x1078, 0x621e, 0x147f, 0x157f, 0x007c, 0x127e, 0x0c7e, 0x2091,
+ 0x8000, 0x2061, 0x0100, 0x6120, 0xd1b4, 0x00c0, 0x6574, 0xd1bc,
+ 0x00c0, 0x65be, 0x0078, 0x65fe, 0x2009, 0x017f, 0x200b, 0x00a1,
+ 0x157e, 0x007e, 0x0d7e, 0x2069, 0x0140, 0x20a9, 0x001e, 0x2009,
+ 0x0169, 0x6804, 0xa084, 0x4000, 0x0040, 0x65b5, 0x6020, 0xd0b4,
+ 0x0040, 0x65b5, 0x6024, 0xd094, 0x00c0, 0x65b5, 0x2104, 0xa084,
+ 0x000f, 0xa086, 0x0004, 0x00c0, 0x65b5, 0x00f0, 0x6581, 0x027e,
+ 0x6198, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c, 0x00ff, 0xa10d,
+ 0x6088, 0x628c, 0x618e, 0x608b, 0xbc91, 0x6043, 0x0001, 0x6043,
+ 0x0000, 0x608a, 0x628e, 0x6024, 0xd094, 0x00c0, 0x65b4, 0x6a04,
+ 0xa294, 0x4000, 0x00c0, 0x65ab, 0x027f, 0x0d7f, 0x007f, 0x157f,
+ 0x2009, 0x017f, 0x200b, 0x0000, 0x0078, 0x65fe, 0x2009, 0x017f,
+ 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069, 0x0140, 0x20a9,
+ 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000, 0x0040, 0x65f7,
+ 0x6020, 0xd0bc, 0x0040, 0x65f7, 0x2104, 0xa084, 0x000f, 0xa086,
+ 0x0004, 0x00c0, 0x65f7, 0x00f0, 0x65cb, 0x027e, 0x6164, 0xa18c,
+ 0x00ff, 0x8107, 0x6130, 0xa18c, 0x00ff, 0xa10d, 0x6088, 0x628c,
+ 0x608b, 0xbc91, 0x618e, 0x6043, 0x0001, 0x6043, 0x0000, 0x608a,
+ 0x628e, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x65f1, 0x027f, 0x0d7f,
+ 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000, 0x0c7f, 0x127f,
+ 0x007c, 0x0e7e, 0x2071, 0x8aa2, 0x7020, 0xa005, 0x0040, 0x660a,
+ 0x8001, 0x7022, 0x0e7f, 0x007c, 0x20a9, 0x0008, 0x20a2, 0x00f0,
+ 0x660e, 0x20a2, 0x20a2, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e,
+ 0x077e, 0x067e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x8aa2,
+ 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff, 0x0040, 0x66ad,
+ 0x8cff, 0x0040, 0x66ad, 0x601c, 0xa086, 0x0006, 0x00c0, 0x66a8,
+ 0x88ff, 0x0040, 0x663b, 0x2800, 0xac06, 0x00c0, 0x66a8, 0x2039,
+ 0x0000, 0x0078, 0x6646, 0x6018, 0xa206, 0x00c0, 0x66a8, 0x85ff,
+ 0x0040, 0x6646, 0x6020, 0xa106, 0x00c0, 0x66a8, 0x7024, 0xac06,
+ 0x00c0, 0x6676, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x6671,
+ 0x1078, 0x516f, 0x6817, 0x0008, 0x68c3, 0x0000, 0x1078, 0x6741,
0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
- 0x0040, 0x5a76, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
- 0x6824, 0xd084, 0x0040, 0x5a7e, 0x6827, 0x0001, 0x037f, 0x0078,
- 0x5a86, 0x6003, 0x0009, 0x630a, 0x0078, 0x5ab8, 0x7014, 0xac36,
- 0x00c0, 0x5a8c, 0x660c, 0x7616, 0x7010, 0xac36, 0x00c0, 0x5a9a,
- 0x2c00, 0xaf36, 0x0040, 0x5a98, 0x2f00, 0x7012, 0x0078, 0x5a9a,
- 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5aa3,
- 0x7e0e, 0x0078, 0x5aa4, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068,
- 0x1078, 0x6a58, 0x0040, 0x5aae, 0x1078, 0x75fd, 0x1078, 0x6bb6,
- 0x1078, 0x5a1a, 0x88ff, 0x00c0, 0x5ac7, 0x0c7f, 0x0078, 0x5a3e,
- 0x2c78, 0x600c, 0x2060, 0x0078, 0x5a3e, 0xa006, 0x127f, 0x007f,
+ 0x0040, 0x6666, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
+ 0x6824, 0xd084, 0x0040, 0x666e, 0x6827, 0x0001, 0x037f, 0x0078,
+ 0x6676, 0x6003, 0x0009, 0x630a, 0x0078, 0x66a8, 0x7014, 0xac36,
+ 0x00c0, 0x667c, 0x660c, 0x7616, 0x7010, 0xac36, 0x00c0, 0x668a,
+ 0x2c00, 0xaf36, 0x0040, 0x6688, 0x2f00, 0x7012, 0x0078, 0x668a,
+ 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x6693,
+ 0x7e0e, 0x0078, 0x6694, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068,
+ 0x1078, 0x77ed, 0x0040, 0x669e, 0x1078, 0x86aa, 0x1078, 0x79a8,
+ 0x1078, 0x6601, 0x88ff, 0x00c0, 0x66b7, 0x0c7f, 0x0078, 0x6625,
+ 0x2c78, 0x600c, 0x2060, 0x0078, 0x6625, 0xa006, 0x127f, 0x007f,
0x067f, 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x6017,
- 0x0000, 0x0c7f, 0xa8c5, 0x0001, 0x0078, 0x5abe, 0x0f7e, 0x0e7e,
+ 0x0000, 0x0c7f, 0xa8c5, 0x0001, 0x0078, 0x66ae, 0x0f7e, 0x0e7e,
0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x007e, 0x127e, 0x2091, 0x8000,
- 0x2071, 0x7936, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x5b39,
- 0x601c, 0xa086, 0x0006, 0x00c0, 0x5b34, 0x88ff, 0x0040, 0x5aee,
- 0x2800, 0xac06, 0x00c0, 0x5b34, 0x0078, 0x5af2, 0x6018, 0xa206,
- 0x00c0, 0x5b34, 0x703c, 0xac06, 0x00c0, 0x5b04, 0x037e, 0x2019,
- 0x0001, 0x1078, 0x5880, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043,
- 0x0000, 0x7047, 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x5b0a,
- 0x660c, 0x763a, 0x7034, 0xac36, 0x00c0, 0x5b18, 0x2c00, 0xaf36,
- 0x0040, 0x5b16, 0x2f00, 0x7036, 0x0078, 0x5b18, 0x7037, 0x0000,
- 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5b21, 0x7e0e, 0x0078,
- 0x5b22, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x6a58,
- 0x0040, 0x5b2c, 0x1078, 0x75fd, 0x1078, 0x6bb6, 0x88ff, 0x00c0,
- 0x5b43, 0x0c7f, 0x0078, 0x5add, 0x2c78, 0x600c, 0x2060, 0x0078,
- 0x5add, 0xa006, 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0d7f,
- 0x0e7f, 0x0f7f, 0x007c, 0x6017, 0x0000, 0x0c7f, 0xa8c5, 0x0001,
- 0x0078, 0x5b3a, 0x0e7e, 0x2071, 0x7936, 0x2001, 0x7700, 0x2004,
- 0xa086, 0x0002, 0x00c0, 0x5b58, 0x7007, 0x0005, 0x0078, 0x5b5a,
- 0x7007, 0x0000, 0x0e7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e,
- 0x027e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x7936, 0x2c10,
- 0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x5b9a, 0x2200, 0xac06,
- 0x00c0, 0x5b95, 0x7038, 0xac36, 0x00c0, 0x5b78, 0x660c, 0x763a,
- 0x7034, 0xac36, 0x00c0, 0x5b86, 0x2c00, 0xaf36, 0x0040, 0x5b84,
- 0x2f00, 0x7036, 0x0078, 0x5b86, 0x7037, 0x0000, 0x660c, 0x2c00,
- 0xaf06, 0x0040, 0x5b8e, 0x7e0e, 0x0078, 0x5b8f, 0x2678, 0x600f,
- 0x0000, 0xa085, 0x0001, 0x0078, 0x5b9a, 0x2c78, 0x600c, 0x2060,
- 0x0078, 0x5b6b, 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0e7f,
- 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e,
- 0x127e, 0x2091, 0x8000, 0x2071, 0x7936, 0x760c, 0x2660, 0x2678,
- 0x8cff, 0x0040, 0x5c33, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206,
- 0x00c0, 0x5c2e, 0x7024, 0xac06, 0x00c0, 0x5be1, 0x2069, 0x0100,
- 0x68c0, 0xa005, 0x0040, 0x5be1, 0x1078, 0x569c, 0x68c3, 0x0000,
- 0x1078, 0x5b4a, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04,
- 0xa384, 0x1000, 0x0040, 0x5bd8, 0x6803, 0x0100, 0x6803, 0x0000,
- 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5be0, 0x6827, 0x0001,
- 0x037f, 0x700c, 0xac36, 0x00c0, 0x5be7, 0x660c, 0x760e, 0x7008,
- 0xac36, 0x00c0, 0x5bf5, 0x2c00, 0xaf36, 0x0040, 0x5bf3, 0x2f00,
- 0x700a, 0x0078, 0x5bf5, 0x700b, 0x0000, 0x660c, 0x067e, 0x2c00,
- 0xaf06, 0x0040, 0x5bfe, 0x7e0e, 0x0078, 0x5bff, 0x2678, 0x600f,
- 0x0000, 0x1078, 0x6bcf, 0x00c0, 0x5c09, 0x1078, 0x22d7, 0x0078,
- 0x5c25, 0x1078, 0x6be3, 0x00c0, 0x5c11, 0x1078, 0x5f6d, 0x0078,
- 0x5c25, 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x5c25, 0x601c,
- 0xa086, 0x0003, 0x00c0, 0x5c3b, 0x6837, 0x0103, 0x6b4a, 0x6847,
- 0x0000, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x6003, 0x0000, 0x1078,
- 0x6bb6, 0x1078, 0x5a1a, 0x0c7f, 0x0078, 0x5bb0, 0x2c78, 0x600c,
- 0x2060, 0x0078, 0x5bb0, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f,
- 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x5c1c,
- 0x1078, 0x75fd, 0x0078, 0x5c25, 0x037e, 0x157e, 0x137e, 0x147e,
- 0x3908, 0xa006, 0xa190, 0x0020, 0x221c, 0xa39e, 0x2149, 0x00c0,
- 0x5c55, 0x8210, 0x8000, 0x0078, 0x5c4c, 0xa005, 0x0040, 0x5c5f,
- 0x20a9, 0x0020, 0x2198, 0xa110, 0x22a0, 0x22c8, 0x53a3, 0x147f,
- 0x137f, 0x157f, 0x037f, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078,
- 0x516f, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x20a3, 0x514c, 0x20a3, 0x4f47, 0x20a3,
- 0x4943, 0x20a3, 0x2020, 0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x1078, 0x5688, 0x0d7f, 0x007c, 0x20a1,
- 0x020b, 0x1078, 0x516f, 0x20a3, 0x0210, 0x20a3, 0x0018, 0x20a3,
- 0x0800, 0x7810, 0xa084, 0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7810,
- 0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
- 0x0018, 0x1078, 0x5688, 0x007c, 0x2061, 0x7e00, 0x2a70, 0x7060,
- 0x7046, 0x704b, 0x7e00, 0x007c, 0x0e7e, 0x127e, 0x2071, 0x7700,
- 0x2091, 0x8000, 0x7544, 0xa582, 0x0001, 0x0048, 0x5ce6, 0x7048,
- 0x2060, 0x6000, 0xa086, 0x0000, 0x0040, 0x5cd2, 0xace0, 0x0008,
- 0x7054, 0xac02, 0x00c8, 0x5cce, 0x0078, 0x5cc1, 0x2061, 0x7e00,
- 0x0078, 0x5cc1, 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8, 0x0008,
- 0x7054, 0xa502, 0x00c8, 0x5ce2, 0x754a, 0xa085, 0x0001, 0x127f,
- 0x0e7f, 0x007c, 0x704b, 0x7e00, 0x0078, 0x5cdd, 0xa006, 0x0078,
- 0x5cdf, 0x0e7e, 0x2071, 0x7700, 0x7544, 0xa582, 0x0001, 0x0048,
- 0x5d17, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040, 0x5d04,
- 0xace0, 0x0008, 0x7054, 0xac02, 0x00c8, 0x5d00, 0x0078, 0x5cf3,
- 0x2061, 0x7e00, 0x0078, 0x5cf3, 0x6003, 0x0008, 0x8529, 0x7546,
- 0xaca8, 0x0008, 0x7054, 0xa502, 0x00c8, 0x5d13, 0x754a, 0xa085,
- 0x0001, 0x0e7f, 0x007c, 0x704b, 0x7e00, 0x0078, 0x5d0f, 0xa006,
- 0x0078, 0x5d11, 0xac82, 0x7e00, 0x1048, 0x12cd, 0x2001, 0x7715,
- 0x2004, 0xac02, 0x10c8, 0x12cd, 0xa006, 0x6006, 0x600a, 0x600e,
- 0x6012, 0x6016, 0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x2061,
- 0x7700, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0040, 0x5d39,
- 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x4d96, 0x127f, 0x0078,
- 0x5d38, 0x601c, 0xa084, 0x000f, 0x0079, 0x5d46, 0x5d4f, 0x5d57,
- 0x5d73, 0x5d8f, 0x6c60, 0x6c7c, 0x6c98, 0x5d4f, 0x5d57, 0xa18e,
- 0x0047, 0x00c0, 0x5d56, 0xa016, 0x1078, 0x156a, 0x007c, 0x067e,
- 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x5d61, 0x067f,
- 0x007c, 0x5d71, 0x5e58, 0x5f88, 0x5d71, 0x5fdf, 0x5d71, 0x5d71,
- 0x5d71, 0x5e07, 0x6298, 0x5d71, 0x5d71, 0x5d71, 0x5d71, 0x5d71,
- 0x5d71, 0x1078, 0x12cd, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
- 0x12cd, 0x1079, 0x5d7d, 0x067f, 0x007c, 0x5d8d, 0x5d8d, 0x5d8d,
- 0x5d8d, 0x5d8d, 0x5d8d, 0x5d8d, 0x5d8d, 0x670c, 0x67d2, 0x5d8d,
- 0x6725, 0x677e, 0x6725, 0x677e, 0x5d8d, 0x1078, 0x12cd, 0x067e,
- 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x5d99, 0x067f,
- 0x007c, 0x5da9, 0x62d6, 0x637c, 0x643e, 0x6596, 0x5da9, 0x5da9,
- 0x5da9, 0x62b4, 0x66c1, 0x66c5, 0x5da9, 0x5da9, 0x5da9, 0x5da9,
- 0x66eb, 0x1078, 0x12cd, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0,
- 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, 0x9398, 0x94a0, 0x3318,
- 0x3428, 0x222e, 0x2326, 0xa290, 0x0002, 0xa5a8, 0x0002, 0xa398,
- 0x0002, 0xa4a0, 0x0002, 0x00f0, 0x5db9, 0x0e7e, 0x1078, 0x6a58,
- 0x0040, 0x5dd0, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103,
- 0x0e7f, 0x1078, 0x5d1a, 0x007c, 0x0d7e, 0x037e, 0x7330, 0xa386,
- 0x0200, 0x00c0, 0x5de1, 0x6018, 0x2068, 0x6813, 0x00ff, 0x6817,
- 0xfffd, 0x6010, 0xa005, 0x0040, 0x5deb, 0x2068, 0x6807, 0x0000,
- 0x6837, 0x0103, 0x6b32, 0x1078, 0x5d1a, 0x037f, 0x0d7f, 0x007c,
- 0x0d7e, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0, 0x53a3, 0xa1b6,
- 0x0015, 0x00c0, 0x5e04, 0x6018, 0x2068, 0x7038, 0x680a, 0x703c,
- 0x680e, 0x6800, 0xc08d, 0x6802, 0x0d7f, 0x0078, 0x5dc5, 0x2100,
- 0xa1b2, 0x0030, 0x10c8, 0x12cd, 0x0079, 0x5e0e, 0x5e40, 0x5e4c,
- 0x5e40, 0x5e40, 0x5e40, 0x5e40, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e,
- 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e,
- 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e,
- 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e40, 0x5e3e, 0x5e40,
- 0x5e40, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e40, 0x5e3e,
- 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x5e3e, 0x1078, 0x12cd,
- 0x6003, 0x0001, 0x6106, 0x1078, 0x498e, 0x127e, 0x2091, 0x8000,
- 0x1078, 0x4d96, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078,
- 0x498e, 0x127e, 0x2091, 0x8000, 0x1078, 0x4d96, 0x127f, 0x007c,
- 0x6004, 0xa0b2, 0x0030, 0x10c8, 0x12cd, 0xa1b6, 0x0013, 0x00c0,
- 0x5e64, 0x2008, 0x0079, 0x5eeb, 0xa1b6, 0x0027, 0x00c0, 0x5eb9,
- 0x1078, 0x4c9d, 0x6004, 0x1078, 0x6bcf, 0x0040, 0x5e7d, 0x1078,
- 0x6be3, 0x0040, 0x5eb1, 0xa08e, 0x0021, 0x0040, 0x5eb5, 0xa08e,
- 0x0022, 0x0040, 0x5eb1, 0x0078, 0x5eac, 0x1078, 0x22d7, 0x2001,
- 0x0007, 0x1078, 0x37f4, 0x6018, 0xa080, 0x0028, 0x200c, 0x1078,
- 0x5f6d, 0xa186, 0x007e, 0x00c0, 0x5e92, 0x2001, 0x772f, 0x2014,
- 0xc285, 0x2202, 0x017e, 0x027e, 0x037e, 0x2110, 0x2019, 0x0028,
- 0x1078, 0x4a7e, 0x1078, 0x49c1, 0x0c7e, 0x6018, 0xa065, 0x0040,
- 0x5ea3, 0x1078, 0x3a36, 0x0c7f, 0x2c08, 0x1078, 0x747b, 0x037f,
- 0x027f, 0x017f, 0x1078, 0x3834, 0x1078, 0x5d1a, 0x1078, 0x4d96,
- 0x007c, 0x1078, 0x5f6d, 0x0078, 0x5eac, 0x1078, 0x5f7c, 0x0078,
- 0x5eac, 0xa186, 0x0014, 0x00c0, 0x5eb0, 0x1078, 0x4c9d, 0x1078,
- 0x22b5, 0x1078, 0x6bcf, 0x00c0, 0x5ed8, 0x1078, 0x22d7, 0x6018,
- 0xa080, 0x0028, 0x200c, 0x1078, 0x5f6d, 0xa186, 0x007e, 0x00c0,
- 0x5ed6, 0x2001, 0x772f, 0x200c, 0xc185, 0x2102, 0x0078, 0x5eac,
- 0x1078, 0x6be3, 0x00c0, 0x5ee0, 0x1078, 0x5f6d, 0x0078, 0x5eac,
- 0x6004, 0xa08e, 0x0021, 0x0040, 0x5edc, 0xa08e, 0x0022, 0x1040,
- 0x5f7c, 0x0078, 0x5eac, 0x5f1d, 0x5f1f, 0x5f23, 0x5f27, 0x5f2b,
- 0x5f2f, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b,
- 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b,
- 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b, 0x5f1b,
- 0x5f1b, 0x5f33, 0x5f39, 0x5f1b, 0x5f43, 0x5f39, 0x5f1b, 0x5f1b,
- 0x5f1b, 0x5f1b, 0x5f1b, 0x5f39, 0x5f39, 0x5f1b, 0x5f1b, 0x5f1b,
- 0x5f1b, 0x5f1b, 0x5f1b, 0x1078, 0x12cd, 0x0078, 0x5f39, 0x2001,
- 0x000b, 0x0078, 0x5f4c, 0x2001, 0x0003, 0x0078, 0x5f4c, 0x2001,
- 0x0005, 0x0078, 0x5f4c, 0x2001, 0x0001, 0x0078, 0x5f4c, 0x2001,
- 0x0009, 0x0078, 0x5f4c, 0x1078, 0x12cd, 0x0078, 0x5f4b, 0x1078,
- 0x37f4, 0x1078, 0x4c9d, 0x6003, 0x0002, 0x6017, 0x0028, 0x1078,
- 0x4d96, 0x0078, 0x5f4b, 0x1078, 0x4c9d, 0x6003, 0x0004, 0x6017,
- 0x0028, 0x1078, 0x4d96, 0x007c, 0x1078, 0x37f4, 0x1078, 0x4c9d,
- 0x6003, 0x0002, 0x037e, 0x2019, 0x775c, 0x2304, 0xa084, 0xff00,
- 0x00c0, 0x5f5e, 0x2019, 0x0028, 0x0078, 0x5f67, 0x8007, 0xa09a,
- 0x0004, 0x0048, 0x5f5a, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316,
- 0x037f, 0x1078, 0x4d96, 0x0078, 0x5f4b, 0x0e7e, 0x1078, 0x6a58,
- 0x0040, 0x5f7a, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103,
- 0x7033, 0x0100, 0x0e7f, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74,
- 0x7000, 0x2070, 0x7037, 0x0103, 0x7023, 0x8001, 0x0e7f, 0x007c,
- 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084, 0x00ff, 0x0d7f, 0xa0b2,
- 0x000c, 0x10c8, 0x12cd, 0x6604, 0xa6b6, 0x0028, 0x00c0, 0x5f9c,
- 0x1078, 0x6c18, 0x0078, 0x5fce, 0x6604, 0xa6b6, 0x0029, 0x00c0,
- 0x5fa5, 0x1078, 0x6c32, 0x0078, 0x5fce, 0x6604, 0xa6b6, 0x001f,
- 0x00c0, 0x5fae, 0x1078, 0x5dab, 0x0078, 0x5fce, 0x6604, 0xa6b6,
- 0x0000, 0x00c0, 0x5fb7, 0x1078, 0x5df0, 0x0078, 0x5fce, 0x6604,
- 0xa6b6, 0x0022, 0x00c0, 0x5fc0, 0x1078, 0x5dd4, 0x0078, 0x5fce,
- 0xa1b6, 0x0015, 0x00c0, 0x5fc8, 0x1079, 0x5fd3, 0x0078, 0x5fce,
- 0xa1b6, 0x0016, 0x00c0, 0x5fcf, 0x1079, 0x6110, 0x007c, 0x1078,
- 0x5d4f, 0x0078, 0x5fce, 0x5ff7, 0x5ffa, 0x5ff7, 0x603b, 0x5ff7,
- 0x60ac, 0x5ff7, 0x5ff7, 0x5ff7, 0x60e8, 0x5ff7, 0x60fe, 0xa1b6,
- 0x0048, 0x0040, 0x5feb, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10,
- 0x1078, 0x156a, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000,
- 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x5d1a, 0x007c, 0x0005,
- 0x0005, 0x007c, 0x0e7e, 0x2071, 0x7700, 0x7078, 0xa086, 0x0074,
- 0x00c0, 0x6024, 0x1078, 0x744f, 0x00c0, 0x6016, 0x0d7e, 0x6018,
- 0x2068, 0x1078, 0x6028, 0x0d7f, 0x2001, 0x0006, 0x1078, 0x37f4,
- 0x1078, 0x22d7, 0x1078, 0x5d1a, 0x0078, 0x6026, 0x2001, 0x000a,
- 0x1078, 0x37f4, 0x1078, 0x22d7, 0x6003, 0x0001, 0x6007, 0x0001,
- 0x1078, 0x498e, 0x0078, 0x6026, 0x1078, 0x609c, 0x0e7f, 0x007c,
- 0x6800, 0xd084, 0x0040, 0x603a, 0x2001, 0x0000, 0x1078, 0x37e0,
- 0x2069, 0x7751, 0x6804, 0xd0a4, 0x0040, 0x603a, 0x2001, 0x0006,
- 0x1078, 0x3802, 0x007c, 0x0d7e, 0x2011, 0x771e, 0x2204, 0xa086,
- 0x0074, 0x00c0, 0x6098, 0x1078, 0x61ea, 0x6018, 0x2068, 0xa080,
- 0x0028, 0x2014, 0xa286, 0x007e, 0x0040, 0x6063, 0xa286, 0x0080,
- 0x00c0, 0x608c, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005,
- 0x0040, 0x6082, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833,
- 0x0200, 0x0078, 0x6082, 0x0e7e, 0x0f7e, 0x6813, 0x00ff, 0x6817,
- 0xfffe, 0x2071, 0x772f, 0x2e04, 0xa085, 0x0003, 0x2072, 0x2071,
- 0x7c80, 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0x7719,
- 0x206a, 0x78e6, 0x8e70, 0x2e04, 0x2069, 0x771a, 0x206a, 0x78ea,
- 0x0f7f, 0x0e7f, 0x2001, 0x0006, 0x1078, 0x37f4, 0x1078, 0x22d7,
- 0x1078, 0x5d1a, 0x0078, 0x609a, 0x2001, 0x0004, 0x1078, 0x37f4,
- 0x6003, 0x0001, 0x6007, 0x0003, 0x1078, 0x498e, 0x0078, 0x609a,
- 0x1078, 0x609c, 0x0d7f, 0x007c, 0x2001, 0x7700, 0x2004, 0xa086,
- 0x0003, 0x0040, 0x60a7, 0x2001, 0x0007, 0x1078, 0x37f4, 0x1078,
- 0x22d7, 0x1078, 0x5d1a, 0x007c, 0x0e7e, 0x2071, 0x7700, 0x7078,
- 0xa086, 0x0014, 0x00c0, 0x60e2, 0x7000, 0xa086, 0x0003, 0x00c0,
- 0x60bf, 0x6010, 0xa005, 0x00c0, 0x60bf, 0x1078, 0x2dd7, 0x0d7e,
- 0x6018, 0x2068, 0x1078, 0x38c8, 0x1078, 0x6028, 0x0d7f, 0x1078,
- 0x61f4, 0x00c0, 0x60e2, 0x2001, 0x0006, 0x1078, 0x37f4, 0x0e7e,
- 0x6010, 0xa005, 0x0040, 0x60db, 0x2070, 0x7007, 0x0000, 0x7037,
- 0x0103, 0x7033, 0x0200, 0x0e7f, 0x1078, 0x22d7, 0x1078, 0x5d1a,
- 0x0078, 0x60e6, 0x1078, 0x5f6d, 0x1078, 0x609c, 0x0e7f, 0x007c,
- 0x2011, 0x771e, 0x2204, 0xa086, 0x0014, 0x00c0, 0x60fb, 0x2001,
- 0x0002, 0x1078, 0x37f4, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078,
- 0x498e, 0x0078, 0x60fd, 0x1078, 0x609c, 0x007c, 0x2011, 0x771e,
- 0x2204, 0xa086, 0x0004, 0x00c0, 0x610d, 0x2001, 0x0007, 0x1078,
- 0x37f4, 0x1078, 0x5d1a, 0x0078, 0x610f, 0x1078, 0x609c, 0x007c,
- 0x5ff7, 0x611c, 0x5ff7, 0x6142, 0x5ff7, 0x619d, 0x5ff7, 0x5ff7,
- 0x5ff7, 0x61b2, 0x5ff7, 0x61c5, 0x0c7e, 0x1078, 0x61d8, 0x00c0,
- 0x6131, 0x2001, 0x0000, 0x1078, 0x37e0, 0x2001, 0x0002, 0x1078,
- 0x37f4, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x498e, 0x0078,
- 0x6140, 0x2009, 0x7c8f, 0x2104, 0xa084, 0xff00, 0xa086, 0x1900,
- 0x00c0, 0x613e, 0x1078, 0x5d1a, 0x0078, 0x6140, 0x1078, 0x609c,
- 0x0c7f, 0x007c, 0x1078, 0x61e7, 0x00c0, 0x6156, 0x2001, 0x0000,
- 0x1078, 0x37e0, 0x2001, 0x0002, 0x1078, 0x37f4, 0x6003, 0x0001,
- 0x6007, 0x0002, 0x1078, 0x498e, 0x0078, 0x6178, 0x1078, 0x5f6d,
- 0x2009, 0x7c8e, 0x2134, 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x0040,
- 0x6179, 0x2009, 0x7c8f, 0x2104, 0xa084, 0xff00, 0xa086, 0x1900,
- 0x00c0, 0x6176, 0xa686, 0x0009, 0x0040, 0x6179, 0x2001, 0x0004,
- 0x1078, 0x37f4, 0x1078, 0x5d1a, 0x0078, 0x6178, 0x1078, 0x609c,
- 0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x6187,
- 0x6838, 0xd0fc, 0x0040, 0x6187, 0x0d7f, 0x0078, 0x6176, 0x6018,
- 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x6198, 0x8001,
- 0x6842, 0x6017, 0x000a, 0x6007, 0x0016, 0x0d7f, 0x0078, 0x6178,
- 0x1078, 0x22b5, 0x0d7f, 0x0078, 0x6176, 0x1078, 0x61e7, 0x00c0,
- 0x61ad, 0x2001, 0x0004, 0x1078, 0x37f4, 0x6003, 0x0001, 0x6007,
- 0x0003, 0x1078, 0x498e, 0x0078, 0x61b1, 0x1078, 0x5f6d, 0x1078,
- 0x609c, 0x007c, 0x1078, 0x61e7, 0x00c0, 0x61c2, 0x2001, 0x0008,
- 0x1078, 0x37f4, 0x6003, 0x0001, 0x6007, 0x0005, 0x1078, 0x498e,
- 0x0078, 0x61c4, 0x1078, 0x609c, 0x007c, 0x1078, 0x61e7, 0x00c0,
- 0x61d5, 0x2001, 0x000a, 0x1078, 0x37f4, 0x6003, 0x0001, 0x6007,
- 0x0001, 0x1078, 0x498e, 0x0078, 0x61d7, 0x1078, 0x609c, 0x007c,
- 0x2009, 0x7c8e, 0x2104, 0xa086, 0x0003, 0x00c0, 0x61e6, 0x2009,
- 0x7c8f, 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, 0x007c, 0xa085,
- 0x0001, 0x007c, 0x0c7e, 0x017e, 0xac88, 0x0006, 0x2164, 0x1078,
- 0x385e, 0x017f, 0x0c7f, 0x007c, 0x0e7e, 0x2071, 0x7c8c, 0x7004,
- 0xa086, 0x0014, 0x00c0, 0x6217, 0x7008, 0xa086, 0x0800, 0x00c0,
- 0x6217, 0x700c, 0xd0ec, 0x0040, 0x6215, 0xa084, 0x0f00, 0xa086,
- 0x0100, 0x00c0, 0x6215, 0x7024, 0xd0a4, 0x0040, 0x6215, 0xd08c,
- 0x0040, 0x6215, 0xa006, 0x0078, 0x6217, 0xa085, 0x0001, 0x0e7f,
- 0x007c, 0x0e7e, 0x0d7e, 0x0c7e, 0x077e, 0x057e, 0x047e, 0x027e,
- 0x007e, 0x127e, 0x2091, 0x8000, 0x2029, 0x793f, 0x252c, 0x2021,
- 0x7945, 0x2424, 0x2061, 0x7e00, 0x2071, 0x7700, 0x7244, 0x7060,
- 0xa202, 0x00c8, 0x626e, 0x1078, 0x7659, 0x0040, 0x6266, 0x671c,
- 0xa786, 0x0001, 0x0040, 0x6266, 0xa786, 0x0007, 0x0040, 0x6266,
- 0x2500, 0xac06, 0x0040, 0x6266, 0x2400, 0xac06, 0x0040, 0x6266,
- 0x0c7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x6250, 0x1078, 0x166e,
- 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x6263, 0xa786, 0x0003,
- 0x00c0, 0x6278, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078,
- 0x3b92, 0x1078, 0x6ba9, 0x1078, 0x6bb6, 0x0c7f, 0xace0, 0x0008,
- 0x7054, 0xac02, 0x00c8, 0x626e, 0x0078, 0x622e, 0x127f, 0x007f,
- 0x027f, 0x047f, 0x057f, 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c,
- 0xa786, 0x0006, 0x00c0, 0x625a, 0x1078, 0x75fd, 0x0078, 0x6263,
- 0x220c, 0x2304, 0xa106, 0x00c0, 0x628b, 0x8210, 0x8318, 0x00f0,
- 0x6280, 0xa006, 0x007c, 0x2304, 0xa102, 0x0048, 0x6293, 0x2001,
- 0x0001, 0x0078, 0x6295, 0x2001, 0x0000, 0xa18d, 0x0001, 0x007c,
- 0x6004, 0xa08a, 0x0030, 0x10c8, 0x12cd, 0x1078, 0x6bcf, 0x0040,
- 0x62a7, 0x1078, 0x6be3, 0x0040, 0x62b0, 0x0078, 0x62a9, 0x1078,
- 0x22d7, 0x1078, 0x4c9d, 0x1078, 0x5d1a, 0x1078, 0x4d96, 0x007c,
- 0x1078, 0x5f6d, 0x0078, 0x62a9, 0xa182, 0x0040, 0x0079, 0x62b8,
- 0x62c8, 0x62c8, 0x62c8, 0x62c8, 0x62c8, 0x62c8, 0x62c8, 0x62c8,
- 0x62c8, 0x62c8, 0x62c8, 0x62ca, 0x62ca, 0x62ca, 0x62ca, 0x62c8,
- 0x1078, 0x12cd, 0x6003, 0x0001, 0x6106, 0x1078, 0x4941, 0x127e,
- 0x2091, 0x8000, 0x1078, 0x4d96, 0x127f, 0x007c, 0xa186, 0x0013,
- 0x00c0, 0x62df, 0x6004, 0xa082, 0x0040, 0x0079, 0x6355, 0xa186,
- 0x0027, 0x00c0, 0x62fc, 0x1078, 0x4c9d, 0x1078, 0x22b5, 0x0d7e,
- 0x6110, 0x2168, 0x1078, 0x6a58, 0x0040, 0x62f6, 0x6837, 0x0103,
- 0x684b, 0x0029, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x0d7f, 0x1078,
- 0x5d1a, 0x1078, 0x4d96, 0x007c, 0xa186, 0x0014, 0x00c0, 0x6305,
- 0x6004, 0xa082, 0x0040, 0x0079, 0x6325, 0xa186, 0x0047, 0x10c0,
- 0x12cd, 0x2001, 0x0109, 0x2004, 0xd084, 0x0040, 0x6322, 0x127e,
- 0x2091, 0x2200, 0x007e, 0x017e, 0x027e, 0x1078, 0x4802, 0x027f,
- 0x017f, 0x007f, 0x127f, 0x6000, 0xa086, 0x0002, 0x00c0, 0x6322,
- 0x0078, 0x637c, 0x1078, 0x5d4f, 0x007c, 0x6337, 0x6335, 0x6335,
- 0x6335, 0x6335, 0x6335, 0x6335, 0x6335, 0x6335, 0x6335, 0x6335,
- 0x634e, 0x634e, 0x634e, 0x634e, 0x6335, 0x1078, 0x12cd, 0x1078,
- 0x4c9d, 0x0d7e, 0x6110, 0x2168, 0x1078, 0x6a58, 0x0040, 0x6348,
- 0x6837, 0x0103, 0x684b, 0x0006, 0x1078, 0x3b92, 0x1078, 0x6ba9,
- 0x0d7f, 0x1078, 0x5d1a, 0x1078, 0x4d96, 0x007c, 0x1078, 0x4c9d,
- 0x1078, 0x5d1a, 0x1078, 0x4d96, 0x007c, 0x6367, 0x6365, 0x6365,
- 0x6365, 0x6365, 0x6365, 0x6365, 0x6365, 0x6365, 0x6365, 0x6365,
- 0x6375, 0x6375, 0x6375, 0x6375, 0x6365, 0x1078, 0x12cd, 0x1078,
- 0x4c9d, 0x6003, 0x0002, 0x1078, 0x4d96, 0x6010, 0xa088, 0x0013,
- 0x2104, 0xa085, 0x0400, 0x200a, 0x007c, 0x1078, 0x4c9d, 0x6003,
- 0x000f, 0x1078, 0x4d96, 0x007c, 0xa182, 0x0040, 0x0079, 0x6380,
- 0x6390, 0x6390, 0x6390, 0x6390, 0x6390, 0x6392, 0x641b, 0x6433,
- 0x6390, 0x6390, 0x6390, 0x6390, 0x6390, 0x6390, 0x6390, 0x6390,
- 0x1078, 0x12cd, 0x0e7e, 0x0d7e, 0x2071, 0x7c8c, 0x6110, 0x2168,
- 0x7614, 0xa6b4, 0x0fff, 0x86ff, 0x0040, 0x63ff, 0xa68c, 0x00ff,
- 0xa186, 0x0002, 0x0040, 0x63c4, 0xa186, 0x0028, 0x00c0, 0x63ae,
- 0x1078, 0x6bbd, 0x684b, 0x001c, 0x0078, 0x63c6, 0xd6dc, 0x0040,
- 0x63b9, 0x684b, 0x0015, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078,
- 0x63c6, 0xd6d4, 0x0040, 0x63c4, 0x684b, 0x0007, 0x7318, 0x6b62,
- 0x731c, 0x6b5e, 0x0078, 0x63c6, 0x684b, 0x0000, 0x6837, 0x0103,
- 0x6e46, 0xa01e, 0xd6c4, 0x0040, 0x63d9, 0x7328, 0x732c, 0x6b56,
- 0x037e, 0x2308, 0x2019, 0x7c98, 0xad90, 0x0019, 0x1078, 0x6841,
- 0x037f, 0xd6cc, 0x0040, 0x640f, 0x7124, 0x695a, 0xa192, 0x0021,
- 0x00c8, 0x63ed, 0x2071, 0x7c98, 0x831c, 0x2300, 0xae18, 0xad90,
- 0x001d, 0x1078, 0x6841, 0x0078, 0x640f, 0x6838, 0xd0fc, 0x0040,
- 0x63f6, 0x2009, 0x0020, 0x695a, 0x0078, 0x63e2, 0x0f7e, 0x2d78,
- 0x1078, 0x67d9, 0x0f7f, 0x1078, 0x682e, 0x0078, 0x6411, 0x684b,
- 0x0000, 0x6837, 0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0040, 0x640f,
- 0x6810, 0x6914, 0xa115, 0x0040, 0x640f, 0x1078, 0x6587, 0x1078,
- 0x3b92, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x0d7f, 0x0e7f,
- 0x1078, 0x5d1a, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0x7c8c,
- 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16,
- 0x7e0a, 0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x19c7, 0x1078, 0x49ad,
- 0x1078, 0x4e56, 0x007c, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005,
- 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x156a, 0x007c, 0xa182, 0x0040,
- 0x0079, 0x6442, 0x6452, 0x6452, 0x6452, 0x6452, 0x6452, 0x6454,
- 0x64eb, 0x6452, 0x6452, 0x6501, 0x6563, 0x6452, 0x6452, 0x6452,
- 0x6452, 0x656e, 0x1078, 0x12cd, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e,
- 0x2071, 0x7c8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46,
- 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e,
- 0x86ff, 0x0040, 0x64e6, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0040,
- 0x6475, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0040,
- 0x64e6, 0x1078, 0x1327, 0x1040, 0x12cd, 0x2d00, 0x784a, 0x7f4c,
- 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e,
- 0x7840, 0x6842, 0x6e46, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040,
- 0x64af, 0xa186, 0x0028, 0x00c0, 0x6499, 0x684b, 0x001c, 0x0078,
- 0x64b1, 0xd6dc, 0x0040, 0x64a4, 0x684b, 0x0015, 0x7318, 0x6b62,
- 0x731c, 0x6b5e, 0x0078, 0x64b1, 0xd6d4, 0x0040, 0x64af, 0x684b,
- 0x0007, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078, 0x64b1, 0x684b,
- 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4,
- 0x0040, 0x64c6, 0x7328, 0x732c, 0x6b56, 0x037e, 0x2308, 0x2019,
- 0x7c98, 0xad90, 0x0019, 0x1078, 0x6841, 0x037f, 0xd6cc, 0x0040,
- 0x64e6, 0x7124, 0x695a, 0xa192, 0x0021, 0x00c8, 0x64da, 0x2071,
- 0x7c98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x6841,
- 0x0078, 0x64e6, 0x7838, 0xd0fc, 0x0040, 0x64e3, 0x2009, 0x0020,
- 0x695a, 0x0078, 0x64cf, 0x2d78, 0x1078, 0x67d9, 0x0d7f, 0x0e7f,
- 0x0f7f, 0x077f, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0x7c8c,
- 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16,
- 0x7e0a, 0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x19c7, 0x1078, 0x5681,
- 0x007c, 0x0d7e, 0x6003, 0x0002, 0x1078, 0x4d45, 0x1078, 0x4e56,
- 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040, 0x6561, 0xd1cc, 0x0040,
- 0x653c, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x6534, 0x017e, 0x684c,
- 0x007e, 0x6850, 0x007e, 0xad90, 0x000d, 0xa198, 0x000d, 0x2009,
- 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x00f0,
- 0x6523, 0x157f, 0x007f, 0x6852, 0x007f, 0x684e, 0x017f, 0x2168,
- 0x1078, 0x1350, 0x0078, 0x655f, 0x017e, 0x1078, 0x1350, 0x0d7f,
- 0x1078, 0x682e, 0x0078, 0x655f, 0x6837, 0x0103, 0x6944, 0xa184,
- 0x00ff, 0xa186, 0x0002, 0x0040, 0x655b, 0xa086, 0x0028, 0x00c0,
- 0x654d, 0x684b, 0x001c, 0x0078, 0x655d, 0xd1dc, 0x0040, 0x6554,
- 0x684b, 0x0015, 0x0078, 0x655d, 0xd1d4, 0x0040, 0x655b, 0x684b,
- 0x0007, 0x0078, 0x655d, 0x684b, 0x0000, 0x1078, 0x3b92, 0x1078,
- 0x5d1a, 0x0d7f, 0x007c, 0x2019, 0x0001, 0x1078, 0x5880, 0x6003,
- 0x0002, 0x1078, 0x4d45, 0x1078, 0x4e56, 0x007c, 0x1078, 0x4d45,
- 0x1078, 0x22b5, 0x0d7e, 0x6110, 0x2168, 0x1078, 0x6a58, 0x0040,
- 0x6581, 0x6837, 0x0103, 0x684b, 0x0029, 0x1078, 0x3b92, 0x1078,
- 0x6ba9, 0x0d7f, 0x1078, 0x5d1a, 0x1078, 0x4e56, 0x007c, 0x684b,
- 0x0015, 0xd1fc, 0x0040, 0x6593, 0x684b, 0x0007, 0x8002, 0x8000,
- 0x810a, 0xa189, 0x0000, 0x6962, 0x685e, 0x007c, 0xa182, 0x0040,
- 0x0079, 0x659a, 0x65aa, 0x65aa, 0x65aa, 0x65aa, 0x65aa, 0x65ac,
- 0x65aa, 0x6650, 0x6658, 0x65aa, 0x65aa, 0x65aa, 0x65aa, 0x65aa,
- 0x65aa, 0x65aa, 0x1078, 0x12cd, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e,
- 0x2071, 0x7c8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46,
- 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e,
- 0x86ff, 0x0040, 0x6642, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0040,
- 0x65cd, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0040,
- 0x663f, 0x1078, 0x1327, 0x1040, 0x12cd, 0x2d00, 0x784a, 0x7f4c,
- 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c,
- 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x00ff, 0xa186, 0x0002,
- 0x0040, 0x6608, 0xa186, 0x0028, 0x00c0, 0x65f2, 0x684b, 0x001c,
- 0x0078, 0x660a, 0xd6dc, 0x0040, 0x65fd, 0x684b, 0x0015, 0x7318,
- 0x6b62, 0x731c, 0x6b5e, 0x0078, 0x660a, 0xd6d4, 0x0040, 0x6608,
- 0x684b, 0x0007, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0x0078, 0x660a,
- 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e,
- 0xd6c4, 0x0040, 0x661f, 0x7328, 0x732c, 0x6b56, 0x037e, 0x2308,
- 0x2019, 0x7c98, 0xad90, 0x0019, 0x1078, 0x6841, 0x037f, 0xd6cc,
- 0x0040, 0x663f, 0x7124, 0x695a, 0xa192, 0x0021, 0x00c8, 0x6633,
- 0x2071, 0x7c98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078,
- 0x6841, 0x0078, 0x663f, 0x7838, 0xd0fc, 0x0040, 0x663c, 0x2009,
- 0x0020, 0x695a, 0x0078, 0x6628, 0x2d78, 0x1078, 0x67d9, 0xd6dc,
- 0x00c0, 0x6645, 0xa006, 0x0078, 0x6649, 0x2001, 0x0001, 0x7218,
- 0x731c, 0x1078, 0x15ae, 0x0d7f, 0x0e7f, 0x0f7f, 0x077f, 0x007c,
- 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x156a, 0x007c,
- 0x0d7e, 0x6003, 0x0002, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040,
- 0x66bf, 0xd1cc, 0x0040, 0x668f, 0x6948, 0x6838, 0xd0fc, 0x0040,
- 0x6687, 0x017e, 0x684c, 0x007e, 0x6850, 0x007e, 0xad90, 0x000d,
- 0xa198, 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012,
- 0x8318, 0x8210, 0x00f0, 0x6676, 0x157f, 0x007f, 0x6852, 0x007f,
- 0x684e, 0x017f, 0x2168, 0x1078, 0x1350, 0x0078, 0x66bd, 0x017e,
- 0x1078, 0x1350, 0x0d7f, 0x1078, 0x682e, 0x0078, 0x66bd, 0x6837,
- 0x0103, 0x6944, 0xa184, 0x00ff, 0xa186, 0x0002, 0x0040, 0x66ae,
- 0xa086, 0x0028, 0x00c0, 0x66a0, 0x684b, 0x001c, 0x0078, 0x66bb,
- 0xd1dc, 0x0040, 0x66a7, 0x684b, 0x0015, 0x0078, 0x66bb, 0xd1d4,
- 0x0040, 0x66ae, 0x684b, 0x0007, 0x0078, 0x66bb, 0x684b, 0x0000,
- 0x684c, 0xd0ac, 0x0040, 0x66bb, 0x6810, 0x6914, 0xa115, 0x0040,
- 0x66bb, 0x1078, 0x6587, 0x1078, 0x3b92, 0x1078, 0x5d1a, 0x0d7f,
- 0x007c, 0x1078, 0x4c9d, 0x0078, 0x66c7, 0x1078, 0x4d45, 0x1078,
- 0x6a58, 0x0040, 0x66de, 0x0d7e, 0x6110, 0x2168, 0x6837, 0x0103,
- 0x2009, 0x770c, 0x210c, 0xd18c, 0x00c0, 0x66e7, 0xd184, 0x00c0,
- 0x66e3, 0x6108, 0x694a, 0x1078, 0x3b92, 0x0d7f, 0x1078, 0x5d1a,
- 0x1078, 0x4d96, 0x007c, 0x684b, 0x0004, 0x0078, 0x66db, 0x684b,
- 0x0004, 0x0078, 0x66db, 0xa182, 0x0040, 0x0079, 0x66ef, 0x66ff,
- 0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x6701, 0x66ff, 0x6704, 0x66ff,
- 0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x66ff, 0x1078,
- 0x12cd, 0x1078, 0x5d1a, 0x007c, 0x007e, 0x027e, 0xa016, 0x1078,
- 0x156a, 0x027f, 0x007f, 0x007c, 0xa182, 0x0085, 0x0079, 0x6710,
- 0x6719, 0x6717, 0x6717, 0x6717, 0x6717, 0x6717, 0x6717, 0x1078,
- 0x12cd, 0x6003, 0x0001, 0x6106, 0x1078, 0x4941, 0x127e, 0x2091,
- 0x8000, 0x1078, 0x4d96, 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0,
- 0x672f, 0x6004, 0xa082, 0x0085, 0x2008, 0x0079, 0x6763, 0xa186,
- 0x0027, 0x00c0, 0x6750, 0x1078, 0x4c9d, 0x1078, 0x22b5, 0x0d7e,
- 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040, 0x6746, 0x6837, 0x0103,
- 0x684b, 0x0029, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x0d7f, 0x1078,
- 0x5d1a, 0x1078, 0x4d96, 0x007c, 0x1078, 0x5d4f, 0x0078, 0x674b,
- 0xa186, 0x0014, 0x00c0, 0x674c, 0x1078, 0x4c9d, 0x0d7e, 0x6010,
- 0x2068, 0x1078, 0x6a58, 0x0040, 0x6746, 0x6837, 0x0103, 0x684b,
- 0x0006, 0x0078, 0x6742, 0x676c, 0x676a, 0x676a, 0x676a, 0x676a,
- 0x676a, 0x6775, 0x1078, 0x12cd, 0x1078, 0x4c9d, 0x6017, 0x0014,
- 0x6003, 0x000c, 0x1078, 0x4d96, 0x007c, 0x1078, 0x4c9d, 0x6017,
- 0x0014, 0x6003, 0x000e, 0x1078, 0x4d96, 0x007c, 0xa182, 0x008c,
- 0x00c8, 0x6788, 0xa182, 0x0085, 0x0048, 0x6788, 0x0079, 0x678b,
- 0x1078, 0x5d4f, 0x007c, 0x6792, 0x6792, 0x6792, 0x6792, 0x6794,
- 0x67b3, 0x6792, 0x1078, 0x12cd, 0x0d7e, 0x1078, 0x6ba9, 0x1078,
- 0x6a58, 0x0040, 0x67af, 0x6010, 0x2068, 0x6837, 0x0103, 0x6850,
- 0xd0b4, 0x0040, 0x67a7, 0x684b, 0x0006, 0x0078, 0x67ab, 0x684b,
- 0x0005, 0x1078, 0x6c5c, 0x6847, 0x0000, 0x1078, 0x3b92, 0x1078,
- 0x5d1a, 0x0d7f, 0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x6a58,
- 0x0040, 0x67ce, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, 0x67c4,
- 0x684b, 0x0006, 0x0078, 0x67c8, 0x684b, 0x0005, 0x1078, 0x6c5c,
- 0x6847, 0x0000, 0x1078, 0x3b92, 0x1078, 0x6ba9, 0x0d7f, 0x1078,
- 0x5d1a, 0x007c, 0x1078, 0x4c9d, 0x1078, 0x5d1a, 0x1078, 0x4d96,
+ 0x2071, 0x8aa2, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x6730,
+ 0x601c, 0xa086, 0x0006, 0x00c0, 0x672b, 0x88ff, 0x0040, 0x66de,
+ 0x2800, 0xac06, 0x00c0, 0x672b, 0x0078, 0x66e9, 0x6018, 0xa206,
+ 0x00c0, 0x672b, 0x85ff, 0x0040, 0x66e9, 0x6020, 0xa106, 0x00c0,
+ 0x672b, 0x703c, 0xac06, 0x00c0, 0x66fb, 0x037e, 0x2019, 0x0001,
+ 0x1078, 0x642d, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000,
+ 0x7047, 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x6701, 0x660c,
+ 0x763a, 0x7034, 0xac36, 0x00c0, 0x670f, 0x2c00, 0xaf36, 0x0040,
+ 0x670d, 0x2f00, 0x7036, 0x0078, 0x670f, 0x7037, 0x0000, 0x660c,
+ 0x067e, 0x2c00, 0xaf06, 0x0040, 0x6718, 0x7e0e, 0x0078, 0x6719,
+ 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040,
+ 0x6723, 0x1078, 0x86aa, 0x1078, 0x79a8, 0x88ff, 0x00c0, 0x673a,
+ 0x0c7f, 0x0078, 0x66cd, 0x2c78, 0x600c, 0x2060, 0x0078, 0x66cd,
+ 0xa006, 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f,
+ 0x0f7f, 0x007c, 0x6017, 0x0000, 0x0c7f, 0xa8c5, 0x0001, 0x0078,
+ 0x6731, 0x0e7e, 0x2071, 0x8aa2, 0x2001, 0x8800, 0x2004, 0xa086,
+ 0x0002, 0x00c0, 0x674f, 0x7007, 0x0005, 0x0078, 0x6751, 0x7007,
+ 0x0000, 0x0e7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, 0x027e,
+ 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0x8aa2, 0x2c10, 0x7638,
+ 0x2660, 0x2678, 0x8cff, 0x0040, 0x6791, 0x2200, 0xac06, 0x00c0,
+ 0x678c, 0x7038, 0xac36, 0x00c0, 0x676f, 0x660c, 0x763a, 0x7034,
+ 0xac36, 0x00c0, 0x677d, 0x2c00, 0xaf36, 0x0040, 0x677b, 0x2f00,
+ 0x7036, 0x0078, 0x677d, 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06,
+ 0x0040, 0x6785, 0x7e0e, 0x0078, 0x6786, 0x2678, 0x600f, 0x0000,
+ 0xa085, 0x0001, 0x0078, 0x6791, 0x2c78, 0x600c, 0x2060, 0x0078,
+ 0x6762, 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0e7f, 0x0f7f,
+ 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e, 0x127e,
+ 0x2091, 0x8000, 0x2071, 0x8aa2, 0x760c, 0x2660, 0x2678, 0x8cff,
+ 0x0040, 0x682a, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0,
+ 0x6825, 0x7024, 0xac06, 0x00c0, 0x67d8, 0x2069, 0x0100, 0x68c0,
+ 0xa005, 0x0040, 0x67d8, 0x1078, 0x6232, 0x68c3, 0x0000, 0x1078,
+ 0x6741, 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384,
+ 0x1000, 0x0040, 0x67cf, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069,
+ 0x0100, 0x6824, 0xd084, 0x0040, 0x67d7, 0x6827, 0x0001, 0x037f,
+ 0x700c, 0xac36, 0x00c0, 0x67de, 0x660c, 0x760e, 0x7008, 0xac36,
+ 0x00c0, 0x67ec, 0x2c00, 0xaf36, 0x0040, 0x67ea, 0x2f00, 0x700a,
+ 0x0078, 0x67ec, 0x700b, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06,
+ 0x0040, 0x67f5, 0x7e0e, 0x0078, 0x67f6, 0x2678, 0x600f, 0x0000,
+ 0x1078, 0x79c1, 0x00c0, 0x6800, 0x1078, 0x24e5, 0x0078, 0x681c,
+ 0x1078, 0x79d5, 0x00c0, 0x6808, 0x1078, 0x6bc7, 0x0078, 0x681c,
+ 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, 0x681c, 0x601c, 0xa086,
+ 0x0003, 0x00c0, 0x6832, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+ 0x1078, 0x4376, 0x1078, 0x799b, 0x6003, 0x0000, 0x1078, 0x79a8,
+ 0x1078, 0x6601, 0x0c7f, 0x0078, 0x67a7, 0x2c78, 0x600c, 0x2060,
+ 0x0078, 0x67a7, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f,
+ 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x6813, 0x1078,
+ 0x86aa, 0x0078, 0x681c, 0x037e, 0x157e, 0x137e, 0x147e, 0x3908,
+ 0xa006, 0xa190, 0x0020, 0x221c, 0xa39e, 0x231e, 0x00c0, 0x684c,
+ 0x8210, 0x8000, 0x0078, 0x6843, 0xa005, 0x0040, 0x6856, 0x20a9,
+ 0x0020, 0x2198, 0xa110, 0x22a0, 0x22c8, 0x53a3, 0x147f, 0x137f,
+ 0x157f, 0x037f, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078, 0x5c87,
+ 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x2099, 0x8a9c, 0x20a9, 0x0004, 0x53a6, 0x20a3,
+ 0x0004, 0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x1078,
+ 0x621e, 0x0d7f, 0x007c, 0x20a1, 0x020b, 0x1078, 0x5c87, 0x20a3,
+ 0x0210, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084, 0xff00,
+ 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x7810, 0xa084, 0x00ff, 0x20a2, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x1078, 0x621e, 0x007c,
+ 0x2061, 0x8f00, 0x2a70, 0x7060, 0x7046, 0x704b, 0x8f00, 0x007c,
+ 0x0e7e, 0x127e, 0x2071, 0x8800, 0x2091, 0x8000, 0x7544, 0xa582,
+ 0x0001, 0x0048, 0x68da, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000,
+ 0x0040, 0x68c6, 0xace0, 0x000c, 0x7054, 0xac02, 0x00c8, 0x68c2,
+ 0x0078, 0x68b5, 0x2061, 0x8f00, 0x0078, 0x68b5, 0x6003, 0x0008,
+ 0x8529, 0x7546, 0xaca8, 0x000c, 0x7054, 0xa502, 0x00c8, 0x68d6,
+ 0x754a, 0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704b, 0x8f00,
+ 0x0078, 0x68d1, 0xa006, 0x0078, 0x68d3, 0x0e7e, 0x2071, 0x8800,
+ 0x7544, 0xa582, 0x0001, 0x0048, 0x690b, 0x7048, 0x2060, 0x6000,
+ 0xa086, 0x0000, 0x0040, 0x68f8, 0xace0, 0x000c, 0x7054, 0xac02,
+ 0x00c8, 0x68f4, 0x0078, 0x68e7, 0x2061, 0x8f00, 0x0078, 0x68e7,
+ 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8, 0x000c, 0x7054, 0xa502,
+ 0x00c8, 0x6907, 0x754a, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x704b,
+ 0x8f00, 0x0078, 0x6903, 0xa006, 0x0078, 0x6905, 0xac82, 0x8f00,
+ 0x1048, 0x12d2, 0x2001, 0x8815, 0x2004, 0xac02, 0x10c8, 0x12d2,
+ 0xa006, 0x6006, 0x600a, 0x600e, 0x6012, 0x6016, 0x601a, 0x601f,
+ 0x0000, 0x6003, 0x0000, 0x6022, 0x6026, 0x602a, 0x602e, 0x2061,
+ 0x8800, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0040, 0x6931,
+ 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x5888, 0x127f, 0x0078,
+ 0x6930, 0x601c, 0xa084, 0x000f, 0x0079, 0x693e, 0x6947, 0x6958,
+ 0x6974, 0x6990, 0x7a52, 0x7a6e, 0x7a8a, 0x6947, 0x6958, 0xa186,
+ 0x0013, 0x00c0, 0x6950, 0x1078, 0x578f, 0x1078, 0x5888, 0x007c,
+ 0xa18e, 0x0047, 0x00c0, 0x6957, 0xa016, 0x1078, 0x1594, 0x007c,
+ 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12d2, 0x1079, 0x6962,
+ 0x067f, 0x007c, 0x6972, 0x6a89, 0x6be6, 0x6972, 0x6c46, 0x6972,
+ 0x6972, 0x6972, 0x6a28, 0x6f24, 0x6972, 0x6972, 0x6972, 0x6972,
+ 0x6972, 0x6972, 0x1078, 0x12d2, 0x067e, 0x6000, 0xa0b2, 0x0010,
+ 0x10c8, 0x12d2, 0x1079, 0x697e, 0x067f, 0x007c, 0x698e, 0x698e,
+ 0x698e, 0x698e, 0x698e, 0x698e, 0x698e, 0x698e, 0x7419, 0x74f8,
+ 0x698e, 0x7432, 0x7492, 0x7432, 0x7492, 0x698e, 0x1078, 0x12d2,
+ 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12d2, 0x1079, 0x699a,
+ 0x067f, 0x007c, 0x69aa, 0x6f65, 0x7020, 0x70fa, 0x7257, 0x69aa,
+ 0x69aa, 0x69aa, 0x6f40, 0x73c7, 0x73cb, 0x69aa, 0x69aa, 0x69aa,
+ 0x69aa, 0x73f5, 0x1078, 0x12d2, 0x20a9, 0x000e, 0x2e98, 0x6010,
+ 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, 0x9398, 0x94a0,
+ 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002, 0xa5a8, 0x0002,
+ 0xa398, 0x0002, 0xa4a0, 0x0002, 0x00f0, 0x69ba, 0x0e7e, 0x1078,
+ 0x77ed, 0x0040, 0x69d1, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037,
+ 0x0103, 0x0e7f, 0x1078, 0x690e, 0x007c, 0x0d7e, 0x037e, 0x7330,
+ 0xa386, 0x0200, 0x00c0, 0x69e2, 0x6018, 0x2068, 0x6813, 0x00ff,
+ 0x6817, 0xfffd, 0x6010, 0xa005, 0x0040, 0x69ec, 0x2068, 0x6807,
+ 0x0000, 0x6837, 0x0103, 0x6b32, 0x1078, 0x690e, 0x037f, 0x0d7f,
+ 0x007c, 0x017e, 0x20a9, 0x002a, 0xae80, 0x000c, 0x2098, 0x6010,
+ 0xa080, 0x0002, 0x20a0, 0x53a3, 0x20a9, 0x002a, 0x6010, 0xa080,
+ 0x0001, 0x2004, 0xa080, 0x0002, 0x20a0, 0x53a3, 0x0e7e, 0x6010,
+ 0x2004, 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x690e, 0x017f,
+ 0x007c, 0x0d7e, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0, 0x53a3,
+ 0xa1b6, 0x0015, 0x00c0, 0x6a25, 0x6018, 0x2068, 0x7038, 0x680a,
+ 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802, 0x0d7f, 0x0078, 0x69c6,
+ 0x2100, 0xa1b2, 0x0040, 0x10c8, 0x12d2, 0x0079, 0x6a2f, 0x6a71,
+ 0x6a7d, 0x6a71, 0x6a71, 0x6a71, 0x6a71, 0x6a6f, 0x6a6f, 0x6a6f,
+ 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f,
+ 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f,
+ 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a71, 0x6a6f,
+ 0x6a71, 0x6a71, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a71,
+ 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f,
+ 0x6a6f, 0x6a71, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f,
+ 0x6a6f, 0x6a6f, 0x6a6f, 0x6a6f, 0x6a71, 0x6a6f, 0x6a6f, 0x1078,
+ 0x12d2, 0x6003, 0x0001, 0x6106, 0x1078, 0x53e6, 0x127e, 0x2091,
+ 0x8000, 0x1078, 0x5888, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106,
+ 0x1078, 0x53e6, 0x127e, 0x2091, 0x8000, 0x1078, 0x5888, 0x127f,
+ 0x007c, 0x6004, 0xa0b2, 0x0040, 0x10c8, 0x12d2, 0xa1b6, 0x0013,
+ 0x00c0, 0x6a95, 0x2008, 0x0079, 0x6b35, 0xa1b6, 0x0027, 0x00c0,
+ 0x6af2, 0x1078, 0x578f, 0x6004, 0x1078, 0x79c1, 0x0040, 0x6ab2,
+ 0x1078, 0x79d5, 0x0040, 0x6aea, 0xa08e, 0x0021, 0x0040, 0x6aee,
+ 0xa08e, 0x0022, 0x0040, 0x6aea, 0xa08e, 0x003d, 0x0040, 0x6aee,
+ 0x0078, 0x6ae5, 0x1078, 0x24e5, 0x2001, 0x0007, 0x1078, 0x3f05,
+ 0x6018, 0xa080, 0x0028, 0x200c, 0x1078, 0x6bc7, 0xa186, 0x007e,
+ 0x00c0, 0x6ac7, 0x2001, 0x8830, 0x2014, 0xc285, 0x2202, 0x017e,
+ 0x027e, 0x037e, 0x2110, 0x2019, 0x0028, 0x1078, 0x54f0, 0x087e,
+ 0x2041, 0x0000, 0x1078, 0x5419, 0x0c7e, 0x6018, 0xa065, 0x0040,
+ 0x6adb, 0x1078, 0x418b, 0x0c7f, 0x2c08, 0x1078, 0x84d2, 0x087f,
+ 0x037f, 0x027f, 0x017f, 0x1078, 0x3f76, 0x1078, 0x690e, 0x1078,
+ 0x5888, 0x007c, 0x1078, 0x6bc7, 0x0078, 0x6ae5, 0x1078, 0x6bda,
+ 0x0078, 0x6ae5, 0xa186, 0x0014, 0x00c0, 0x6ae9, 0x1078, 0x578f,
+ 0x1078, 0x24bf, 0x1078, 0x79c1, 0x00c0, 0x6b11, 0x1078, 0x24e5,
+ 0x6018, 0xa080, 0x0028, 0x200c, 0x1078, 0x6bc7, 0xa186, 0x007e,
+ 0x00c0, 0x6b0f, 0x2001, 0x8830, 0x200c, 0xc185, 0x2102, 0x0078,
+ 0x6ae5, 0x1078, 0x79d5, 0x00c0, 0x6b19, 0x1078, 0x6bc7, 0x0078,
+ 0x6ae5, 0x6004, 0xa08e, 0x0032, 0x00c0, 0x6b2a, 0x0e7e, 0x0f7e,
+ 0x2071, 0x8881, 0x2079, 0x0000, 0x1078, 0x27c9, 0x0f7f, 0x0e7f,
+ 0x0078, 0x6ae5, 0x6004, 0xa08e, 0x0021, 0x0040, 0x6b15, 0xa08e,
+ 0x0022, 0x1040, 0x6bda, 0x0078, 0x6ae5, 0x6b77, 0x6b79, 0x6b7d,
+ 0x6b81, 0x6b85, 0x6b89, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75,
+ 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75,
+ 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75,
+ 0x6b75, 0x6b75, 0x6b75, 0x6b8d, 0x6b93, 0x6b75, 0x6b9d, 0x6b93,
+ 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b93, 0x6b93, 0x6b75,
+ 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75,
+ 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75, 0x6b75,
+ 0x6b75, 0x6b75, 0x6b93, 0x6b75, 0x6b75, 0x1078, 0x12d2, 0x0078,
+ 0x6b93, 0x2001, 0x000b, 0x0078, 0x6ba6, 0x2001, 0x0003, 0x0078,
+ 0x6ba6, 0x2001, 0x0005, 0x0078, 0x6ba6, 0x2001, 0x0001, 0x0078,
+ 0x6ba6, 0x2001, 0x0009, 0x0078, 0x6ba6, 0x1078, 0x12d2, 0x0078,
+ 0x6ba5, 0x1078, 0x3f05, 0x1078, 0x578f, 0x6003, 0x0002, 0x6017,
+ 0x0028, 0x1078, 0x5888, 0x0078, 0x6ba5, 0x1078, 0x578f, 0x6003,
+ 0x0004, 0x6017, 0x0028, 0x1078, 0x5888, 0x007c, 0x1078, 0x3f05,
+ 0x1078, 0x578f, 0x6003, 0x0002, 0x037e, 0x2019, 0x885c, 0x2304,
+ 0xa084, 0xff00, 0x00c0, 0x6bb8, 0x2019, 0x0028, 0x0078, 0x6bc1,
+ 0x8007, 0xa09a, 0x0004, 0x0048, 0x6bb4, 0x8003, 0x801b, 0x831b,
+ 0xa318, 0x6316, 0x037f, 0x1078, 0x5888, 0x0078, 0x6ba5, 0x0e7e,
+ 0x1078, 0x77ed, 0x0040, 0x6bd8, 0x6010, 0x2070, 0x7038, 0xd0fc,
+ 0x0040, 0x6bd8, 0x7007, 0x0000, 0x7037, 0x0103, 0x7033, 0x0100,
+ 0x0e7f, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070,
+ 0x7037, 0x0103, 0x7023, 0x8001, 0x0e7f, 0x007c, 0x0d7e, 0x6618,
+ 0x2668, 0x6804, 0xa084, 0x00ff, 0x0d7f, 0xa0b2, 0x000c, 0x10c8,
+ 0x12d2, 0x6604, 0xa6b6, 0x0028, 0x00c0, 0x6bfa, 0x1078, 0x7a0a,
+ 0x0078, 0x6c35, 0x6604, 0xa6b6, 0x0029, 0x00c0, 0x6c03, 0x1078,
+ 0x7a24, 0x0078, 0x6c35, 0x6604, 0xa6b6, 0x001f, 0x00c0, 0x6c0c,
+ 0x1078, 0x69ac, 0x0078, 0x6c35, 0x6604, 0xa6b6, 0x0000, 0x00c0,
+ 0x6c15, 0x1078, 0x6a11, 0x0078, 0x6c35, 0x6604, 0xa6b6, 0x0022,
+ 0x00c0, 0x6c1e, 0x1078, 0x69d5, 0x0078, 0x6c35, 0x6604, 0xa6b6,
+ 0x003d, 0x00c0, 0x6c27, 0x1078, 0x69f1, 0x0078, 0x6c35, 0xa1b6,
+ 0x0015, 0x00c0, 0x6c2f, 0x1079, 0x6c3a, 0x0078, 0x6c35, 0xa1b6,
+ 0x0016, 0x00c0, 0x6c36, 0x1079, 0x6d93, 0x007c, 0x1078, 0x6950,
+ 0x0078, 0x6c35, 0x6c5e, 0x6c61, 0x6c5e, 0x6ca2, 0x6c5e, 0x6d2f,
+ 0x6c5e, 0x6c5e, 0x6c5e, 0x6d6b, 0x6c5e, 0x6d81, 0xa1b6, 0x0048,
+ 0x0040, 0x6c52, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078,
+ 0x1594, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070,
+ 0x7037, 0x0103, 0x0e7f, 0x1078, 0x690e, 0x007c, 0x0005, 0x0005,
+ 0x007c, 0x0e7e, 0x2071, 0x8800, 0x707c, 0xa086, 0x0074, 0x00c0,
+ 0x6c8b, 0x1078, 0x84a6, 0x00c0, 0x6c7d, 0x0d7e, 0x6018, 0x2068,
+ 0x1078, 0x6c8f, 0x0d7f, 0x2001, 0x0006, 0x1078, 0x3f05, 0x1078,
+ 0x24e5, 0x1078, 0x690e, 0x0078, 0x6c8d, 0x2001, 0x000a, 0x1078,
+ 0x3f05, 0x1078, 0x24e5, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078,
+ 0x53e6, 0x0078, 0x6c8d, 0x1078, 0x6d1f, 0x0e7f, 0x007c, 0x6800,
+ 0xd084, 0x0040, 0x6ca1, 0x2001, 0x0000, 0x1078, 0x3ef1, 0x2069,
+ 0x8851, 0x6804, 0xd0a4, 0x0040, 0x6ca1, 0x2001, 0x0006, 0x1078,
+ 0x3f2c, 0x007c, 0x0d7e, 0x2011, 0x881f, 0x2204, 0xa086, 0x0074,
+ 0x00c0, 0x6d1b, 0x1078, 0x6e79, 0x6018, 0x2068, 0xa080, 0x0028,
+ 0x2014, 0xa286, 0x007e, 0x0040, 0x6cca, 0xa286, 0x0080, 0x00c0,
+ 0x6cf3, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005, 0x0040,
+ 0x6ce9, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833, 0x0200,
+ 0x0078, 0x6ce9, 0x0e7e, 0x0f7e, 0x6813, 0x00ff, 0x6817, 0xfffe,
+ 0x2071, 0x8830, 0x2e04, 0xa085, 0x0003, 0x2072, 0x2071, 0x8d80,
+ 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0x881a, 0x206a,
+ 0x78e6, 0x8e70, 0x2e04, 0x2069, 0x881b, 0x206a, 0x78ea, 0x0f7f,
+ 0x0e7f, 0x2001, 0x0006, 0x1078, 0x3f05, 0x1078, 0x24e5, 0x1078,
+ 0x690e, 0x0078, 0x6d1d, 0x0e7e, 0x2071, 0x8830, 0x2e04, 0xd09c,
+ 0x0040, 0x6d0e, 0x2071, 0x8d80, 0x7108, 0x720c, 0xa18c, 0x00ff,
+ 0x00c0, 0x6d06, 0xa284, 0xff00, 0x0040, 0x6d0e, 0x6018, 0x2070,
+ 0x70a0, 0xd0bc, 0x00c0, 0x6d0e, 0x7112, 0x7216, 0x0e7f, 0x2001,
+ 0x0004, 0x1078, 0x3f05, 0x6003, 0x0001, 0x6007, 0x0003, 0x1078,
+ 0x53e6, 0x0078, 0x6d1d, 0x1078, 0x6d1f, 0x0d7f, 0x007c, 0x2001,
+ 0x8800, 0x2004, 0xa086, 0x0003, 0x0040, 0x6d2a, 0x2001, 0x0007,
+ 0x1078, 0x3f05, 0x1078, 0x24e5, 0x1078, 0x690e, 0x007c, 0x0e7e,
+ 0x2071, 0x8800, 0x707c, 0xa086, 0x0014, 0x00c0, 0x6d65, 0x7000,
+ 0xa086, 0x0003, 0x00c0, 0x6d42, 0x6010, 0xa005, 0x00c0, 0x6d42,
+ 0x1078, 0x31f8, 0x0d7e, 0x6018, 0x2068, 0x1078, 0x400a, 0x1078,
+ 0x6c8f, 0x0d7f, 0x1078, 0x6e83, 0x00c0, 0x6d65, 0x2001, 0x0006,
+ 0x1078, 0x3f05, 0x0e7e, 0x6010, 0xa005, 0x0040, 0x6d5e, 0x2070,
+ 0x7007, 0x0000, 0x7037, 0x0103, 0x7033, 0x0200, 0x0e7f, 0x1078,
+ 0x24e5, 0x1078, 0x690e, 0x0078, 0x6d69, 0x1078, 0x6bc7, 0x1078,
+ 0x6d1f, 0x0e7f, 0x007c, 0x2011, 0x881f, 0x2204, 0xa086, 0x0014,
+ 0x00c0, 0x6d7e, 0x2001, 0x0002, 0x1078, 0x3f05, 0x6003, 0x0001,
+ 0x6007, 0x0001, 0x1078, 0x53e6, 0x0078, 0x6d80, 0x1078, 0x6d1f,
+ 0x007c, 0x2011, 0x881f, 0x2204, 0xa086, 0x0004, 0x00c0, 0x6d90,
+ 0x2001, 0x0007, 0x1078, 0x3f05, 0x1078, 0x690e, 0x0078, 0x6d92,
+ 0x1078, 0x6d1f, 0x007c, 0x6c5e, 0x6d9f, 0x6c5e, 0x6dc7, 0x6c5e,
+ 0x6e2c, 0x6c5e, 0x6c5e, 0x6c5e, 0x6e41, 0x6c5e, 0x6e54, 0x0d7e,
+ 0x0c7e, 0x1078, 0x6e67, 0x00c0, 0x6db5, 0x2001, 0x0000, 0x1078,
+ 0x3ef1, 0x2001, 0x0002, 0x1078, 0x3f05, 0x6003, 0x0001, 0x6007,
+ 0x0002, 0x1078, 0x53e6, 0x0078, 0x6dc4, 0x2009, 0x8d8f, 0x2104,
+ 0xa084, 0xff00, 0xa086, 0x1900, 0x00c0, 0x6dc2, 0x1078, 0x690e,
+ 0x0078, 0x6dc4, 0x1078, 0x6d1f, 0x0c7f, 0x0d7f, 0x007c, 0x1078,
+ 0x6e76, 0x00c0, 0x6ddb, 0x2001, 0x0000, 0x1078, 0x3ef1, 0x2001,
+ 0x0002, 0x1078, 0x3f05, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078,
+ 0x53e6, 0x0078, 0x6e07, 0x1078, 0x6bc7, 0x2009, 0x8d8e, 0x2134,
+ 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x0040, 0x6e08, 0xa686, 0x000b,
+ 0x0040, 0x6e05, 0x2009, 0x8d8f, 0x2104, 0xa084, 0xff00, 0x00c0,
+ 0x6df5, 0xa686, 0x0009, 0x0040, 0x6e08, 0xa086, 0x1900, 0x00c0,
+ 0x6e05, 0xa686, 0x0009, 0x0040, 0x6e08, 0x2001, 0x0004, 0x1078,
+ 0x3f05, 0x1078, 0x690e, 0x0078, 0x6e07, 0x1078, 0x6d1f, 0x007c,
+ 0x0d7e, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, 0x6e16, 0x6838,
+ 0xd0fc, 0x0040, 0x6e16, 0x0d7f, 0x0078, 0x6e05, 0x6018, 0x2068,
+ 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x6e27, 0x8001, 0x6842,
+ 0x6017, 0x000a, 0x6007, 0x0016, 0x0d7f, 0x0078, 0x6e07, 0x1078,
+ 0x24bf, 0x0d7f, 0x0078, 0x6e05, 0x1078, 0x6e76, 0x00c0, 0x6e3c,
+ 0x2001, 0x0004, 0x1078, 0x3f05, 0x6003, 0x0001, 0x6007, 0x0003,
+ 0x1078, 0x53e6, 0x0078, 0x6e40, 0x1078, 0x6bc7, 0x1078, 0x6d1f,
+ 0x007c, 0x1078, 0x6e76, 0x00c0, 0x6e51, 0x2001, 0x0008, 0x1078,
+ 0x3f05, 0x6003, 0x0001, 0x6007, 0x0005, 0x1078, 0x53e6, 0x0078,
+ 0x6e53, 0x1078, 0x6d1f, 0x007c, 0x1078, 0x6e76, 0x00c0, 0x6e64,
+ 0x2001, 0x000a, 0x1078, 0x3f05, 0x6003, 0x0001, 0x6007, 0x0001,
+ 0x1078, 0x53e6, 0x0078, 0x6e66, 0x1078, 0x6d1f, 0x007c, 0x2009,
+ 0x8d8e, 0x2104, 0xa086, 0x0003, 0x00c0, 0x6e75, 0x2009, 0x8d8f,
+ 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, 0x007c, 0xa085, 0x0001,
+ 0x007c, 0x0c7e, 0x017e, 0xac88, 0x0006, 0x2164, 0x1078, 0x3fa0,
+ 0x017f, 0x0c7f, 0x007c, 0x0e7e, 0x2071, 0x8d8c, 0x7004, 0xa086,
+ 0x0014, 0x00c0, 0x6ea3, 0x7008, 0xa086, 0x0800, 0x00c0, 0x6ea3,
+ 0x700c, 0xd0ec, 0x0040, 0x6ea1, 0xa084, 0x0f00, 0xa086, 0x0100,
+ 0x00c0, 0x6ea1, 0x7024, 0xd0a4, 0x0040, 0x6ea1, 0xa006, 0x0078,
+ 0x6ea3, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x0e7e, 0x0d7e, 0x0c7e,
+ 0x077e, 0x057e, 0x047e, 0x027e, 0x007e, 0x127e, 0x2091, 0x8000,
+ 0x2029, 0x8aab, 0x252c, 0x2021, 0x8ab1, 0x2424, 0x2061, 0x8f00,
+ 0x2071, 0x8800, 0x7244, 0x7060, 0xa202, 0x00c8, 0x6efa, 0x1078,
+ 0x870c, 0x0040, 0x6ef2, 0x671c, 0xa786, 0x0001, 0x0040, 0x6ef2,
+ 0xa786, 0x0007, 0x0040, 0x6ef2, 0x2500, 0xac06, 0x0040, 0x6ef2,
+ 0x2400, 0xac06, 0x0040, 0x6ef2, 0x0c7e, 0x6000, 0xa086, 0x0004,
+ 0x00c0, 0x6edc, 0x1078, 0x16af, 0x6010, 0x2068, 0x1078, 0x77ed,
+ 0x0040, 0x6eef, 0xa786, 0x0003, 0x00c0, 0x6f04, 0x6837, 0x0103,
+ 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4376, 0x1078, 0x799b, 0x1078,
+ 0x79a8, 0x0c7f, 0xace0, 0x000c, 0x7054, 0xac02, 0x00c8, 0x6efa,
+ 0x0078, 0x6eba, 0x127f, 0x007f, 0x027f, 0x047f, 0x057f, 0x077f,
+ 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0, 0x6ee6,
+ 0x1078, 0x86aa, 0x0078, 0x6eef, 0x220c, 0x2304, 0xa106, 0x00c0,
+ 0x6f17, 0x8210, 0x8318, 0x00f0, 0x6f0c, 0xa006, 0x007c, 0x2304,
+ 0xa102, 0x0048, 0x6f1f, 0x2001, 0x0001, 0x0078, 0x6f21, 0x2001,
+ 0x0000, 0xa18d, 0x0001, 0x007c, 0x6004, 0xa08a, 0x0040, 0x10c8,
+ 0x12d2, 0x1078, 0x79c1, 0x0040, 0x6f33, 0x1078, 0x79d5, 0x0040,
+ 0x6f3c, 0x0078, 0x6f35, 0x1078, 0x24e5, 0x1078, 0x578f, 0x1078,
+ 0x690e, 0x1078, 0x5888, 0x007c, 0x1078, 0x6bc7, 0x0078, 0x6f35,
+ 0xa182, 0x0040, 0x0079, 0x6f44, 0x6f57, 0x6f57, 0x6f57, 0x6f57,
+ 0x6f57, 0x6f57, 0x6f57, 0x6f57, 0x6f57, 0x6f57, 0x6f57, 0x6f59,
+ 0x6f59, 0x6f59, 0x6f59, 0x6f57, 0x6f57, 0x6f57, 0x6f59, 0x1078,
+ 0x12d2, 0x6003, 0x0001, 0x6106, 0x1078, 0x5399, 0x127e, 0x2091,
+ 0x8000, 0x1078, 0x5888, 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0,
+ 0x6f6e, 0x6004, 0xa082, 0x0040, 0x0079, 0x6ff6, 0xa186, 0x0027,
+ 0x00c0, 0x6f8d, 0x1078, 0x578f, 0x1078, 0x24bf, 0x0d7e, 0x6110,
+ 0x2168, 0x1078, 0x77ed, 0x0040, 0x6f87, 0x6837, 0x0103, 0x684b,
+ 0x0029, 0x6847, 0x0000, 0x1078, 0x4376, 0x1078, 0x799b, 0x0d7f,
+ 0x1078, 0x690e, 0x1078, 0x5888, 0x007c, 0xa186, 0x0014, 0x00c0,
+ 0x6f96, 0x6004, 0xa082, 0x0040, 0x0079, 0x6fbe, 0xa186, 0x0046,
+ 0x0040, 0x6fa2, 0xa186, 0x0045, 0x0040, 0x6fa2, 0xa186, 0x0047,
+ 0x10c0, 0x12d2, 0x2001, 0x0109, 0x2004, 0xd084, 0x0040, 0x6fbb,
+ 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e, 0x1078, 0x5273,
+ 0x027f, 0x017f, 0x007f, 0x127f, 0x6000, 0xa086, 0x0002, 0x00c0,
+ 0x6fbb, 0x0078, 0x7020, 0x1078, 0x6950, 0x007c, 0x6fd3, 0x6fd1,
+ 0x6fd1, 0x6fd1, 0x6fd1, 0x6fd1, 0x6fd1, 0x6fd1, 0x6fd1, 0x6fd1,
+ 0x6fd1, 0x6fef, 0x6fef, 0x6fef, 0x6fef, 0x6fd1, 0x6fd1, 0x6fd1,
+ 0x6fef, 0x1078, 0x12d2, 0x1078, 0x578f, 0x0d7e, 0x6110, 0x2168,
+ 0x1078, 0x77ed, 0x0040, 0x6fe9, 0x6837, 0x0103, 0x684b, 0x0006,
+ 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x1078, 0x4376, 0x1078,
+ 0x799b, 0x0d7f, 0x1078, 0x690e, 0x1078, 0x5888, 0x007c, 0x1078,
+ 0x578f, 0x1078, 0x690e, 0x1078, 0x5888, 0x007c, 0x700b, 0x7009,
+ 0x7009, 0x7009, 0x7009, 0x7009, 0x7009, 0x7009, 0x7009, 0x7009,
+ 0x7009, 0x7019, 0x7019, 0x7019, 0x7019, 0x7009, 0x7009, 0x7009,
+ 0x7019, 0x1078, 0x12d2, 0x1078, 0x578f, 0x6003, 0x0002, 0x1078,
+ 0x5888, 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a,
+ 0x007c, 0x1078, 0x578f, 0x6003, 0x000f, 0x1078, 0x5888, 0x007c,
+ 0xa182, 0x0040, 0x0079, 0x7024, 0x7037, 0x7037, 0x7037, 0x7037,
+ 0x7037, 0x7039, 0x70cf, 0x70ef, 0x7037, 0x7037, 0x7037, 0x7037,
+ 0x7037, 0x7037, 0x7037, 0x7037, 0x7037, 0x7037, 0x7037, 0x1078,
+ 0x12d2, 0x0e7e, 0x0d7e, 0x2071, 0x8d8c, 0x6110, 0x2168, 0x7614,
+ 0xa6b4, 0x0fff, 0x86ff, 0x0040, 0x70b3, 0xa68c, 0x0c00, 0x0040,
+ 0x704d, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186,
+ 0x0002, 0x0040, 0x706b, 0xa186, 0x0028, 0x00c0, 0x705d, 0x1078,
+ 0x79af, 0x684b, 0x001c, 0x0078, 0x706d, 0xd6dc, 0x0040, 0x7064,
+ 0x684b, 0x0015, 0x0078, 0x706d, 0xd6d4, 0x0040, 0x706b, 0x684b,
+ 0x0007, 0x0078, 0x706d, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46,
+ 0xa01e, 0xd6c4, 0x0040, 0x708d, 0xa686, 0x0100, 0x00c0, 0x7081,
+ 0x2001, 0x8d99, 0x2004, 0xa005, 0x00c0, 0x7081, 0xc6c4, 0x0078,
+ 0x7042, 0x7328, 0x732c, 0x6b56, 0x037e, 0x2308, 0x2019, 0x8d98,
+ 0xad90, 0x0019, 0x1078, 0x7589, 0x037f, 0xd6cc, 0x0040, 0x70c3,
+ 0x7124, 0x695a, 0xa192, 0x0021, 0x00c8, 0x70a1, 0x2071, 0x8d98,
+ 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x7589, 0x0078,
+ 0x70c3, 0x6838, 0xd0fc, 0x0040, 0x70aa, 0x2009, 0x0020, 0x695a,
+ 0x0078, 0x7096, 0x0f7e, 0x2d78, 0x1078, 0x7521, 0x0f7f, 0x1078,
+ 0x7576, 0x0078, 0x70c5, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46,
+ 0x684c, 0xd0ac, 0x0040, 0x70c3, 0x6810, 0x6914, 0xa115, 0x0040,
+ 0x70c3, 0x1078, 0x7248, 0x1078, 0x4376, 0x6218, 0x2268, 0x6a3c,
+ 0x8211, 0x6a3e, 0x0d7f, 0x0e7f, 0x1078, 0x690e, 0x007c, 0x0f7e,
+ 0x6003, 0x0003, 0x2079, 0x8d8c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08,
+ 0x6010, 0x2078, 0x784c, 0xd0ac, 0x0040, 0x70e2, 0x6003, 0x0002,
+ 0x0f7f, 0x007c, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x0f7f, 0x2c10,
+ 0x1078, 0x1b07, 0x1078, 0x5405, 0x1078, 0x5948, 0x007c, 0x6003,
+ 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078,
+ 0x1594, 0x007c, 0xa182, 0x0040, 0x0079, 0x70fe, 0x7111, 0x7111,
+ 0x7111, 0x7111, 0x7111, 0x7113, 0x71aa, 0x7111, 0x7111, 0x71c0,
+ 0x7222, 0x7111, 0x7111, 0x7111, 0x7111, 0x722d, 0x7111, 0x7111,
+ 0x7111, 0x1078, 0x12d2, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071,
+ 0x8d8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c,
+ 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff,
+ 0x0040, 0x71a5, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0040, 0x7134,
+ 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0040, 0x71a5,
+ 0x1078, 0x132b, 0x1040, 0x12d2, 0x2d00, 0x784a, 0x7f4c, 0xc7cd,
+ 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840,
+ 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0040, 0x7152, 0x7318, 0x6b62,
+ 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, 0x716e,
+ 0xa186, 0x0028, 0x00c0, 0x7160, 0x684b, 0x001c, 0x0078, 0x7170,
+ 0xd6dc, 0x0040, 0x7167, 0x684b, 0x0015, 0x0078, 0x7170, 0xd6d4,
+ 0x0040, 0x716e, 0x684b, 0x0007, 0x0078, 0x7170, 0x684b, 0x0000,
+ 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0040,
+ 0x7185, 0x7328, 0x732c, 0x6b56, 0x037e, 0x2308, 0x2019, 0x8d98,
+ 0xad90, 0x0019, 0x1078, 0x7589, 0x037f, 0xd6cc, 0x0040, 0x71a5,
+ 0x7124, 0x695a, 0xa192, 0x0021, 0x00c8, 0x7199, 0x2071, 0x8d98,
+ 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x7589, 0x0078,
+ 0x71a5, 0x7838, 0xd0fc, 0x0040, 0x71a2, 0x2009, 0x0020, 0x695a,
+ 0x0078, 0x718e, 0x2d78, 0x1078, 0x7521, 0x0d7f, 0x0e7f, 0x0f7f,
+ 0x077f, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0x8d8c, 0x7c04,
+ 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a,
+ 0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x1b07, 0x1078, 0x6217, 0x007c,
+ 0x0d7e, 0x6003, 0x0002, 0x1078, 0x5837, 0x1078, 0x5948, 0x6110,
+ 0x2168, 0x694c, 0xd1e4, 0x0040, 0x7220, 0xd1cc, 0x0040, 0x71fb,
+ 0x6948, 0x6838, 0xd0fc, 0x0040, 0x71f3, 0x017e, 0x684c, 0x007e,
+ 0x6850, 0x007e, 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0020,
+ 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x00f0, 0x71e2,
+ 0x157f, 0x007f, 0x6852, 0x007f, 0x684e, 0x017f, 0x2168, 0x1078,
+ 0x1354, 0x0078, 0x721e, 0x017e, 0x1078, 0x1354, 0x0d7f, 0x1078,
+ 0x7576, 0x0078, 0x721e, 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff,
+ 0xa0b6, 0x0002, 0x0040, 0x721a, 0xa086, 0x0028, 0x00c0, 0x720c,
+ 0x684b, 0x001c, 0x0078, 0x721c, 0xd1dc, 0x0040, 0x7213, 0x684b,
+ 0x0015, 0x0078, 0x721c, 0xd1d4, 0x0040, 0x721a, 0x684b, 0x0007,
+ 0x0078, 0x721c, 0x684b, 0x0000, 0x1078, 0x4376, 0x1078, 0x690e,
+ 0x0d7f, 0x007c, 0x2019, 0x0001, 0x1078, 0x642d, 0x6003, 0x0002,
+ 0x1078, 0x5837, 0x1078, 0x5948, 0x007c, 0x1078, 0x5837, 0x1078,
+ 0x24bf, 0x0d7e, 0x6110, 0x2168, 0x1078, 0x77ed, 0x0040, 0x7242,
+ 0x6837, 0x0103, 0x684b, 0x0029, 0x6847, 0x0000, 0x1078, 0x4376,
+ 0x1078, 0x799b, 0x0d7f, 0x1078, 0x690e, 0x1078, 0x5948, 0x007c,
+ 0x684b, 0x0015, 0xd1fc, 0x0040, 0x7254, 0x684b, 0x0007, 0x8002,
+ 0x8000, 0x810a, 0xa189, 0x0000, 0x6962, 0x685e, 0x007c, 0xa182,
+ 0x0040, 0x0079, 0x725b, 0x726e, 0x726e, 0x726e, 0x726e, 0x726e,
+ 0x7270, 0x726e, 0x7324, 0x732c, 0x726e, 0x726e, 0x726e, 0x726e,
+ 0x726e, 0x726e, 0x726e, 0x726e, 0x726e, 0x726e, 0x1078, 0x12d2,
+ 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0x8d8c, 0x6110, 0x2178,
+ 0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218,
+ 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x7314, 0xa694,
+ 0xff00, 0xa284, 0x0c00, 0x0040, 0x7291, 0x7018, 0x7862, 0x701c,
+ 0x785e, 0xa284, 0x0300, 0x0040, 0x7311, 0xa686, 0x0100, 0x00c0,
+ 0x72a3, 0x2001, 0x8d99, 0x2004, 0xa005, 0x00c0, 0x72a3, 0xc6c4,
+ 0x7e46, 0x0078, 0x7284, 0x1078, 0x132b, 0x1040, 0x12d2, 0x2d00,
+ 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838,
+ 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00,
+ 0x0040, 0x72be, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff,
+ 0xa186, 0x0002, 0x0040, 0x72da, 0xa186, 0x0028, 0x00c0, 0x72cc,
+ 0x684b, 0x001c, 0x0078, 0x72dc, 0xd6dc, 0x0040, 0x72d3, 0x684b,
+ 0x0015, 0x0078, 0x72dc, 0xd6d4, 0x0040, 0x72da, 0x684b, 0x0007,
+ 0x0078, 0x72dc, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854,
+ 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x72f1, 0x7328, 0x732c, 0x6b56,
+ 0x037e, 0x2308, 0x2019, 0x8d98, 0xad90, 0x0019, 0x1078, 0x7589,
+ 0x037f, 0xd6cc, 0x0040, 0x7311, 0x7124, 0x695a, 0xa192, 0x0021,
+ 0x00c8, 0x7305, 0x2071, 0x8d98, 0x831c, 0x2300, 0xae18, 0xad90,
+ 0x001d, 0x1078, 0x7589, 0x0078, 0x7311, 0x7838, 0xd0fc, 0x0040,
+ 0x730e, 0x2009, 0x0020, 0x695a, 0x0078, 0x72fa, 0x2d78, 0x1078,
+ 0x7521, 0xd6dc, 0x00c0, 0x7317, 0xa006, 0x0078, 0x731d, 0x2001,
+ 0x0001, 0x2071, 0x8d8c, 0x7218, 0x731c, 0x1078, 0x15e5, 0x0d7f,
+ 0x0e7f, 0x0f7f, 0x077f, 0x007c, 0x20e1, 0x0005, 0x3d18, 0x3e20,
+ 0x2c10, 0x1078, 0x1594, 0x007c, 0x0d7e, 0x6003, 0x0002, 0x6110,
+ 0x2168, 0x694c, 0xd1e4, 0x0040, 0x73c5, 0xd1cc, 0x0040, 0x7395,
+ 0x6948, 0x6838, 0xd0fc, 0x0040, 0x7371, 0x017e, 0x684c, 0x007e,
+ 0x6850, 0x007e, 0x684c, 0xd0ac, 0x0040, 0x7357, 0x6810, 0x6914,
+ 0xa115, 0x0040, 0x7357, 0x1078, 0x7248, 0x0f7e, 0x6948, 0x2178,
+ 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0x0f7f, 0x6948,
+ 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8,
+ 0x2304, 0x2012, 0x8318, 0x8210, 0x00f0, 0x7360, 0x157f, 0x007f,
+ 0x6852, 0x007f, 0x684e, 0x017f, 0x2168, 0x1078, 0x1354, 0x0078,
+ 0x73c3, 0x017e, 0x684c, 0xd0ac, 0x0040, 0x7389, 0x6810, 0x6914,
+ 0xa115, 0x0040, 0x7389, 0x1078, 0x7248, 0x0f7e, 0x6948, 0x2178,
+ 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e,
+ 0x0f7f, 0x6948, 0xa188, 0x0013, 0x684c, 0x200a, 0x1078, 0x1354,
+ 0x0d7f, 0x1078, 0x7576, 0x0078, 0x73c3, 0x6837, 0x0103, 0x6944,
+ 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040, 0x73b4, 0xa086, 0x0028,
+ 0x00c0, 0x73a6, 0x684b, 0x001c, 0x0078, 0x73c1, 0xd1dc, 0x0040,
+ 0x73ad, 0x684b, 0x0015, 0x0078, 0x73c1, 0xd1d4, 0x0040, 0x73b4,
+ 0x684b, 0x0007, 0x0078, 0x73c1, 0x684b, 0x0000, 0x684c, 0xd0ac,
+ 0x0040, 0x73c1, 0x6810, 0x6914, 0xa115, 0x0040, 0x73c1, 0x1078,
+ 0x7248, 0x1078, 0x4376, 0x1078, 0x690e, 0x0d7f, 0x007c, 0x1078,
+ 0x578f, 0x0078, 0x73cd, 0x1078, 0x5837, 0x1078, 0x77ed, 0x0040,
+ 0x73e6, 0x0d7e, 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0x880c,
+ 0x210c, 0xd18c, 0x00c0, 0x73f1, 0xd184, 0x00c0, 0x73ed, 0x6108,
+ 0x694a, 0x6847, 0x0000, 0x1078, 0x4376, 0x0d7f, 0x1078, 0x690e,
+ 0x1078, 0x5888, 0x1078, 0x5948, 0x007c, 0x684b, 0x0004, 0x0078,
+ 0x73e1, 0x684b, 0x0004, 0x0078, 0x73e1, 0xa182, 0x0040, 0x0079,
+ 0x73f9, 0x740c, 0x740c, 0x740c, 0x740c, 0x740c, 0x740e, 0x740c,
+ 0x7411, 0x740c, 0x740c, 0x740c, 0x740c, 0x740c, 0x740c, 0x740c,
+ 0x740c, 0x740c, 0x740c, 0x740c, 0x1078, 0x12d2, 0x1078, 0x690e,
+ 0x007c, 0x007e, 0x027e, 0xa016, 0x1078, 0x1594, 0x027f, 0x007f,
+ 0x007c, 0xa182, 0x0085, 0x0079, 0x741d, 0x7426, 0x7424, 0x7424,
+ 0x7424, 0x7424, 0x7424, 0x7424, 0x1078, 0x12d2, 0x6003, 0x000b,
+ 0x6106, 0x1078, 0x5399, 0x127e, 0x2091, 0x8000, 0x1078, 0x5888,
+ 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x743c, 0x6004, 0xa082,
+ 0x0085, 0x2008, 0x0079, 0x7477, 0xa186, 0x0027, 0x00c0, 0x745f,
+ 0x1078, 0x578f, 0x1078, 0x24bf, 0x0d7e, 0x6010, 0x2068, 0x1078,
+ 0x77ed, 0x0040, 0x7455, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b,
+ 0x0029, 0x1078, 0x4376, 0x1078, 0x799b, 0x0d7f, 0x1078, 0x690e,
+ 0x1078, 0x5888, 0x007c, 0x1078, 0x6950, 0x0078, 0x745a, 0xa186,
+ 0x0014, 0x00c0, 0x745b, 0x1078, 0x578f, 0x0d7e, 0x6010, 0x2068,
+ 0x1078, 0x77ed, 0x0040, 0x7455, 0x6837, 0x0103, 0x6847, 0x0000,
+ 0x684b, 0x0006, 0x6850, 0xc0ec, 0x6852, 0x0078, 0x7451, 0x7480,
+ 0x747e, 0x747e, 0x747e, 0x747e, 0x747e, 0x7489, 0x1078, 0x12d2,
+ 0x1078, 0x578f, 0x6017, 0x0014, 0x6003, 0x000c, 0x1078, 0x5888,
+ 0x007c, 0x1078, 0x578f, 0x6017, 0x0014, 0x6003, 0x000e, 0x1078,
+ 0x5888, 0x007c, 0xa182, 0x008c, 0x00c8, 0x749c, 0xa182, 0x0085,
+ 0x0048, 0x749c, 0x0079, 0x749f, 0x1078, 0x6950, 0x007c, 0x74a6,
+ 0x74a6, 0x74a6, 0x74a6, 0x74a8, 0x74d0, 0x74a6, 0x1078, 0x12d2,
+ 0x0d7e, 0x1078, 0x799b, 0x1078, 0x77ed, 0x0040, 0x74cc, 0x6010,
+ 0x2068, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, 0x74bd, 0x684b,
+ 0x0006, 0xc0ec, 0x6852, 0x0078, 0x74c8, 0xd0bc, 0x0040, 0x74c4,
+ 0x684b, 0x0002, 0x0078, 0x74c8, 0x684b, 0x0005, 0x1078, 0x7a4e,
+ 0x6847, 0x0000, 0x1078, 0x4376, 0x1078, 0x690e, 0x0d7f, 0x007c,
+ 0x0d7e, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, 0x74f4, 0x6837,
+ 0x0103, 0x6850, 0xd0b4, 0x0040, 0x74e3, 0xc0ec, 0x6852, 0x684b,
+ 0x0006, 0x0078, 0x74ee, 0xd0bc, 0x0040, 0x74ea, 0x684b, 0x0002,
+ 0x0078, 0x74ee, 0x684b, 0x0005, 0x1078, 0x7a4e, 0x6847, 0x0000,
+ 0x1078, 0x4376, 0x1078, 0x799b, 0x0d7f, 0x1078, 0x690e, 0x007c,
+ 0x017e, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, 0x7508,
+ 0x6837, 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x1078, 0x4376,
+ 0x0d7f, 0x017f, 0xa186, 0x0013, 0x0040, 0x751a, 0xa186, 0x0014,
+ 0x0040, 0x751a, 0xa186, 0x0027, 0x0040, 0x751a, 0x1078, 0x6950,
+ 0x0078, 0x7520, 0x1078, 0x578f, 0x1078, 0x79a8, 0x1078, 0x5888,
0x007c, 0x057e, 0x067e, 0x0d7e, 0x0f7e, 0x2029, 0x0001, 0xa182,
- 0x0101, 0x00c8, 0x67e5, 0x0078, 0x67e7, 0x2009, 0x0100, 0x2130,
- 0x2069, 0x7c98, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, 0xaf90,
- 0x001d, 0x1078, 0x6841, 0xa6b2, 0x0020, 0x7804, 0xa06d, 0x0040,
- 0x67fb, 0x1078, 0x1350, 0x1078, 0x1327, 0x0040, 0x6825, 0x8528,
+ 0x0101, 0x00c8, 0x752d, 0x0078, 0x752f, 0x2009, 0x0100, 0x2130,
+ 0x2069, 0x8d98, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, 0xaf90,
+ 0x001d, 0x1078, 0x7589, 0xa6b2, 0x0020, 0x7804, 0xa06d, 0x0040,
+ 0x7543, 0x1078, 0x1354, 0x1078, 0x132b, 0x0040, 0x756d, 0x8528,
0x6837, 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d,
- 0x00c8, 0x6811, 0x2608, 0xad90, 0x000f, 0x1078, 0x6841, 0x0078,
- 0x6825, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90, 0x000f,
- 0x1078, 0x6841, 0x0078, 0x67fb, 0x0f7f, 0x852f, 0xa5ad, 0x0003,
- 0x7d36, 0xa5ac, 0x0000, 0x0078, 0x682a, 0x0f7f, 0x852f, 0xa5ad,
+ 0x00c8, 0x7559, 0x2608, 0xad90, 0x000f, 0x1078, 0x7589, 0x0078,
+ 0x756d, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90, 0x000f,
+ 0x1078, 0x7589, 0x0078, 0x7543, 0x0f7f, 0x852f, 0xa5ad, 0x0003,
+ 0x7d36, 0xa5ac, 0x0000, 0x0078, 0x7572, 0x0f7f, 0x852f, 0xa5ad,
0x0003, 0x7d36, 0x0d7f, 0x067f, 0x057f, 0x007c, 0x0f7e, 0x8dff,
- 0x0040, 0x683f, 0x6804, 0xa07d, 0x0040, 0x683d, 0x6807, 0x0000,
- 0x1078, 0x3b92, 0x2f68, 0x0078, 0x6832, 0x1078, 0x3b92, 0x0f7f,
- 0x007c, 0x157e, 0xa184, 0x0001, 0x0040, 0x6847, 0x8108, 0x810c,
- 0x21a8, 0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x00f0, 0x6849,
+ 0x0040, 0x7587, 0x6804, 0xa07d, 0x0040, 0x7585, 0x6807, 0x0000,
+ 0x1078, 0x4376, 0x2f68, 0x0078, 0x757a, 0x1078, 0x4376, 0x0f7f,
+ 0x007c, 0x157e, 0xa184, 0x0001, 0x0040, 0x758f, 0x8108, 0x810c,
+ 0x21a8, 0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x00f0, 0x7591,
0x157f, 0x007c, 0x127e, 0x2091, 0x8000, 0x601c, 0xa084, 0x000f,
- 0x1079, 0x685c, 0x127f, 0x007c, 0x686b, 0x6864, 0x6866, 0x6884,
- 0x6864, 0x6866, 0x6866, 0x6866, 0x1078, 0x12cd, 0xa006, 0x007c,
- 0xa085, 0x0001, 0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x6a58,
- 0x0040, 0x6881, 0xa00e, 0x2001, 0x0005, 0x1078, 0x3c22, 0x1078,
- 0x6c5c, 0x1078, 0x3b92, 0x1078, 0x5d1a, 0xa085, 0x0001, 0x0d7f,
- 0x007c, 0xa006, 0x0078, 0x687f, 0x6000, 0xa08a, 0x0010, 0x10c8,
- 0x12cd, 0x1079, 0x688c, 0x007c, 0x689c, 0x68b9, 0x689e, 0x68ca,
- 0x68b5, 0x689c, 0x6866, 0x686b, 0x686b, 0x6866, 0x6866, 0x6866,
- 0x6866, 0x6866, 0x6866, 0x6866, 0x1078, 0x12cd, 0x0d7e, 0x6010,
- 0x2068, 0x1078, 0x6a58, 0x0040, 0x68a7, 0x1078, 0x6c5c, 0x0d7f,
- 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078, 0x4941,
- 0x1078, 0x4d96, 0xa085, 0x0001, 0x007c, 0x1078, 0x166e, 0x0078,
- 0x689e, 0x0e7e, 0x2071, 0x7936, 0x7024, 0xac06, 0x00c0, 0x68c2,
- 0x1078, 0x57ee, 0x1078, 0x5725, 0x0e7f, 0x00c0, 0x689e, 0x1078,
- 0x6866, 0x007c, 0x037e, 0x0e7e, 0x2071, 0x7936, 0x703c, 0xac06,
- 0x00c0, 0x68da, 0x2019, 0x0000, 0x1078, 0x5880, 0x0e7f, 0x037f,
- 0x0078, 0x689e, 0x1078, 0x5b5c, 0x0e7f, 0x037f, 0x00c0, 0x689e,
- 0x1078, 0x6866, 0x007c, 0x0c7e, 0x601c, 0xa084, 0x000f, 0x1079,
- 0x68eb, 0x0c7f, 0x007c, 0x68fa, 0x6957, 0x69fc, 0x68fe, 0x68fa,
- 0x68fa, 0x72dd, 0x5d1a, 0x6957, 0x1078, 0x6be3, 0x00c0, 0x68fa,
- 0x1078, 0x5f6d, 0x007c, 0x6017, 0x0001, 0x007c, 0x6000, 0xa08a,
- 0x0010, 0x10c8, 0x12cd, 0x1079, 0x6906, 0x007c, 0x6916, 0x6918,
- 0x6938, 0x694a, 0x694a, 0x6916, 0x68fa, 0x68fa, 0x68fa, 0x694a,
- 0x694a, 0x6916, 0x6916, 0x6916, 0x6916, 0x6954, 0x1078, 0x12cd,
- 0x0e7e, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071, 0x7936,
- 0x7024, 0xac06, 0x0040, 0x6934, 0x1078, 0x5725, 0x6007, 0x0085,
- 0x6003, 0x000b, 0x601f, 0x0002, 0x6017, 0x0014, 0x1078, 0x4941,
- 0x1078, 0x4d96, 0x0e7f, 0x007c, 0x6017, 0x0001, 0x0078, 0x6932,
- 0x0d7e, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x0d7f, 0x6007,
- 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078, 0x4941, 0x1078,
- 0x4d96, 0x007c, 0x0d7e, 0x6017, 0x0001, 0x6010, 0x2068, 0x6850,
- 0xc0b5, 0x6852, 0x0d7f, 0x007c, 0x1078, 0x5d1a, 0x007c, 0x6000,
- 0xa08a, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x695f, 0x007c, 0x696f,
- 0x68fb, 0x6971, 0x696f, 0x6971, 0x696f, 0x696f, 0x696f, 0x68f4,
- 0x68f4, 0x696f, 0x696f, 0x696f, 0x696f, 0x696f, 0x696f, 0x1078,
- 0x12cd, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f,
- 0xa08a, 0x000c, 0x10c8, 0x12cd, 0x1079, 0x697f, 0x007c, 0x698b,
- 0x69aa, 0x698b, 0x69aa, 0x698b, 0x69aa, 0x698d, 0x6996, 0x698b,
- 0x69aa, 0x698b, 0x69a3, 0x1078, 0x12cd, 0x6004, 0xa08e, 0x0004,
- 0x0040, 0x69a5, 0xa08e, 0x0002, 0x0040, 0x69a5, 0x6004, 0x1078,
- 0x6be3, 0x0040, 0x69f4, 0xa08e, 0x0021, 0x0040, 0x69f8, 0xa08e,
- 0x0022, 0x0040, 0x69f4, 0x1078, 0x22b5, 0x1078, 0x5f6d, 0x1078,
- 0x5d1a, 0x007c, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016, 0x0040,
- 0x69e4, 0xa186, 0x0002, 0x00c0, 0x69d3, 0x6018, 0x2068, 0x68a0,
- 0xd0bc, 0x00c0, 0x69d3, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040,
- 0x69d3, 0x8001, 0x6842, 0x6013, 0x0000, 0x601f, 0x0007, 0x6017,
- 0x0398, 0x1078, 0x5cb4, 0x0040, 0x69d3, 0x2d00, 0x601a, 0x601f,
- 0x0001, 0x0078, 0x69e4, 0x0d7f, 0x0c7f, 0x1078, 0x5f6d, 0x1078,
- 0x22b5, 0x0e7e, 0x127e, 0x2091, 0x8000, 0x1078, 0x22d7, 0x127f,
- 0x0e7f, 0x1078, 0x5d1a, 0x007c, 0x2001, 0x0002, 0x1078, 0x37f4,
- 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x498e, 0x1078, 0x4d96,
- 0x0d7f, 0x0c7f, 0x0078, 0x69e3, 0x1078, 0x5f6d, 0x0078, 0x69a7,
- 0x1078, 0x5f7c, 0x0078, 0x69a7, 0x6000, 0xa08a, 0x0010, 0x10c8,
- 0x12cd, 0x1079, 0x6a04, 0x007c, 0x6a14, 0x6a14, 0x6a14, 0x6a14,
- 0x6a14, 0x6a14, 0x6a14, 0x6a14, 0x6a14, 0x68fa, 0x6a14, 0x68fb,
- 0x6a16, 0x68fb, 0x6a1f, 0x6a14, 0x1078, 0x12cd, 0x6007, 0x008b,
- 0x6003, 0x000d, 0x1078, 0x4941, 0x1078, 0x4d96, 0x007c, 0x1078,
- 0x6ba9, 0x1078, 0x6a58, 0x0040, 0x6a41, 0x1078, 0x22b5, 0x0d7e,
- 0x1078, 0x6a58, 0x0040, 0x6a34, 0x6010, 0x2068, 0x6837, 0x0103,
- 0x684b, 0x0006, 0x1078, 0x3b92, 0x0d7f, 0x601f, 0x0001, 0x6007,
- 0x0001, 0x6003, 0x0001, 0x1078, 0x498e, 0x1078, 0x4d96, 0x0078,
- 0x6a43, 0x1078, 0x5d1a, 0x007c, 0xa284, 0x0007, 0x00c0, 0x6a55,
- 0xa282, 0x7e00, 0x0048, 0x6a55, 0x2001, 0x7715, 0x2004, 0xa202,
- 0x00c8, 0x6a55, 0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x6a54,
- 0x027e, 0x0e7e, 0x2071, 0x7700, 0x6210, 0x7058, 0xa202, 0x0048,
- 0x6a6a, 0x705c, 0xa202, 0x00c8, 0x6a6a, 0xa085, 0x0001, 0x0e7f,
- 0x027f, 0x007c, 0xa006, 0x0078, 0x6a67, 0x0e7e, 0x0c7e, 0x037e,
- 0x007e, 0x127e, 0x2091, 0x8000, 0x2061, 0x7e00, 0x2071, 0x7700,
- 0x7344, 0x7060, 0xa302, 0x00c8, 0x6a93, 0x601c, 0xa206, 0x00c0,
- 0x6a8b, 0x1078, 0x6be3, 0x00c0, 0x6a87, 0x1078, 0x5f6d, 0x0c7e,
- 0x1078, 0x5d1a, 0x0c7f, 0xace0, 0x0008, 0x7054, 0xac02, 0x00c8,
- 0x6a93, 0x0078, 0x6a78, 0x127f, 0x007f, 0x037f, 0x0c7f, 0x0e7f,
- 0x007c, 0x0e7e, 0x0c7e, 0x017e, 0xa188, 0x7820, 0x210c, 0x81ff,
- 0x0040, 0x6ab1, 0x2061, 0x7e00, 0x2071, 0x7700, 0x017e, 0x1078,
- 0x5cb4, 0x017f, 0x0040, 0x6ab4, 0x611a, 0x1078, 0x22b5, 0x1078,
- 0x5d1a, 0xa006, 0x0078, 0x6ab6, 0xa085, 0x0001, 0x017f, 0x0c7f,
- 0x0e7f, 0x007c, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e,
- 0x1078, 0x5cb4, 0x057f, 0x0040, 0x6ad3, 0x6612, 0x651a, 0x601f,
- 0x0003, 0x2009, 0x004b, 0x1078, 0x5d41, 0xa085, 0x0001, 0x127f,
- 0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6acf, 0x0c7e, 0x057e,
- 0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, 0x5cb4, 0x057f,
- 0x0040, 0x6afd, 0x6013, 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e,
- 0x2560, 0x1078, 0x3a36, 0x0c7f, 0x1078, 0x4a7e, 0x1078, 0x49c1,
- 0x2c08, 0x1078, 0x747b, 0x2009, 0x004c, 0x1078, 0x5d41, 0xa085,
- 0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6af9,
- 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078,
- 0x5cb4, 0x057f, 0x0040, 0x6b28, 0x6612, 0x651a, 0x601f, 0x0003,
- 0x2019, 0x0005, 0x0c7e, 0x2560, 0x1078, 0x3a36, 0x0c7f, 0x1078,
- 0x4a7e, 0x1078, 0x49c1, 0x2c08, 0x1078, 0x747b, 0x2009, 0x004d,
- 0x1078, 0x5d41, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c,
- 0xa006, 0x0078, 0x6b24, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000,
- 0x62a0, 0x0c7e, 0x1078, 0x5cb4, 0x057f, 0x0040, 0x6b53, 0x6612,
- 0x651a, 0x601f, 0x0003, 0x2019, 0x0005, 0x0c7e, 0x2560, 0x1078,
- 0x3a36, 0x0c7f, 0x1078, 0x4a7e, 0x1078, 0x49c1, 0x2c08, 0x1078,
- 0x747b, 0x2009, 0x004e, 0x1078, 0x5d41, 0xa085, 0x0001, 0x127f,
- 0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6b4f, 0x0c7e, 0x127e,
- 0x2091, 0x8000, 0x0c7e, 0x1078, 0x5cb4, 0x017f, 0x0040, 0x6b6f,
- 0x660a, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x001f,
- 0x1078, 0x5d41, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006,
- 0x0078, 0x6b6c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078,
- 0x5cb4, 0x017f, 0x0040, 0x6b8b, 0x660a, 0x611a, 0x601f, 0x0008,
- 0x2d00, 0x6012, 0x2009, 0x0021, 0x1078, 0x5d41, 0xa085, 0x0001,
- 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6b88, 0x0c7e, 0x127e,
- 0x2091, 0x8000, 0x0c7e, 0x1078, 0x5cb4, 0x017f, 0x0040, 0x6ba6,
- 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x1078,
- 0x5d41, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
- 0x6ba3, 0x027e, 0x0d7e, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0040,
- 0x6bb3, 0x8211, 0x6a3e, 0x0d7f, 0x027f, 0x007c, 0x6013, 0x0000,
- 0x601f, 0x0007, 0x6017, 0x0014, 0x007c, 0x067e, 0x0c7e, 0x0d7e,
- 0x2031, 0x7752, 0x2634, 0xd6e4, 0x0040, 0x6bcb, 0x6618, 0x2660,
- 0x6e48, 0x1078, 0x3942, 0x0d7f, 0x0c7f, 0x067f, 0x007c, 0x007e,
- 0x017e, 0x6004, 0xa08e, 0x0002, 0x0040, 0x6be0, 0xa08e, 0x0003,
- 0x0040, 0x6be0, 0xa08e, 0x0004, 0x0040, 0x6be0, 0xa085, 0x0001,
- 0x017f, 0x007f, 0x007c, 0x007e, 0x017e, 0x6004, 0xa08e, 0x0000,
- 0x0040, 0x6bf8, 0xa08e, 0x001f, 0x0040, 0x6bf8, 0xa08e, 0x0028,
- 0x0040, 0x6bf8, 0xa08e, 0x0029, 0x0040, 0x6bf8, 0xa085, 0x0001,
- 0x017f, 0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e,
- 0x1078, 0x5cb4, 0x017f, 0x0040, 0x6c15, 0x611a, 0x601f, 0x0001,
- 0x2d00, 0x6012, 0x1078, 0x22b5, 0x2009, 0x0028, 0x1078, 0x5d41,
- 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x6c12,
- 0xa186, 0x0015, 0x00c0, 0x6c2d, 0x2011, 0x771e, 0x2204, 0xa086,
- 0x0074, 0x00c0, 0x6c2d, 0x1078, 0x61ea, 0x6003, 0x0001, 0x6007,
- 0x0029, 0x1078, 0x498e, 0x0078, 0x6c31, 0x1078, 0x5f6d, 0x1078,
- 0x5d1a, 0x007c, 0xa186, 0x0015, 0x00c0, 0x6c4f, 0x2011, 0x771e,
- 0x2204, 0xa086, 0x0014, 0x00c0, 0x6c4f, 0x0d7e, 0x6018, 0x2068,
- 0x1078, 0x38c8, 0x0d7f, 0x1078, 0x61f4, 0x00c0, 0x6c4f, 0x2001,
- 0x0006, 0x1078, 0x37f4, 0x1078, 0x5dc5, 0x0078, 0x6c53, 0x1078,
- 0x5f6d, 0x1078, 0x5d1a, 0x007c, 0x6848, 0xa086, 0x0005, 0x00c0,
- 0x6c5b, 0x1078, 0x6c5c, 0x007c, 0x6850, 0xc0ad, 0x6852, 0x007c,
- 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x6c6a,
- 0x067f, 0x007c, 0x6c7a, 0x6e51, 0x6f32, 0x6c7a, 0x6c7a, 0x6c7a,
- 0x6c7a, 0x6c7a, 0x6cb4, 0x6fa0, 0x6c7a, 0x6c7a, 0x6c7a, 0x6c7a,
- 0x6c7a, 0x6c7a, 0x1078, 0x12cd, 0x067e, 0x6000, 0xa0b2, 0x0010,
- 0x10c8, 0x12cd, 0x1079, 0x6c86, 0x067f, 0x007c, 0x6c96, 0x728c,
- 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x7267, 0x72d6,
- 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x6c96, 0x1078, 0x12cd,
- 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12cd, 0x1079, 0x6ca2,
- 0x067f, 0x007c, 0x6cb2, 0x70d8, 0x714a, 0x716c, 0x71b8, 0x6cb2,
- 0x6cb2, 0x7212, 0x6fac, 0x724f, 0x7253, 0x6cb2, 0x6cb2, 0x6cb2,
- 0x6cb2, 0x6cb2, 0x1078, 0x12cd, 0xa1b2, 0x0030, 0x10c8, 0x12cd,
- 0x2100, 0x0079, 0x6cbb, 0x6ceb, 0x6dc8, 0x6ceb, 0x6ceb, 0x6ceb,
- 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb,
- 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb,
- 0x6ceb, 0x6ceb, 0x6ced, 0x6d1c, 0x6d27, 0x6d4f, 0x6d55, 0x6d89,
- 0x6dc1, 0x6ceb, 0x6ceb, 0x6dd0, 0x6ceb, 0x6ceb, 0x6dd7, 0x6dde,
- 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6ceb, 0x6dfb, 0x6ceb, 0x6ceb,
- 0x6e06, 0x6ceb, 0x6ceb, 0x1078, 0x12cd, 0x1078, 0x3b3e, 0x6618,
- 0x0c7e, 0x2660, 0x1078, 0x385e, 0x0c7f, 0xa6b0, 0x0001, 0x2634,
- 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x6d0e, 0x1078, 0x73b7,
- 0x00c0, 0x6d49, 0x1078, 0x7355, 0x00c0, 0x6d0a, 0x6007, 0x0008,
- 0x0078, 0x6dc3, 0x6007, 0x0009, 0x0078, 0x6dc3, 0x1078, 0x754c,
- 0x0040, 0x6d18, 0x1078, 0x73b7, 0x0040, 0x6d02, 0x0078, 0x6d49,
- 0x6013, 0x1900, 0x0078, 0x6d0a, 0x6106, 0x1078, 0x7317, 0x6007,
- 0x0006, 0x0078, 0x6dc3, 0x6007, 0x0007, 0x0078, 0x6dc3, 0x0d7e,
- 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006,
- 0x0040, 0x6d39, 0xa686, 0x0004, 0x0040, 0x6d39, 0x0d7f, 0x0078,
- 0x6d49, 0x1078, 0x7415, 0x00c0, 0x6d44, 0x1078, 0x38c8, 0x6007,
- 0x000a, 0x0d7f, 0x0078, 0x6dc3, 0x6007, 0x000b, 0x0d7f, 0x0078,
- 0x6dc3, 0x1078, 0x22b5, 0x6007, 0x0001, 0x0078, 0x6dc3, 0x1078,
- 0x22b5, 0x6007, 0x000c, 0x0078, 0x6dc3, 0x1078, 0x3b3e, 0x6618,
+ 0x1079, 0x75a4, 0x127f, 0x007c, 0x75ba, 0x75ac, 0x75b5, 0x75d3,
+ 0x75ac, 0x75b5, 0x75ae, 0x75b5, 0x1078, 0x12d2, 0x037e, 0x2019,
+ 0x0010, 0x1078, 0x831c, 0x037f, 0x007c, 0xa006, 0x007c, 0xa085,
+ 0x0001, 0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040,
+ 0x75d0, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4454, 0x1078, 0x7a4e,
+ 0x1078, 0x4376, 0x1078, 0x690e, 0xa085, 0x0001, 0x0d7f, 0x007c,
+ 0xa006, 0x0078, 0x75ce, 0x6000, 0xa08a, 0x0010, 0x10c8, 0x12d2,
+ 0x1079, 0x75db, 0x007c, 0x75eb, 0x7608, 0x75ed, 0x7619, 0x7604,
+ 0x75eb, 0x75b5, 0x75ba, 0x75ba, 0x75b5, 0x75b5, 0x75b5, 0x75b5,
+ 0x75b5, 0x75b5, 0x75b5, 0x1078, 0x12d2, 0x0d7e, 0x6010, 0x2068,
+ 0x1078, 0x77ed, 0x0040, 0x75f6, 0x1078, 0x7a4e, 0x0d7f, 0x6007,
+ 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078, 0x5399, 0x1078,
+ 0x5888, 0xa085, 0x0001, 0x007c, 0x1078, 0x16af, 0x0078, 0x75ed,
+ 0x0e7e, 0x2071, 0x8aa2, 0x7024, 0xac06, 0x00c0, 0x7611, 0x1078,
+ 0x639b, 0x1078, 0x62b2, 0x0e7f, 0x00c0, 0x75ed, 0x1078, 0x75b5,
+ 0x007c, 0x037e, 0x0e7e, 0x2071, 0x8aa2, 0x703c, 0xac06, 0x00c0,
+ 0x7629, 0x2019, 0x0000, 0x1078, 0x642d, 0x0e7f, 0x037f, 0x0078,
+ 0x75ed, 0x1078, 0x6753, 0x0e7f, 0x037f, 0x00c0, 0x75ed, 0x1078,
+ 0x75b5, 0x007c, 0x0c7e, 0x601c, 0xa084, 0x000f, 0x1079, 0x763a,
+ 0x0c7f, 0x007c, 0x7649, 0x76ae, 0x777b, 0x764d, 0x7649, 0x7649,
+ 0x8311, 0x690e, 0x76ae, 0x1078, 0x79d5, 0x00c0, 0x7649, 0x1078,
+ 0x6bc7, 0x007c, 0x6017, 0x0001, 0x007c, 0x6010, 0xa080, 0x0019,
+ 0x2c02, 0x6000, 0xa08a, 0x0010, 0x10c8, 0x12d2, 0x1079, 0x7659,
+ 0x007c, 0x7669, 0x766b, 0x768b, 0x769d, 0x76aa, 0x7669, 0x7649,
+ 0x7649, 0x7649, 0x769d, 0x769d, 0x7669, 0x7669, 0x7669, 0x7669,
+ 0x76a7, 0x1078, 0x12d2, 0x0e7e, 0x6010, 0x2070, 0x7050, 0xc0b5,
+ 0x7052, 0x2071, 0x8aa2, 0x7024, 0xac06, 0x0040, 0x7687, 0x1078,
+ 0x62b2, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6017,
+ 0x0014, 0x1078, 0x5399, 0x1078, 0x5888, 0x0e7f, 0x007c, 0x6017,
+ 0x0001, 0x0078, 0x7685, 0x0d7e, 0x6010, 0x2068, 0x6850, 0xc0b5,
+ 0x6852, 0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002,
+ 0x1078, 0x5399, 0x1078, 0x5888, 0x007c, 0x0d7e, 0x6017, 0x0001,
+ 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x0d7f, 0x007c, 0x1078,
+ 0x690e, 0x007c, 0x1078, 0x16af, 0x0078, 0x768b, 0x6000, 0xa08a,
+ 0x0010, 0x10c8, 0x12d2, 0x1079, 0x76b6, 0x007c, 0x76c6, 0x764a,
+ 0x76c8, 0x76c6, 0x76c8, 0x76c6, 0x76c6, 0x76c6, 0x7643, 0x7643,
+ 0x76c6, 0x76c6, 0x76c6, 0x76c6, 0x76c6, 0x76c6, 0x1078, 0x12d2,
+ 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f, 0xa08a,
+ 0x000c, 0x10c8, 0x12d2, 0x1079, 0x76d6, 0x007c, 0x76e2, 0x7714,
+ 0x76e2, 0x7714, 0x76e2, 0x7714, 0x76e4, 0x76ed, 0x76e2, 0x7714,
+ 0x76e2, 0x76fe, 0x1078, 0x12d2, 0x6004, 0xa08e, 0x0004, 0x0040,
+ 0x770f, 0xa08e, 0x0002, 0x0040, 0x770f, 0x6004, 0x1078, 0x79d5,
+ 0x0040, 0x775e, 0xa08e, 0x0021, 0x0040, 0x7762, 0xa08e, 0x0022,
+ 0x0040, 0x775e, 0xa08e, 0x003d, 0x0040, 0x7762, 0xa08e, 0x0001,
+ 0x00c0, 0x770d, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff,
+ 0x0d7f, 0xa086, 0x0006, 0x0040, 0x770f, 0x1078, 0x24bf, 0x1078,
+ 0x6bc7, 0x1078, 0x79a8, 0x007c, 0x0c7e, 0x0d7e, 0x6104, 0xa186,
+ 0x0016, 0x0040, 0x774e, 0xa186, 0x0002, 0x00c0, 0x773d, 0x6018,
+ 0x2068, 0x68a0, 0xd0bc, 0x00c0, 0x7766, 0x6840, 0xa084, 0x00ff,
+ 0xa005, 0x0040, 0x773d, 0x8001, 0x6842, 0x6013, 0x0000, 0x601f,
+ 0x0007, 0x6017, 0x0398, 0x1078, 0x68a8, 0x0040, 0x773d, 0x2d00,
+ 0x601a, 0x601f, 0x0001, 0x0078, 0x774e, 0x0d7f, 0x0c7f, 0x1078,
+ 0x6bc7, 0x1078, 0x24bf, 0x0e7e, 0x127e, 0x2091, 0x8000, 0x1078,
+ 0x24e5, 0x127f, 0x0e7f, 0x1078, 0x79a8, 0x007c, 0x2001, 0x0002,
+ 0x1078, 0x3f05, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x53e6,
+ 0x1078, 0x5888, 0x0d7f, 0x0c7f, 0x0078, 0x774d, 0x1078, 0x6bc7,
+ 0x0078, 0x7711, 0x1078, 0x6bda, 0x0078, 0x7711, 0x0d7f, 0x0c7f,
+ 0x1078, 0x6bc7, 0x1078, 0x24bf, 0x0e7e, 0x127e, 0x2091, 0x8000,
+ 0x1078, 0x24e5, 0x6013, 0x0000, 0x601f, 0x0007, 0x6017, 0x0398,
+ 0x127f, 0x0e7f, 0x007c, 0x6000, 0xa08a, 0x0010, 0x10c8, 0x12d2,
+ 0x1079, 0x7783, 0x007c, 0x7793, 0x7793, 0x7793, 0x7793, 0x7793,
+ 0x7793, 0x7793, 0x7793, 0x7793, 0x7649, 0x7793, 0x764a, 0x7795,
+ 0x764a, 0x779e, 0x7793, 0x1078, 0x12d2, 0x6007, 0x008b, 0x6003,
+ 0x000d, 0x1078, 0x5399, 0x1078, 0x5888, 0x007c, 0x1078, 0x799b,
+ 0x1078, 0x77ed, 0x0040, 0x77d6, 0x1078, 0x24bf, 0x0d7e, 0x1078,
+ 0x77ed, 0x0040, 0x77b8, 0x6010, 0x2068, 0x6837, 0x0103, 0x684b,
+ 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x1078, 0x4376,
+ 0x2c68, 0x1078, 0x68a8, 0x0040, 0x77c6, 0x6818, 0x601a, 0x0c7e,
+ 0x2d60, 0x1078, 0x79a8, 0x0c7f, 0x0078, 0x77c7, 0x2d60, 0x0d7f,
+ 0x6013, 0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001,
+ 0x1078, 0x53e6, 0x1078, 0x5888, 0x0078, 0x77d8, 0x1078, 0x79a8,
+ 0x007c, 0xa284, 0x0003, 0x00c0, 0x77ea, 0xa282, 0x8f00, 0x0048,
+ 0x77ea, 0x2001, 0x8815, 0x2004, 0xa202, 0x00c8, 0x77ea, 0xa085,
+ 0x0001, 0x007c, 0xa006, 0x0078, 0x77e9, 0x027e, 0x0e7e, 0x2071,
+ 0x8800, 0x6210, 0x7058, 0xa202, 0x0048, 0x77ff, 0x705c, 0xa202,
+ 0x00c8, 0x77ff, 0xa085, 0x0001, 0x0e7f, 0x027f, 0x007c, 0xa006,
+ 0x0078, 0x77fc, 0x0e7e, 0x0c7e, 0x037e, 0x007e, 0x127e, 0x2091,
+ 0x8000, 0x2061, 0x8f00, 0x2071, 0x8800, 0x7344, 0x7060, 0xa302,
+ 0x00c8, 0x7828, 0x601c, 0xa206, 0x00c0, 0x7820, 0x1078, 0x79d5,
+ 0x00c0, 0x781c, 0x1078, 0x6bc7, 0x0c7e, 0x1078, 0x690e, 0x0c7f,
+ 0xace0, 0x000c, 0x7054, 0xac02, 0x00c8, 0x7828, 0x0078, 0x780d,
+ 0x127f, 0x007f, 0x037f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e,
+ 0x017e, 0xa188, 0x8934, 0x210c, 0x81ff, 0x0040, 0x7846, 0x2061,
+ 0x8f00, 0x2071, 0x8800, 0x017e, 0x1078, 0x68a8, 0x017f, 0x0040,
+ 0x7849, 0x611a, 0x1078, 0x24bf, 0x1078, 0x690e, 0xa006, 0x0078,
+ 0x784b, 0xa085, 0x0001, 0x017f, 0x0c7f, 0x0e7f, 0x007c, 0x0c7e,
+ 0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x68a8, 0x057f,
+ 0x0040, 0x7868, 0x6612, 0x651a, 0x601f, 0x0003, 0x2009, 0x004b,
+ 0x1078, 0x6939, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c,
+ 0xa006, 0x0078, 0x7864, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000,
+ 0x62a0, 0x0c7e, 0x1078, 0x68a8, 0x057f, 0x0040, 0x7896, 0x6013,
+ 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e, 0x2560, 0x1078, 0x418b,
+ 0x0c7f, 0x1078, 0x54f0, 0x087e, 0x2041, 0x0000, 0x1078, 0x5419,
+ 0x2c08, 0x1078, 0x84d2, 0x087f, 0x2009, 0x004c, 0x1078, 0x6939,
+ 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078,
+ 0x7892, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x68a8, 0x2c78,
+ 0x0c7f, 0x0040, 0x78b5, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003,
+ 0x2021, 0x0005, 0x1078, 0x78f9, 0x0040, 0x78b5, 0x2f60, 0x2009,
+ 0x004d, 0x1078, 0x6939, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f,
+ 0x007c, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x68a8, 0x2c78,
+ 0x0c7f, 0x0040, 0x78d5, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003,
+ 0x2021, 0x0005, 0x1078, 0x78f9, 0x0040, 0x78d5, 0x2f60, 0x2009,
+ 0x004e, 0x1078, 0x6939, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f,
+ 0x007c, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x68a8, 0x2c78,
+ 0x0c7f, 0x0040, 0x78f5, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003,
+ 0x2021, 0x0004, 0x1078, 0x78f9, 0x0040, 0x78f5, 0x2f60, 0x2009,
+ 0x0052, 0x1078, 0x6939, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f,
+ 0x007c, 0x097e, 0x087e, 0x127e, 0x2091, 0x8000, 0x1078, 0x4117,
+ 0x0040, 0x7906, 0x2001, 0x78fe, 0x0078, 0x790c, 0x1078, 0x40dd,
+ 0x0040, 0x7915, 0x2001, 0x7906, 0x007e, 0xa00e, 0x2400, 0x1078,
+ 0x4454, 0x1078, 0x4376, 0x007f, 0x007a, 0x2418, 0x1078, 0x5726,
+ 0x62a0, 0x2041, 0x0001, 0x2608, 0x1078, 0x550a, 0x1078, 0x5419,
+ 0x2f08, 0x2648, 0x1078, 0x84d2, 0x613c, 0x81ff, 0x1040, 0x55ae,
+ 0x127f, 0x087f, 0x097f, 0x007c, 0x0c7e, 0x127e, 0x2091, 0x8000,
+ 0x0c7e, 0x1078, 0x68a8, 0x017f, 0x0040, 0x7945, 0x660a, 0x611a,
+ 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x001f, 0x1078, 0x6939,
+ 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x7942,
+ 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x68a8, 0x017f,
+ 0x0040, 0x7961, 0x660a, 0x611a, 0x601f, 0x0008, 0x2d00, 0x6012,
+ 0x2009, 0x0021, 0x1078, 0x6939, 0xa085, 0x0001, 0x127f, 0x0c7f,
+ 0x007c, 0xa006, 0x0078, 0x795e, 0x0c7e, 0x127e, 0x2091, 0x8000,
+ 0x0c7e, 0x1078, 0x68a8, 0x017f, 0x0040, 0x797d, 0x660a, 0x611a,
+ 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x003d, 0x1078, 0x6939,
+ 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x797a,
+ 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x68a8, 0x017f,
+ 0x0040, 0x7998, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009,
+ 0x0000, 0x1078, 0x6939, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c,
+ 0xa006, 0x0078, 0x7995, 0x027e, 0x0d7e, 0x6218, 0x2268, 0x6a3c,
+ 0x82ff, 0x0040, 0x79a5, 0x8211, 0x6a3e, 0x0d7f, 0x027f, 0x007c,
+ 0x6013, 0x0000, 0x601f, 0x0007, 0x6017, 0x0014, 0x007c, 0x067e,
+ 0x0c7e, 0x0d7e, 0x2031, 0x8852, 0x2634, 0xd6e4, 0x0040, 0x79bd,
+ 0x6618, 0x2660, 0x6e48, 0x1078, 0x408b, 0x0d7f, 0x0c7f, 0x067f,
+ 0x007c, 0x007e, 0x017e, 0x6004, 0xa08e, 0x0002, 0x0040, 0x79d2,
+ 0xa08e, 0x0003, 0x0040, 0x79d2, 0xa08e, 0x0004, 0x0040, 0x79d2,
+ 0xa085, 0x0001, 0x017f, 0x007f, 0x007c, 0x007e, 0x017e, 0x6004,
+ 0xa08e, 0x0000, 0x0040, 0x79ea, 0xa08e, 0x001f, 0x0040, 0x79ea,
+ 0xa08e, 0x0028, 0x0040, 0x79ea, 0xa08e, 0x0029, 0x0040, 0x79ea,
+ 0xa085, 0x0001, 0x017f, 0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091,
+ 0x8000, 0x0c7e, 0x1078, 0x68a8, 0x017f, 0x0040, 0x7a07, 0x611a,
+ 0x601f, 0x0001, 0x2d00, 0x6012, 0x1078, 0x24bf, 0x2009, 0x0028,
+ 0x1078, 0x6939, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006,
+ 0x0078, 0x7a04, 0xa186, 0x0015, 0x00c0, 0x7a1f, 0x2011, 0x881f,
+ 0x2204, 0xa086, 0x0074, 0x00c0, 0x7a1f, 0x1078, 0x6e79, 0x6003,
+ 0x0001, 0x6007, 0x0029, 0x1078, 0x53e6, 0x0078, 0x7a23, 0x1078,
+ 0x6bc7, 0x1078, 0x690e, 0x007c, 0xa186, 0x0015, 0x00c0, 0x7a41,
+ 0x2011, 0x881f, 0x2204, 0xa086, 0x0014, 0x00c0, 0x7a41, 0x0d7e,
+ 0x6018, 0x2068, 0x1078, 0x400a, 0x0d7f, 0x1078, 0x6e83, 0x00c0,
+ 0x7a41, 0x2001, 0x0006, 0x1078, 0x3f05, 0x1078, 0x69c6, 0x0078,
+ 0x7a45, 0x1078, 0x6bc7, 0x1078, 0x690e, 0x007c, 0x6848, 0xa086,
+ 0x0005, 0x00c0, 0x7a4d, 0x1078, 0x7a4e, 0x007c, 0x6850, 0xc0ad,
+ 0x6852, 0x007c, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12d2,
+ 0x1079, 0x7a5c, 0x067f, 0x007c, 0x7a6c, 0x7d34, 0x7e2d, 0x7a6c,
+ 0x7a6c, 0x7a6c, 0x7a6c, 0x7a6c, 0x7aa6, 0x7ea4, 0x7a6c, 0x7a6c,
+ 0x7a6c, 0x7a6c, 0x7a6c, 0x7a6c, 0x1078, 0x12d2, 0x067e, 0x6000,
+ 0xa0b2, 0x0010, 0x10c8, 0x12d2, 0x1079, 0x7a78, 0x067f, 0x007c,
+ 0x7a88, 0x82ac, 0x7a88, 0x7a88, 0x7a88, 0x7a88, 0x7a88, 0x7a88,
+ 0x8276, 0x82fa, 0x7a88, 0x7a88, 0x7a88, 0x7a88, 0x7a88, 0x7a88,
+ 0x1078, 0x12d2, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x12d2,
+ 0x1079, 0x7a94, 0x067f, 0x007c, 0x7aa4, 0x7ff2, 0x80ac, 0x80d1,
+ 0x8120, 0x7aa4, 0x81df, 0x819b, 0x7eb0, 0x824e, 0x8262, 0x7aa4,
+ 0x7aa4, 0x7aa4, 0x7aa4, 0x7aa4, 0x1078, 0x12d2, 0xa1b2, 0x0040,
+ 0x10c8, 0x12d2, 0x2100, 0x0079, 0x7aad, 0x7aed, 0x7c63, 0x7aed,
+ 0x7aed, 0x7aed, 0x7c6b, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed,
+ 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed,
+ 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aef, 0x7b3d, 0x7b48, 0x7b82,
+ 0x7b9d, 0x7bf4, 0x7c4f, 0x7aed, 0x7aed, 0x7c6f, 0x7aed, 0x7aed,
+ 0x7c7e, 0x7c85, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7cb3,
+ 0x7aed, 0x7aed, 0x7cbe, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed,
+ 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed,
+ 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x7aed, 0x1078, 0x12d2, 0x1078,
+ 0x42a2, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x6218, 0x2270,
+ 0x72a0, 0x027e, 0x2019, 0x0029, 0x1078, 0x54f0, 0x087e, 0x2041,
+ 0x0000, 0x1078, 0x5419, 0x2c08, 0x1078, 0x84d2, 0x087f, 0x017f,
+ 0x2e60, 0x1078, 0x418b, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f,
+ 0x6618, 0x0c7e, 0x2660, 0x1078, 0x3fa0, 0x0c7f, 0xa6b0, 0x0001,
+ 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x7b2f, 0x1078,
+ 0x8406, 0x00c0, 0x7b7c, 0x1078, 0x83a4, 0x00c0, 0x7b2b, 0x6007,
+ 0x0008, 0x0078, 0x7c5e, 0x6007, 0x0009, 0x0078, 0x7c5e, 0x1078,
+ 0x85aa, 0x0040, 0x7b39, 0x1078, 0x8406, 0x0040, 0x7b23, 0x0078,
+ 0x7b7c, 0x6013, 0x1900, 0x0078, 0x7b2b, 0x6106, 0x1078, 0x834f,
+ 0x6007, 0x0006, 0x0078, 0x7c5e, 0x6007, 0x0007, 0x0078, 0x7c5e,
+ 0x1078, 0x8727, 0x00c0, 0x7cd3, 0x0d7e, 0x6618, 0x2668, 0x6e04,
+ 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x7b5e, 0xa686,
+ 0x0004, 0x0040, 0x7b5e, 0x0d7f, 0x0078, 0x7b7c, 0x1078, 0x846c,
+ 0x00c0, 0x7b77, 0xa686, 0x0006, 0x00c0, 0x7b70, 0x027e, 0x6218,
+ 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x1078, 0x2507, 0x027f,
+ 0x1078, 0x400a, 0x6007, 0x000a, 0x0d7f, 0x0078, 0x7c5e, 0x6007,
+ 0x000b, 0x0d7f, 0x0078, 0x7c5e, 0x1078, 0x24bf, 0x6007, 0x0001,
+ 0x0078, 0x7c5e, 0x1078, 0x8727, 0x00c0, 0x7cd3, 0x6618, 0x0d7e,
+ 0x2668, 0x6e04, 0x0d7f, 0xa686, 0x0707, 0x0040, 0x7b7c, 0x027e,
+ 0x6218, 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x1078, 0x2507,
+ 0x027f, 0x6007, 0x000c, 0x0078, 0x7c5e, 0x1078, 0x42a2, 0x6618,
0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048,
- 0x6d76, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x00c0, 0x6d49,
- 0x1078, 0x7424, 0x00c0, 0x6d70, 0x6007, 0x000e, 0x0078, 0x6dc3,
- 0x1078, 0x22b5, 0x6007, 0x000f, 0x0078, 0x6dc3, 0x1078, 0x754c,
- 0x0040, 0x6d83, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040,
- 0x6d68, 0x0078, 0x6d49, 0x6013, 0x1900, 0x6007, 0x0009, 0x0078,
- 0x6dc3, 0x1078, 0x3b3e, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684,
- 0x00ff, 0xa082, 0x0006, 0x0048, 0x6dae, 0xa6b4, 0xff00, 0x8637,
- 0xa686, 0x0006, 0x00c0, 0x6d49, 0x1078, 0x744f, 0x00c0, 0x6da8,
- 0x1078, 0x7355, 0x00c0, 0x6da8, 0x6007, 0x0010, 0x0078, 0x6dc3,
- 0x1078, 0x22b5, 0x6007, 0x0011, 0x0078, 0x6dc3, 0x1078, 0x754c,
- 0x0040, 0x6dbb, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040,
- 0x6d9c, 0x0078, 0x6d49, 0x6013, 0x1900, 0x6007, 0x0009, 0x0078,
- 0x6dc3, 0x6007, 0x0012, 0x6003, 0x0001, 0x1078, 0x498e, 0x007c,
- 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x498e, 0x0078, 0x6dc7,
- 0x6007, 0x0020, 0x6003, 0x0001, 0x1078, 0x498e, 0x007c, 0x6007,
- 0x0023, 0x6003, 0x0001, 0x1078, 0x498e, 0x007c, 0x017e, 0x027e,
- 0x2011, 0x7c88, 0x2214, 0x2c08, 0x1078, 0x7614, 0x00c0, 0x6def,
- 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x0078, 0x6df4, 0x1078,
- 0x5d1a, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x1078, 0x498e,
- 0x027f, 0x017f, 0x007c, 0x6106, 0x1078, 0x6e0d, 0x6007, 0x002b,
- 0x0078, 0x6dc3, 0x6007, 0x002c, 0x0078, 0x6dc3, 0x6106, 0x1078,
- 0x6e12, 0x6007, 0x002e, 0x0078, 0x6dc3, 0x0d7e, 0x1078, 0x6e38,
- 0x0d7f, 0x007c, 0x0d7e, 0x1078, 0x6e47, 0x00c0, 0x6e31, 0x680c,
- 0xa08c, 0xff00, 0x6824, 0xa084, 0x00ff, 0xa115, 0x6212, 0xd1e4,
- 0x0040, 0x6e26, 0x2009, 0x0001, 0x0078, 0x6e2d, 0xd1ec, 0x0040,
- 0x6e31, 0x2009, 0x0000, 0xa294, 0x00ff, 0x1078, 0x22f9, 0x0078,
- 0x6e35, 0xa085, 0x0001, 0x0078, 0x6e36, 0xa006, 0x0d7f, 0x007c,
- 0x2069, 0x7c8d, 0x6800, 0xa082, 0x0010, 0x00c8, 0x6e45, 0x6013,
- 0x0000, 0xa085, 0x0001, 0x0078, 0x6e46, 0xa006, 0x007c, 0x6013,
- 0x0000, 0x2069, 0x7c8c, 0x6808, 0xa084, 0xff00, 0xa086, 0x0800,
- 0x007c, 0x6004, 0xa0b2, 0x0030, 0x10c8, 0x12cd, 0xa1b6, 0x0013,
- 0x00c0, 0x6e5d, 0x2008, 0x0079, 0x6e70, 0xa1b6, 0x0027, 0x0040,
- 0x6e65, 0xa1b6, 0x0014, 0x10c0, 0x12cd, 0x2001, 0x0007, 0x1078,
- 0x3802, 0x1078, 0x4c9d, 0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c,
- 0x6ea0, 0x6ea2, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea2, 0x6eaa, 0x6f0d,
- 0x6ed0, 0x6f0d, 0x6ee4, 0x6f0d, 0x6eaa, 0x6f0d, 0x6f05, 0x6f0d,
- 0x6f05, 0x6f0d, 0x6f0d, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0,
- 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0, 0x6ea0,
- 0x6f0d, 0x6ea0, 0x6ea0, 0x6f0d, 0x6ea0, 0x6f0d, 0x6f0d, 0x6ea0,
- 0x6ea0, 0x6ea0, 0x6ea0, 0x6f0d, 0x6f0d, 0x6ea0, 0x6f0d, 0x6f0d,
- 0x1078, 0x12cd, 0x1078, 0x4c9d, 0x6003, 0x0002, 0x1078, 0x4d96,
- 0x0078, 0x6f13, 0x0f7e, 0x2079, 0x7751, 0x7804, 0x0f7f, 0xd0ac,
- 0x00c0, 0x6f0d, 0x2001, 0x0000, 0x1078, 0x37e0, 0x2001, 0x0002,
- 0x1078, 0x37f4, 0x1078, 0x4c9d, 0x601f, 0x0001, 0x6003, 0x0001,
- 0x6007, 0x0002, 0x1078, 0x498e, 0x1078, 0x4d96, 0x0c7e, 0x6118,
- 0x2160, 0x2009, 0x0001, 0x1078, 0x4696, 0x0c7f, 0x0078, 0x6f13,
- 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00, 0x8637,
- 0xa686, 0x0006, 0x0040, 0x6f0d, 0xa686, 0x0004, 0x0040, 0x6f0d,
- 0x2001, 0x0004, 0x0078, 0x6f0b, 0x2001, 0x7700, 0x2004, 0xa086,
- 0x0003, 0x00c0, 0x6eed, 0x1078, 0x2dd7, 0x2001, 0x0006, 0x1078,
- 0x6f14, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00,
- 0x8637, 0xa686, 0x0006, 0x0040, 0x6f0d, 0x2001, 0x0006, 0x0078,
- 0x6f0b, 0x2001, 0x0004, 0x0078, 0x6f0b, 0x2001, 0x0006, 0x1078,
- 0x6f14, 0x0078, 0x6f0d, 0x1078, 0x3802, 0x1078, 0x4c9d, 0x1078,
- 0x5d1a, 0x1078, 0x4d96, 0x007c, 0x017e, 0x0d7e, 0x6118, 0x2168,
- 0x6900, 0xd184, 0x0040, 0x6f2f, 0x6104, 0xa18e, 0x000a, 0x00c0,
- 0x6f27, 0x699c, 0xd1a4, 0x00c0, 0x6f27, 0x2001, 0x0007, 0x1078,
- 0x37f4, 0x2001, 0x0000, 0x1078, 0x37e0, 0x1078, 0x22d7, 0x0d7f,
- 0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084, 0xff00,
- 0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x12cd, 0xa1b6, 0x0015,
- 0x00c0, 0x6f46, 0x1079, 0x6f4d, 0x0078, 0x6f4c, 0xa1b6, 0x0016,
- 0x10c0, 0x12cd, 0x1079, 0x6f85, 0x007c, 0x5ff7, 0x5ff7, 0x5ff7,
- 0x5ff7, 0x5ff7, 0x5ff7, 0x5ff7, 0x6f59, 0x5ff7, 0x5ff7, 0x5ff7,
- 0x5ff7, 0x0f7e, 0x2079, 0x7751, 0x7804, 0x0f7f, 0xd0ac, 0x00c0,
- 0x6f75, 0x2001, 0x0000, 0x1078, 0x37e0, 0x2001, 0x0002, 0x1078,
- 0x37f4, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078,
- 0x498e, 0x1078, 0x4d96, 0x0078, 0x6f84, 0x2011, 0x7c83, 0x220c,
- 0x017e, 0x0c7e, 0x1078, 0x384c, 0x00c0, 0x6f84, 0x1078, 0x3637,
- 0x0c7f, 0x017f, 0x1078, 0x5d1a, 0x007c, 0x5ff7, 0x5ff7, 0x5ff7,
- 0x5ff7, 0x5ff7, 0x5ff7, 0x5ff7, 0x6f91, 0x5ff7, 0x5ff7, 0x5ff7,
- 0x5ff7, 0x1078, 0x61e7, 0x00c0, 0x6f9d, 0x6003, 0x0001, 0x6007,
- 0x0001, 0x1078, 0x498e, 0x0078, 0x6f9f, 0x1078, 0x5d1a, 0x007c,
- 0x6004, 0xa08a, 0x0030, 0x10c8, 0x12cd, 0x1078, 0x4c9d, 0x1078,
- 0x6bb6, 0x1078, 0x4d96, 0x007c, 0xa182, 0x0040, 0x0079, 0x6fb0,
- 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc2, 0x6fc0, 0x6fc0, 0x6fc0,
- 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0, 0x6fc0,
- 0x1078, 0x12cd, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e, 0x027e,
- 0x6106, 0x2071, 0x7c80, 0x7444, 0xa4a4, 0xe600, 0x0040, 0x7026,
- 0x2009, 0x0000, 0x0c7e, 0x1078, 0x4727, 0x2c68, 0x0c7f, 0x6a00,
- 0xa284, 0x0001, 0x0040, 0x7091, 0x1078, 0x47e6, 0x0040, 0x70bc,
- 0xa295, 0x0200, 0x6a02, 0x0078, 0x6feb, 0x2009, 0x0001, 0x2011,
- 0x0200, 0x1078, 0x47d0, 0x1078, 0x1327, 0x1040, 0x12cd, 0x6003,
- 0x0007, 0x2d00, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000,
- 0x6c5a, 0x2c00, 0x685e, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130,
- 0x694a, 0xa084, 0xff00, 0x6846, 0x684f, 0x0000, 0x6857, 0x0036,
- 0x1078, 0x3b92, 0xa486, 0x2000, 0x00c0, 0x7014, 0x2019, 0x0017,
- 0x1078, 0x75d9, 0x0078, 0x707e, 0xa486, 0x0400, 0x00c0, 0x701e,
- 0x2019, 0x0002, 0x1078, 0x75d9, 0x0078, 0x707e, 0xa486, 0x0200,
- 0x00c0, 0x7024, 0x1078, 0x75ca, 0x0078, 0x707e, 0x2009, 0x0000,
- 0x0c7e, 0x1078, 0x4727, 0x2c68, 0x0c7f, 0x6a00, 0xa284, 0x0001,
- 0x0040, 0x70d4, 0xa284, 0x0300, 0x00c0, 0x70cc, 0x6804, 0xa005,
- 0x0040, 0x70bc, 0x8001, 0x6806, 0x6003, 0x0007, 0x1078, 0x130c,
- 0x0040, 0x7085, 0x6013, 0x0000, 0x6803, 0x0000, 0x6837, 0x0116,
- 0x683b, 0x0000, 0x2c00, 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007,
- 0x7130, 0x6986, 0x6846, 0x6853, 0x003d, 0x7044, 0xa084, 0x0003,
- 0xa086, 0x0002, 0x00c0, 0x7060, 0x684f, 0x0040, 0x0078, 0x706a,
- 0xa086, 0x0001, 0x00c0, 0x7068, 0x684f, 0x0080, 0x0078, 0x706a,
- 0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, 0x7c90, 0xad90, 0x0015,
- 0x200c, 0x810f, 0x2112, 0x8000, 0x8210, 0x00f0, 0x7070, 0x200c,
- 0x6982, 0x8000, 0x200c, 0x697e, 0x1078, 0x3b92, 0x027f, 0x047f,
- 0x157f, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x6013, 0x0100, 0x6003,
- 0x0001, 0x6007, 0x0041, 0x1078, 0x4941, 0x1078, 0x4d96, 0x0078,
- 0x707e, 0x2069, 0x7c92, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200,
- 0x00c0, 0x70b0, 0x2069, 0x7c80, 0x686c, 0xa084, 0x00ff, 0x017e,
- 0x6110, 0xa18c, 0x0700, 0xa10d, 0x6112, 0x017f, 0x6003, 0x0001,
- 0x6007, 0x0043, 0x1078, 0x4941, 0x1078, 0x4d96, 0x0078, 0x707e,
- 0x6013, 0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x4941,
- 0x1078, 0x4d96, 0x0078, 0x707e, 0x6013, 0x0300, 0x0078, 0x70c2,
- 0x6013, 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x4941,
- 0x1078, 0x4d96, 0x0078, 0x707e, 0x6013, 0x0500, 0x0078, 0x70c2,
- 0x6013, 0x0600, 0x0078, 0x7091, 0x6013, 0x0200, 0x0078, 0x7091,
- 0xa186, 0x0013, 0x00c0, 0x70ea, 0x6004, 0xa08a, 0x0040, 0x1048,
- 0x12cd, 0xa08a, 0x0050, 0x10c8, 0x12cd, 0xa082, 0x0040, 0x2008,
- 0x0079, 0x711b, 0xa186, 0x0047, 0x00c0, 0x70f0, 0x0078, 0x714a,
- 0xa186, 0x0027, 0x0040, 0x70f8, 0xa186, 0x0014, 0x10c0, 0x12cd,
- 0x6004, 0xa082, 0x0040, 0x2008, 0x0079, 0x70fe, 0x710e, 0x7110,
- 0x7110, 0x710e, 0x710e, 0x710e, 0x710e, 0x710e, 0x710e, 0x710e,
- 0x710e, 0x710e, 0x710e, 0x710e, 0x710e, 0x710e, 0x1078, 0x12cd,
- 0x2001, 0x0007, 0x1078, 0x3802, 0x1078, 0x4c9d, 0x1078, 0x6bb6,
- 0x1078, 0x4d96, 0x007c, 0x712b, 0x713b, 0x7134, 0x7144, 0x712b,
- 0x712b, 0x712b, 0x712b, 0x712b, 0x712b, 0x712b, 0x712b, 0x712b,
- 0x712b, 0x712b, 0x712b, 0x1078, 0x12cd, 0x6010, 0xa088, 0x0013,
- 0x2104, 0xa085, 0x0400, 0x200a, 0x1078, 0x4c9d, 0x6003, 0x0002,
- 0x1078, 0x4d96, 0x007c, 0x1078, 0x4c9d, 0x1078, 0x47a8, 0x1078,
- 0x5d1a, 0x1078, 0x4d96, 0x007c, 0x1078, 0x4c9d, 0x2009, 0x0041,
- 0x0078, 0x7212, 0xa182, 0x0040, 0x0079, 0x714e, 0x715e, 0x7160,
- 0x715e, 0x715e, 0x715e, 0x715e, 0x715e, 0x7161, 0x715e, 0x715e,
- 0x715e, 0x715e, 0x715e, 0x715e, 0x715e, 0x715e, 0x1078, 0x12cd,
- 0x007c, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20,
- 0x2c10, 0x1078, 0x156a, 0x007c, 0xa182, 0x0040, 0x0079, 0x7170,
- 0x7180, 0x7180, 0x7180, 0x7180, 0x7180, 0x7180, 0x7180, 0x7180,
- 0x7180, 0x7182, 0x71a5, 0x7180, 0x7180, 0x7180, 0x7180, 0x71a5,
- 0x1078, 0x12cd, 0x1078, 0x4d45, 0x1078, 0x4e56, 0x6010, 0x0d7e,
- 0x2068, 0x684c, 0xd0fc, 0x0040, 0x7198, 0xa08c, 0x0003, 0xa18e,
- 0x0002, 0x0040, 0x719e, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x7212,
- 0x6003, 0x0007, 0x1078, 0x47a8, 0x0d7f, 0x007c, 0x1078, 0x47a8,
- 0x1078, 0x5d1a, 0x0d7f, 0x0078, 0x719d, 0x037e, 0x1078, 0x4d45,
- 0x1078, 0x4e56, 0x6010, 0x0d7e, 0x2068, 0x2019, 0x0004, 0x1078,
- 0x75fd, 0x1078, 0x6bb6, 0x6017, 0x0028, 0x0d7f, 0x037f, 0x007c,
- 0xa186, 0x0013, 0x00c0, 0x71c6, 0x6004, 0xa086, 0x0042, 0x10c0,
- 0x12cd, 0x1078, 0x4c9d, 0x1078, 0x4d96, 0x007c, 0xa186, 0x0027,
- 0x0040, 0x71ce, 0xa186, 0x0014, 0x00c0, 0x71de, 0x6004, 0xa086,
- 0x0042, 0x10c0, 0x12cd, 0x2001, 0x0007, 0x1078, 0x3802, 0x1078,
- 0x4c9d, 0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c, 0xa182, 0x0040,
- 0x0079, 0x71e2, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2,
- 0x71f2, 0x71f4, 0x7200, 0x71f2, 0x71f2, 0x71f2, 0x71f2, 0x71f2,
- 0x71f2, 0x71f2, 0x1078, 0x12cd, 0x037e, 0x047e, 0x20e1, 0x0005,
- 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x156a, 0x047f, 0x037f, 0x007c,
- 0x6010, 0x0d7e, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x720c, 0x2009,
- 0x0041, 0x0d7f, 0x0078, 0x7212, 0x6003, 0x0007, 0x1078, 0x47a8,
- 0x0d7f, 0x007c, 0xa182, 0x0040, 0x0079, 0x7216, 0x7226, 0x7228,
- 0x7234, 0x7240, 0x7226, 0x7226, 0x7226, 0x7226, 0x7226, 0x7226,
- 0x7226, 0x7226, 0x7226, 0x7226, 0x7226, 0x7226, 0x1078, 0x12cd,
- 0x6003, 0x0001, 0x6106, 0x1078, 0x4941, 0x127e, 0x2091, 0x8000,
- 0x1078, 0x4d96, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078,
- 0x4941, 0x127e, 0x2091, 0x8000, 0x1078, 0x4d96, 0x127f, 0x007c,
- 0x6003, 0x0003, 0x6106, 0x2c10, 0x1078, 0x19c7, 0x127e, 0x2091,
- 0x8000, 0x1078, 0x49ad, 0x1078, 0x4e56, 0x127f, 0x007c, 0x1078,
- 0x4c9d, 0x0078, 0x7255, 0x1078, 0x4d45, 0x6110, 0x81ff, 0x0040,
- 0x7262, 0x0d7e, 0x2168, 0x037e, 0x2019, 0x0029, 0x1078, 0x75fd,
- 0x037f, 0x0d7f, 0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c, 0xa182,
- 0x0085, 0x0079, 0x726b, 0x7272, 0x7272, 0x7272, 0x7274, 0x7272,
- 0x7272, 0x7272, 0x1078, 0x12cd, 0x027e, 0x0e7e, 0x2071, 0x7c80,
- 0x7220, 0x1078, 0x7517, 0x0040, 0x7281, 0x6007, 0x0086, 0x0078,
- 0x7283, 0x6007, 0x0087, 0x6003, 0x0001, 0x1078, 0x4941, 0x1078,
- 0x4d96, 0x0e7f, 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x729d,
- 0x6004, 0xa08a, 0x0085, 0x1048, 0x12cd, 0xa08a, 0x008c, 0x10c8,
- 0x12cd, 0xa082, 0x0085, 0x0079, 0x72b0, 0xa186, 0x0027, 0x0040,
- 0x72a5, 0xa186, 0x0014, 0x10c0, 0x12cd, 0x2001, 0x0007, 0x1078,
- 0x3802, 0x1078, 0x4c9d, 0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c,
- 0x72b7, 0x72b9, 0x72b9, 0x72b7, 0x72b7, 0x72b7, 0x72b7, 0x1078,
- 0x12cd, 0x1078, 0x4c9d, 0x1078, 0x5d1a, 0x1078, 0x4d96, 0x007c,
- 0xa182, 0x0085, 0x1048, 0x12cd, 0xa182, 0x008c, 0x10c8, 0x12cd,
- 0xa182, 0x0085, 0x0079, 0x72cc, 0x72d3, 0x72d3, 0x72d3, 0x72d5,
- 0x72d3, 0x72d3, 0x72d3, 0x1078, 0x12cd, 0x007c, 0x1078, 0x4c9d,
- 0x1078, 0x6bb6, 0x1078, 0x4d96, 0x007c, 0x037e, 0x2019, 0x000b,
- 0x1078, 0x72e6, 0x601f, 0x0006, 0x037f, 0x007c, 0x127e, 0x037e,
- 0x087e, 0x2091, 0x8000, 0x2c40, 0x1078, 0x5a2d, 0x00c0, 0x7313,
- 0x1078, 0x5ace, 0x00c0, 0x7313, 0x6000, 0xa086, 0x0000, 0x0040,
- 0x7313, 0x601c, 0xa086, 0x0007, 0x0040, 0x7313, 0x0d7e, 0x6000,
- 0xa086, 0x0004, 0x00c0, 0x7306, 0x1078, 0x166e, 0x6010, 0x2068,
- 0x1078, 0x6a58, 0x0040, 0x730e, 0x1078, 0x75fd, 0x0d7f, 0x6013,
+ 0x7be1, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004, 0x0040, 0x7bb4,
+ 0xa686, 0x0006, 0x00c0, 0x7b7c, 0x1078, 0x847b, 0x00c0, 0x7bbc,
+ 0x6007, 0x000e, 0x0078, 0x7c5e, 0x047e, 0x6418, 0xa4a0, 0x0028,
+ 0x2424, 0xa4a4, 0x00ff, 0x8427, 0x047e, 0x1078, 0x24bf, 0x047f,
+ 0x017e, 0xa006, 0x2009, 0x8852, 0x210c, 0xd1a4, 0x0040, 0x7bdb,
+ 0x2009, 0x0029, 0x1078, 0x86f5, 0x6018, 0x0d7e, 0x2068, 0x6800,
+ 0xc0e5, 0x6802, 0x0d7f, 0x017f, 0x047f, 0x6007, 0x0001, 0x0078,
+ 0x7c5e, 0x1078, 0x85aa, 0x0040, 0x7bee, 0xa6b4, 0xff00, 0x8637,
+ 0xa686, 0x0006, 0x0040, 0x7bb4, 0x0078, 0x7b7c, 0x6013, 0x1900,
+ 0x6007, 0x0009, 0x0078, 0x7c5e, 0x1078, 0x42a2, 0x6618, 0xa6b0,
+ 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x7c3c,
+ 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004, 0x0040, 0x7c0b, 0xa686,
+ 0x0006, 0x00c0, 0x7b7c, 0x1078, 0x84a6, 0x00c0, 0x7c17, 0x1078,
+ 0x83a4, 0x00c0, 0x7c17, 0x6007, 0x0010, 0x0078, 0x7c5e, 0x047e,
+ 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427, 0x047e,
+ 0x1078, 0x24bf, 0x047f, 0x017e, 0xa006, 0x2009, 0x8852, 0x210c,
+ 0xd1a4, 0x0040, 0x7c36, 0x2009, 0x0029, 0x1078, 0x86f5, 0x6018,
+ 0x0d7e, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x0d7f, 0x017f, 0x047f,
+ 0x6007, 0x0001, 0x0078, 0x7c5e, 0x1078, 0x85aa, 0x0040, 0x7c49,
+ 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x7c0b, 0x0078,
+ 0x7b7c, 0x6013, 0x1900, 0x6007, 0x0009, 0x0078, 0x7c5e, 0x7030,
+ 0xa086, 0x6000, 0x0040, 0x7c5c, 0x1078, 0x8727, 0x00c0, 0x7cd3,
+ 0x1078, 0x7cd6, 0x00c0, 0x7b7c, 0x6007, 0x0012, 0x6003, 0x0001,
+ 0x1078, 0x53e6, 0x007c, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078,
+ 0x53e6, 0x0078, 0x7c62, 0x6007, 0x0005, 0x0078, 0x7c65, 0x1078,
+ 0x8727, 0x00c0, 0x7cd3, 0x1078, 0x7cd6, 0x00c0, 0x7b7c, 0x6007,
+ 0x0020, 0x6003, 0x0001, 0x1078, 0x53e6, 0x007c, 0x6007, 0x0023,
+ 0x6003, 0x0001, 0x1078, 0x53e6, 0x007c, 0x1078, 0x8727, 0x00c0,
+ 0x7cd3, 0x1078, 0x7cd6, 0x00c0, 0x7b7c, 0x017e, 0x027e, 0x2011,
+ 0x8d90, 0x2214, 0x2c08, 0x1078, 0x86c1, 0x00c0, 0x7ca7, 0x2160,
+ 0x6007, 0x0026, 0x6013, 0x1700, 0x2011, 0x8d89, 0x2214, 0xa296,
+ 0xffff, 0x00c0, 0x7cac, 0x6007, 0x0025, 0x0078, 0x7cac, 0x1078,
+ 0x690e, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x1078, 0x53e6,
+ 0x027f, 0x017f, 0x007c, 0x6106, 0x1078, 0x7ce9, 0x6007, 0x002b,
+ 0x0078, 0x7c5e, 0x6007, 0x002c, 0x0078, 0x7c5e, 0x1078, 0x8727,
+ 0x00c0, 0x7cd3, 0x1078, 0x7cd6, 0x00c0, 0x7b7c, 0x6106, 0x1078,
+ 0x7cee, 0x00c0, 0x7ccf, 0x6007, 0x002e, 0x0078, 0x7c5e, 0x6007,
+ 0x002f, 0x0078, 0x7c5e, 0x1078, 0x690e, 0x007c, 0x0d7e, 0x6618,
+ 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040,
+ 0x7ce7, 0xa686, 0x0004, 0x0040, 0x7ce7, 0xa085, 0x0001, 0x0d7f,
+ 0x007c, 0x0d7e, 0x1078, 0x7d1b, 0x0d7f, 0x007c, 0x0d7e, 0x1078,
+ 0x7d2a, 0x00c0, 0x7d14, 0x680c, 0xa08c, 0xff00, 0x6824, 0xa084,
+ 0x00ff, 0xa115, 0x6212, 0xd1e4, 0x0040, 0x7d02, 0x2009, 0x0001,
+ 0x0078, 0x7d10, 0xd1ec, 0x0040, 0x7d14, 0x6920, 0xa18c, 0x00ff,
+ 0x6824, 0x1078, 0x2245, 0x00c0, 0x7d14, 0x2110, 0x2009, 0x0000,
+ 0x1078, 0x2507, 0x0078, 0x7d18, 0xa085, 0x0001, 0x0078, 0x7d19,
+ 0xa006, 0x0d7f, 0x007c, 0x2069, 0x8d8d, 0x6800, 0xa082, 0x0010,
+ 0x00c8, 0x7d28, 0x6013, 0x0000, 0xa085, 0x0001, 0x0078, 0x7d29,
+ 0xa006, 0x007c, 0x6013, 0x0000, 0x2069, 0x8d8c, 0x6808, 0xa084,
+ 0xff00, 0xa086, 0x0800, 0x007c, 0x6004, 0xa0b2, 0x0040, 0x10c8,
+ 0x12d2, 0xa1b6, 0x0013, 0x00c0, 0x7d40, 0x2008, 0x0079, 0x7d53,
+ 0xa1b6, 0x0027, 0x0040, 0x7d48, 0xa1b6, 0x0014, 0x10c0, 0x12d2,
+ 0x2001, 0x0007, 0x1078, 0x3f2c, 0x1078, 0x578f, 0x1078, 0x79a8,
+ 0x1078, 0x5888, 0x007c, 0x7d93, 0x7d95, 0x7d93, 0x7d93, 0x7d93,
+ 0x7d95, 0x7d9d, 0x7e08, 0x7dcb, 0x7e08, 0x7ddf, 0x7e08, 0x7d9d,
+ 0x7e08, 0x7e00, 0x7e08, 0x7e00, 0x7e08, 0x7e08, 0x7d93, 0x7d93,
+ 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93,
+ 0x7d93, 0x7d93, 0x7d93, 0x7e08, 0x7d93, 0x7d93, 0x7e08, 0x7d93,
+ 0x7e08, 0x7e08, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7e08, 0x7e08,
+ 0x7d93, 0x7e08, 0x7e08, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93,
+ 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93, 0x7d93,
+ 0x7d93, 0x7d93, 0x7d93, 0x1078, 0x12d2, 0x1078, 0x578f, 0x6003,
+ 0x0002, 0x1078, 0x5888, 0x0078, 0x7e0e, 0x0f7e, 0x2079, 0x8851,
+ 0x7804, 0x0f7f, 0xd0ac, 0x00c0, 0x7e08, 0x2001, 0x0000, 0x1078,
+ 0x3ef1, 0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x0040,
+ 0x7e08, 0x2001, 0x0002, 0x1078, 0x3f05, 0x1078, 0x578f, 0x601f,
+ 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x53e6, 0x1078,
+ 0x5888, 0x0c7e, 0x6118, 0x2160, 0x2009, 0x0001, 0x1078, 0x50ff,
+ 0x0c7f, 0x0078, 0x7e0e, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f,
+ 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x7e08, 0xa686,
+ 0x0004, 0x0040, 0x7e08, 0x2001, 0x0004, 0x0078, 0x7e06, 0x2001,
+ 0x8800, 0x2004, 0xa086, 0x0003, 0x00c0, 0x7de8, 0x1078, 0x31f8,
+ 0x2001, 0x0006, 0x1078, 0x7e0f, 0x6618, 0x0d7e, 0x2668, 0x6e04,
+ 0x0d7f, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x7e08,
+ 0x2001, 0x0006, 0x0078, 0x7e06, 0x2001, 0x0004, 0x0078, 0x7e06,
+ 0x2001, 0x0006, 0x1078, 0x7e0f, 0x0078, 0x7e08, 0x1078, 0x3f2c,
+ 0x1078, 0x578f, 0x1078, 0x690e, 0x1078, 0x5888, 0x007c, 0x017e,
+ 0x0d7e, 0x6118, 0x2168, 0x6900, 0xd184, 0x0040, 0x7e2a, 0x6104,
+ 0xa18e, 0x000a, 0x00c0, 0x7e22, 0x699c, 0xd1a4, 0x00c0, 0x7e22,
+ 0x2001, 0x0007, 0x1078, 0x3f05, 0x2001, 0x0000, 0x1078, 0x3ef1,
+ 0x1078, 0x24e5, 0x0d7f, 0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668,
+ 0x6804, 0xa084, 0xff00, 0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8,
+ 0x12d2, 0xa1b6, 0x0015, 0x00c0, 0x7e41, 0x1079, 0x7e48, 0x0078,
+ 0x7e47, 0xa1b6, 0x0016, 0x10c0, 0x12d2, 0x1079, 0x7e89, 0x007c,
+ 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x7e54,
+ 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x0f7e, 0x2079, 0x8851, 0x7804,
+ 0x0f7f, 0xd0ac, 0x00c0, 0x7e70, 0x2001, 0x0000, 0x1078, 0x3ef1,
+ 0x2001, 0x0002, 0x1078, 0x3f05, 0x601f, 0x0001, 0x6003, 0x0001,
+ 0x6007, 0x0002, 0x1078, 0x53e6, 0x1078, 0x5888, 0x0078, 0x7e88,
+ 0x2011, 0x8d83, 0x2204, 0x8211, 0x220c, 0x1078, 0x2245, 0x00c0,
+ 0x7e88, 0x0c7e, 0x1078, 0x3f8e, 0x0040, 0x7e83, 0x0c7f, 0x1078,
+ 0x690e, 0x0078, 0x7e88, 0x1078, 0x3d31, 0x0c7f, 0x1078, 0x690e,
+ 0x007c, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e,
+ 0x7e95, 0x6c5e, 0x6c5e, 0x6c5e, 0x6c5e, 0x1078, 0x6e76, 0x00c0,
+ 0x7ea1, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x53e6, 0x0078,
+ 0x7ea3, 0x1078, 0x690e, 0x007c, 0x6004, 0xa08a, 0x0040, 0x10c8,
+ 0x12d2, 0x1078, 0x578f, 0x1078, 0x79a8, 0x1078, 0x5888, 0x007c,
+ 0xa182, 0x0040, 0x0079, 0x7eb4, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7,
+ 0x7ec9, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7,
+ 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, 0x7ec7, 0x1078,
+ 0x12d2, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e, 0x027e, 0x6106,
+ 0x2071, 0x8d80, 0x7444, 0xa4a4, 0xff00, 0x0040, 0x7f3e, 0xa486,
+ 0x2000, 0x0040, 0x7ef3, 0xa486, 0x0400, 0x0040, 0x7ef3, 0xa486,
+ 0x1000, 0x0040, 0x7ee5, 0x0078, 0x7ef9, 0x2069, 0x8b24, 0x6a00,
+ 0xd284, 0x0040, 0x7fab, 0x1078, 0x5253, 0x0040, 0x7fd6, 0xc2cd,
+ 0x6a02, 0x0078, 0x7ef9, 0x2009, 0x0001, 0x2011, 0x0200, 0x1078,
+ 0x5243, 0x1078, 0x132b, 0x1040, 0x12d2, 0x6003, 0x0007, 0x2d00,
+ 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00,
+ 0x685e, 0x6008, 0x68b2, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130,
+ 0x694a, 0x017e, 0xa084, 0xff00, 0x6846, 0x684f, 0x0000, 0x6857,
+ 0x0036, 0x1078, 0x4376, 0x017f, 0xa486, 0x2000, 0x00c0, 0x7f26,
+ 0x2019, 0x0017, 0x1078, 0x8683, 0x0078, 0x7f98, 0xa486, 0x0400,
+ 0x00c0, 0x7f30, 0x2019, 0x0002, 0x1078, 0x8644, 0x0078, 0x7f98,
+ 0xa486, 0x0200, 0x00c0, 0x7f36, 0x1078, 0x8631, 0xa486, 0x1000,
+ 0x00c0, 0x7f3c, 0x1078, 0x8670, 0x0078, 0x7f98, 0x2069, 0x8b24,
+ 0x6a00, 0xd284, 0x0040, 0x7fee, 0xa284, 0x0300, 0x00c0, 0x7fe6,
+ 0x6804, 0xa005, 0x0040, 0x7fd6, 0x2d78, 0x6003, 0x0007, 0x1078,
+ 0x1310, 0x0040, 0x7f9f, 0x7800, 0xd08c, 0x00c0, 0x7f5a, 0x7804,
+ 0x8001, 0x7806, 0x6013, 0x0000, 0x6803, 0x0000, 0x6837, 0x0116,
+ 0x683b, 0x0000, 0x6008, 0x68b2, 0x2c00, 0x684a, 0x6018, 0x2078,
+ 0x78a0, 0x8007, 0x7130, 0x6986, 0x6846, 0x6853, 0x003d, 0x7244,
+ 0xa294, 0x0003, 0xa286, 0x0002, 0x00c0, 0x7f7a, 0x684f, 0x0040,
+ 0x0078, 0x7f84, 0xa286, 0x0001, 0x00c0, 0x7f82, 0x684f, 0x0080,
+ 0x0078, 0x7f84, 0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, 0x8d90,
+ 0xad90, 0x0015, 0x200c, 0x810f, 0x2112, 0x8000, 0x8210, 0x00f0,
+ 0x7f8a, 0x200c, 0x6982, 0x8000, 0x200c, 0x697e, 0x1078, 0x4376,
+ 0x027f, 0x047f, 0x157f, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x6013,
+ 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5399, 0x1078,
+ 0x5888, 0x0078, 0x7f98, 0x2069, 0x8d92, 0x2d04, 0xa084, 0xff00,
+ 0xa086, 0x1200, 0x00c0, 0x7fca, 0x2069, 0x8d80, 0x686c, 0xa084,
+ 0x00ff, 0x017e, 0x6110, 0xa18c, 0x0700, 0xa10d, 0x6112, 0x017f,
+ 0x6003, 0x0001, 0x6007, 0x0043, 0x1078, 0x5399, 0x1078, 0x5888,
+ 0x0078, 0x7f98, 0x6013, 0x0200, 0x6003, 0x0001, 0x6007, 0x0041,
+ 0x1078, 0x5399, 0x1078, 0x5888, 0x0078, 0x7f98, 0x6013, 0x0300,
+ 0x0078, 0x7fdc, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007, 0x0041,
+ 0x1078, 0x5399, 0x1078, 0x5888, 0x0078, 0x7f98, 0x6013, 0x0500,
+ 0x0078, 0x7fdc, 0x6013, 0x0600, 0x0078, 0x7fab, 0x6013, 0x0200,
+ 0x0078, 0x7fab, 0xa186, 0x0013, 0x00c0, 0x8004, 0x6004, 0xa08a,
+ 0x0040, 0x1048, 0x12d2, 0xa08a, 0x0053, 0x10c8, 0x12d2, 0xa082,
+ 0x0040, 0x2008, 0x0079, 0x806b, 0xa186, 0x0047, 0x00c0, 0x8026,
+ 0x6004, 0xa086, 0x0041, 0x0040, 0x8034, 0x2001, 0x0109, 0x2004,
+ 0xd084, 0x0040, 0x8034, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e,
+ 0x027e, 0x1078, 0x5273, 0x027f, 0x017f, 0x007f, 0x127f, 0x6000,
+ 0xa086, 0x0002, 0x00c0, 0x8034, 0x0078, 0x80ac, 0xa186, 0x0027,
+ 0x0040, 0x802e, 0xa186, 0x0014, 0x10c0, 0x12d2, 0x6004, 0xa082,
+ 0x0040, 0x2008, 0x0079, 0x8037, 0x1078, 0x6950, 0x007c, 0x804a,
+ 0x804c, 0x804c, 0x804a, 0x804a, 0x804a, 0x804a, 0x804a, 0x804a,
+ 0x804a, 0x804a, 0x804a, 0x804a, 0x804a, 0x804a, 0x804a, 0x804a,
+ 0x804a, 0x804a, 0x1078, 0x12d2, 0x1078, 0x578f, 0x1078, 0x5888,
+ 0x037e, 0x0d7e, 0x6010, 0xa06d, 0x0040, 0x8068, 0xad84, 0xf000,
+ 0x0040, 0x8068, 0x2019, 0x0004, 0x1078, 0x86aa, 0x6013, 0x0000,
+ 0x6014, 0xa005, 0x00c0, 0x8066, 0x6017, 0x0014, 0x6003, 0x0007,
+ 0x0d7f, 0x037f, 0x007c, 0x807e, 0x809d, 0x8087, 0x80a6, 0x807e,
+ 0x807e, 0x807e, 0x807e, 0x807e, 0x807e, 0x807e, 0x807e, 0x807e,
+ 0x807e, 0x807e, 0x807e, 0x807e, 0x807e, 0x807e, 0x1078, 0x12d2,
+ 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x1078,
+ 0x578f, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4, 0x0040, 0x8098,
+ 0x6003, 0x0007, 0x2009, 0x0043, 0x1078, 0x6939, 0x0078, 0x809a,
+ 0x6003, 0x0002, 0x1078, 0x5888, 0x007c, 0x1078, 0x578f, 0x1078,
+ 0x5219, 0x1078, 0x690e, 0x1078, 0x5888, 0x007c, 0x1078, 0x578f,
+ 0x2009, 0x0041, 0x0078, 0x819b, 0xa182, 0x0040, 0x0079, 0x80b0,
+ 0x80c3, 0x80c5, 0x80c3, 0x80c3, 0x80c3, 0x80c3, 0x80c3, 0x80c6,
+ 0x80c3, 0x80c3, 0x80c3, 0x80c3, 0x80c3, 0x80c3, 0x80c3, 0x80c3,
+ 0x80c3, 0x80c3, 0x80c3, 0x1078, 0x12d2, 0x007c, 0x6003, 0x0004,
+ 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x1594,
+ 0x007c, 0xa182, 0x0040, 0x0079, 0x80d5, 0x80e8, 0x80e8, 0x80e8,
+ 0x80e8, 0x80e8, 0x80e8, 0x80e8, 0x80e8, 0x80e8, 0x80ea, 0x810d,
+ 0x80e8, 0x80e8, 0x80e8, 0x80e8, 0x810d, 0x80e8, 0x80e8, 0x80e8,
+ 0x1078, 0x12d2, 0x1078, 0x5837, 0x1078, 0x5948, 0x6010, 0x0d7e,
+ 0x2068, 0x684c, 0xd0fc, 0x0040, 0x8100, 0xa08c, 0x0003, 0xa18e,
+ 0x0002, 0x0040, 0x8106, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x819b,
+ 0x6003, 0x0007, 0x1078, 0x5219, 0x0d7f, 0x007c, 0x1078, 0x5219,
+ 0x1078, 0x690e, 0x0d7f, 0x0078, 0x8105, 0x037e, 0x1078, 0x5837,
+ 0x1078, 0x5948, 0x6010, 0x0d7e, 0x2068, 0x2019, 0x0004, 0x1078,
+ 0x86aa, 0x1078, 0x79a8, 0x6017, 0x0028, 0x0d7f, 0x037f, 0x007c,
+ 0xa186, 0x0013, 0x00c0, 0x812e, 0x6004, 0xa086, 0x0042, 0x10c0,
+ 0x12d2, 0x1078, 0x578f, 0x1078, 0x5888, 0x007c, 0xa186, 0x0027,
+ 0x0040, 0x8136, 0xa186, 0x0014, 0x00c0, 0x8146, 0x6004, 0xa086,
+ 0x0042, 0x10c0, 0x12d2, 0x2001, 0x0007, 0x1078, 0x3f2c, 0x1078,
+ 0x578f, 0x1078, 0x79a8, 0x1078, 0x5888, 0x007c, 0xa182, 0x0040,
+ 0x0079, 0x814a, 0x815d, 0x815d, 0x815d, 0x815d, 0x815d, 0x815d,
+ 0x815d, 0x815f, 0x816b, 0x815d, 0x815d, 0x815d, 0x815d, 0x815d,
+ 0x815d, 0x815d, 0x815d, 0x815d, 0x815d, 0x1078, 0x12d2, 0x037e,
+ 0x047e, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x1594,
+ 0x047f, 0x037f, 0x007c, 0x6010, 0x0d7e, 0x2068, 0x6810, 0x6a14,
+ 0xa20d, 0x00c0, 0x8182, 0x684c, 0xd0fc, 0x0040, 0x817c, 0x2009,
+ 0x0041, 0x0d7f, 0x0078, 0x819b, 0x6003, 0x0007, 0x1078, 0x5219,
+ 0x0d7f, 0x007c, 0x6003, 0x0006, 0x1078, 0x818a, 0x1078, 0x521b,
+ 0x0d7f, 0x007c, 0xd2fc, 0x0040, 0x8196, 0x8002, 0x8000, 0x8212,
+ 0xa291, 0x0000, 0x2009, 0x0009, 0x0078, 0x8198, 0x2009, 0x0015,
+ 0x6a6a, 0x6866, 0x007c, 0xa182, 0x0040, 0x0079, 0x819f, 0x81b2,
+ 0x81b4, 0x81c0, 0x81cc, 0x81b2, 0x81b2, 0x81b2, 0x81db, 0x81b2,
+ 0x81b2, 0x81b2, 0x81b2, 0x81b2, 0x81b2, 0x81b2, 0x81b2, 0x81b2,
+ 0x81b2, 0x81b2, 0x1078, 0x12d2, 0x6003, 0x0001, 0x6106, 0x1078,
+ 0x5399, 0x127e, 0x2091, 0x8000, 0x1078, 0x5888, 0x127f, 0x007c,
+ 0x6003, 0x0001, 0x6106, 0x1078, 0x5399, 0x127e, 0x2091, 0x8000,
+ 0x1078, 0x5888, 0x127f, 0x007c, 0x6003, 0x0003, 0x6106, 0x2c10,
+ 0x1078, 0x1b07, 0x127e, 0x2091, 0x8000, 0x1078, 0x5405, 0x1078,
+ 0x5948, 0x127f, 0x007c, 0xa016, 0x1078, 0x1594, 0x007c, 0x127e,
+ 0x2091, 0x8000, 0x037e, 0x0d7e, 0xa182, 0x0040, 0x1079, 0x81ec,
+ 0x0d7f, 0x037f, 0x127f, 0x007c, 0x81fc, 0x81fe, 0x8213, 0x8232,
+ 0x81fc, 0x81fc, 0x81fc, 0x824a, 0x81fc, 0x81fc, 0x81fc, 0x81fc,
+ 0x81fc, 0x81fc, 0x81fc, 0x81fc, 0x1078, 0x12d2, 0x6010, 0x2068,
+ 0x684c, 0xd0fc, 0x0040, 0x8228, 0xa09c, 0x0003, 0xa39e, 0x0003,
+ 0x0040, 0x8228, 0x6003, 0x0001, 0x6106, 0x1078, 0x5399, 0x1078,
+ 0x5888, 0x0078, 0x824d, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040,
+ 0x8228, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, 0x8228, 0x6003,
+ 0x0001, 0x6106, 0x1078, 0x5399, 0x1078, 0x5888, 0x0078, 0x824d,
+ 0x6013, 0x0000, 0x6017, 0x0000, 0x2019, 0x0004, 0x1078, 0x86aa,
+ 0x0078, 0x824d, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x8228,
+ 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, 0x8228, 0x6003, 0x0003,
+ 0x6106, 0x2c10, 0x1078, 0x1b07, 0x1078, 0x5405, 0x1078, 0x5948,
+ 0x0078, 0x824d, 0xa016, 0x1078, 0x1594, 0x007c, 0x1078, 0x578f,
+ 0x6110, 0x81ff, 0x0040, 0x825d, 0x0d7e, 0x2168, 0x037e, 0x2019,
+ 0x0029, 0x1078, 0x86aa, 0x037f, 0x0d7f, 0x1078, 0x79a8, 0x1078,
+ 0x5888, 0x007c, 0x1078, 0x5837, 0x6110, 0x81ff, 0x0040, 0x8271,
+ 0x0d7e, 0x2168, 0x037e, 0x2019, 0x0029, 0x1078, 0x86aa, 0x037f,
+ 0x0d7f, 0x1078, 0x79a8, 0x1078, 0x5948, 0x007c, 0xa182, 0x0085,
+ 0x0079, 0x827a, 0x8281, 0x8281, 0x8281, 0x8283, 0x8281, 0x8281,
+ 0x8281, 0x1078, 0x12d2, 0x027e, 0x0e7e, 0x1078, 0x8727, 0x0040,
+ 0x828d, 0x1078, 0x690e, 0x0078, 0x82a9, 0x2071, 0x8d80, 0x7224,
+ 0x6212, 0x7220, 0x1078, 0x8575, 0x0040, 0x829a, 0x6007, 0x0086,
+ 0x0078, 0x82a3, 0x6007, 0x0087, 0x7224, 0xa296, 0xffff, 0x00c0,
+ 0x82a3, 0x6007, 0x0086, 0x6003, 0x0001, 0x1078, 0x5399, 0x1078,
+ 0x5888, 0x0e7f, 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x82bd,
+ 0x6004, 0xa08a, 0x0085, 0x1048, 0x12d2, 0xa08a, 0x008c, 0x10c8,
+ 0x12d2, 0xa082, 0x0085, 0x0079, 0x82d4, 0xa186, 0x0027, 0x0040,
+ 0x82c9, 0xa186, 0x0014, 0x0040, 0x82c9, 0x1078, 0x6950, 0x0078,
+ 0x82d3, 0x2001, 0x0007, 0x1078, 0x3f2c, 0x1078, 0x578f, 0x1078,
+ 0x79a8, 0x1078, 0x5888, 0x007c, 0x82db, 0x82dd, 0x82dd, 0x82db,
+ 0x82db, 0x82db, 0x82db, 0x1078, 0x12d2, 0x1078, 0x578f, 0x1078,
+ 0x690e, 0x1078, 0x5888, 0x007c, 0xa182, 0x0085, 0x1048, 0x12d2,
+ 0xa182, 0x008c, 0x10c8, 0x12d2, 0xa182, 0x0085, 0x0079, 0x82f0,
+ 0x82f7, 0x82f7, 0x82f7, 0x82f9, 0x82f7, 0x82f7, 0x82f7, 0x1078,
+ 0x12d2, 0x007c, 0xa186, 0x0013, 0x0040, 0x830a, 0xa186, 0x0014,
+ 0x0040, 0x830a, 0xa186, 0x0027, 0x0040, 0x830a, 0x1078, 0x6950,
+ 0x0078, 0x8310, 0x1078, 0x578f, 0x1078, 0x79a8, 0x1078, 0x5888,
+ 0x007c, 0x037e, 0x2019, 0x000b, 0x1078, 0x831c, 0x601f, 0x0006,
+ 0x6003, 0x0007, 0x037f, 0x007c, 0x127e, 0x037e, 0x087e, 0x2091,
+ 0x8000, 0x2c40, 0x1078, 0x6614, 0x00c0, 0x834b, 0x1078, 0x66be,
+ 0x00c0, 0x834b, 0x6000, 0xa086, 0x0000, 0x0040, 0x834b, 0x601c,
+ 0xa086, 0x0007, 0x0040, 0x834b, 0x0d7e, 0x6000, 0xa086, 0x0004,
+ 0x00c0, 0x833e, 0x601f, 0x0007, 0x1078, 0x16af, 0x6010, 0x2068,
+ 0x1078, 0x77ed, 0x0040, 0x8346, 0x1078, 0x86aa, 0x0d7f, 0x6013,
0x0000, 0x601f, 0x0007, 0x087f, 0x037f, 0x127f, 0x007c, 0x0f7e,
- 0x0c7e, 0x037e, 0x157e, 0x2079, 0x7c80, 0x7838, 0xa08c, 0x00ff,
- 0x783c, 0x1078, 0x207f, 0x00c0, 0x734e, 0x017e, 0x0c7e, 0x1078,
- 0x384c, 0x00c0, 0x734e, 0x2011, 0x7c90, 0xac98, 0x000a, 0x20a9,
- 0x0004, 0x1078, 0x6280, 0x00c0, 0x734e, 0x017f, 0x027f, 0x027e,
- 0x017e, 0x2019, 0x0029, 0x1078, 0x5ba2, 0x1078, 0x4a7e, 0x1078,
- 0x49c1, 0x017f, 0x1078, 0x747b, 0x1078, 0x3a36, 0x017f, 0x1078,
- 0x3637, 0x6612, 0x6516, 0xa006, 0x0078, 0x7350, 0x0c7f, 0x017f,
- 0x157f, 0x037f, 0x0c7f, 0x0f7f, 0x007c, 0x0c7e, 0x0d7e, 0x017e,
- 0x2009, 0x771e, 0x2104, 0xa086, 0x0074, 0x00c0, 0x73ac, 0x2069,
- 0x7c8e, 0x690c, 0xa182, 0x0100, 0x0048, 0x739c, 0x6908, 0xa184,
- 0x8000, 0x0040, 0x73a8, 0xa184, 0x0800, 0x0040, 0x73a8, 0x6910,
- 0xa18a, 0x0001, 0x0048, 0x73a0, 0x6914, 0x2069, 0x7cae, 0x6904,
- 0x81ff, 0x00c0, 0x7394, 0x690c, 0xa182, 0x0100, 0x0048, 0x739c,
- 0x6908, 0x81ff, 0x00c0, 0x7398, 0x6910, 0xa18a, 0x0001, 0x0048,
- 0x73a0, 0x6918, 0xa18a, 0x0001, 0x0048, 0x73a8, 0x0078, 0x73b2,
- 0x6013, 0x0100, 0x0078, 0x73ae, 0x6013, 0x0300, 0x0078, 0x73ae,
- 0x6013, 0x0500, 0x0078, 0x73ae, 0x6013, 0x0700, 0x0078, 0x73ae,
- 0x6013, 0x0900, 0x0078, 0x73ae, 0x6013, 0x0b00, 0x0078, 0x73ae,
- 0x6013, 0x0f00, 0x0078, 0x73ae, 0x6013, 0x2d00, 0xa085, 0x0001,
- 0x0078, 0x73b3, 0xa006, 0x017f, 0x0d7f, 0x0c7f, 0x007c, 0x0c7e,
- 0x0d7e, 0x027e, 0x037e, 0x157e, 0x6218, 0x2268, 0x6b04, 0xa394,
- 0x00ff, 0xa286, 0x0006, 0x0040, 0x73db, 0xa286, 0x0004, 0x0040,
- 0x73db, 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, 0x0040, 0x73db,
- 0xa286, 0x0004, 0x0040, 0x73db, 0x0c7e, 0x2d60, 0x1078, 0x385e,
- 0x0c7f, 0x0078, 0x740e, 0x2011, 0x7c96, 0xad98, 0x000a, 0x20a9,
- 0x0004, 0x1078, 0x6280, 0x00c0, 0x740f, 0x2011, 0x7c9a, 0xad98,
- 0x0006, 0x20a9, 0x0004, 0x1078, 0x6280, 0x00c0, 0x740f, 0x047e,
- 0x017e, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0x7752,
- 0x210c, 0xd1a4, 0x0040, 0x7403, 0x2009, 0x0029, 0x1078, 0x7641,
- 0x6800, 0xc0e5, 0x6802, 0x2019, 0x0029, 0x1078, 0x4a7e, 0x1078,
- 0x49c1, 0x2c08, 0x1078, 0x747b, 0x017f, 0x047f, 0xa006, 0x157f,
- 0x037f, 0x027f, 0x0d7f, 0x0c7f, 0x007c, 0x0d7e, 0x2069, 0x7c8e,
- 0x6800, 0xa086, 0x0800, 0x0040, 0x7421, 0x6013, 0x0000, 0x0078,
- 0x7422, 0xa006, 0x0d7f, 0x007c, 0x0c7e, 0x0f7e, 0x017e, 0x027e,
- 0x037e, 0x157e, 0x2079, 0x7c8c, 0x7930, 0x7834, 0x1078, 0x207f,
- 0x00c0, 0x7448, 0x1078, 0x384c, 0x00c0, 0x7448, 0x2011, 0x7c90,
- 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x6280, 0x00c0, 0x7448,
- 0x2011, 0x7c94, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078, 0x6280,
- 0x157f, 0x037f, 0x027f, 0x017f, 0x0f7f, 0x0c7f, 0x007c, 0x0c7e,
- 0x007e, 0x017e, 0x027e, 0x037e, 0x157e, 0x2011, 0x7c83, 0x2204,
- 0x8211, 0x220c, 0x1078, 0x207f, 0x00c0, 0x7474, 0x1078, 0x384c,
- 0x00c0, 0x7474, 0x2011, 0x7c96, 0xac98, 0x000a, 0x20a9, 0x0004,
- 0x1078, 0x6280, 0x00c0, 0x7474, 0x2011, 0x7c9a, 0xac98, 0x0006,
- 0x20a9, 0x0004, 0x1078, 0x6280, 0x157f, 0x037f, 0x027f, 0x017f,
- 0x007f, 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x057e,
- 0x047e, 0x027e, 0x127e, 0x2091, 0x8000, 0x2029, 0x793f, 0x252c,
- 0x2021, 0x7945, 0x2424, 0x2061, 0x7e00, 0x2071, 0x7700, 0x7644,
- 0x7060, 0x8001, 0xa602, 0x00c8, 0x74e0, 0x2100, 0xac06, 0x0040,
- 0x74d6, 0x1078, 0x7659, 0x0040, 0x74d6, 0x671c, 0xa786, 0x0001,
- 0x0040, 0x74f5, 0xa786, 0x0007, 0x0040, 0x74d6, 0x2500, 0xac06,
- 0x0040, 0x74d6, 0x2400, 0xac06, 0x0040, 0x74d6, 0x1078, 0x766d,
- 0x00c0, 0x74d6, 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x74bc,
- 0x017e, 0x1078, 0x166e, 0x017f, 0x6010, 0x2068, 0x1078, 0x6a58,
- 0x0040, 0x74d3, 0xa786, 0x0003, 0x00c0, 0x74e9, 0x6837, 0x0103,
- 0x6b4a, 0x6847, 0x0000, 0x017e, 0x1078, 0x6c54, 0x1078, 0x3b92,
- 0x017f, 0x1078, 0x6ba9, 0x0d7f, 0x1078, 0x6bb6, 0xace0, 0x0008,
- 0x2001, 0x7715, 0x2004, 0xac02, 0x00c8, 0x74e0, 0x0078, 0x748d,
- 0x127f, 0x027f, 0x047f, 0x057f, 0x067f, 0x077f, 0x0c7f, 0x0e7f,
- 0x007c, 0xa786, 0x0006, 0x00c0, 0x74c6, 0xa386, 0x0005, 0x0040,
- 0x74d6, 0x1078, 0x75fd, 0x0078, 0x74d3, 0x1078, 0x766d, 0x00c0,
- 0x74d6, 0xa180, 0x0001, 0x2004, 0xa086, 0x0018, 0x00c0, 0x74d6,
- 0x6000, 0xa086, 0x0002, 0x00c0, 0x74d6, 0x1078, 0x6bcf, 0x0040,
- 0x7511, 0x1078, 0x6be3, 0x00c0, 0x74d6, 0x1078, 0x5f6d, 0x0078,
- 0x7513, 0x1078, 0x22d7, 0x1078, 0x6bb6, 0x0078, 0x74d6, 0x0c7e,
- 0x0e7e, 0x017e, 0x2c08, 0x2170, 0x1078, 0x7614, 0x017f, 0x0040,
- 0x7526, 0x601c, 0xa084, 0x000f, 0x1079, 0x7529, 0x0e7f, 0x0c7f,
- 0x007c, 0x7531, 0x7531, 0x7531, 0x7531, 0x7531, 0x7531, 0x7533,
- 0x7531, 0xa006, 0x007c, 0x047e, 0x017e, 0x7018, 0xa080, 0x0028,
- 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, 0x2009, 0x0020, 0x1078,
- 0x7641, 0x017f, 0x047f, 0x037e, 0x2019, 0x0002, 0x1078, 0x72e6,
- 0x037f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0001, 0x1078, 0x37e0,
- 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019, 0x7705,
- 0x2011, 0x7c96, 0x1078, 0x6280, 0x037f, 0x027f, 0x017f, 0x157f,
- 0xa005, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x027e,
- 0x127e, 0x2091, 0x8000, 0x2061, 0x7e00, 0x2079, 0x0001, 0x8fff,
- 0x0040, 0x75bd, 0x2071, 0x7700, 0x7644, 0x7060, 0x8001, 0xa602,
- 0x00c8, 0x75bd, 0x88ff, 0x0040, 0x7583, 0x2800, 0xac06, 0x00c0,
- 0x75b3, 0x2079, 0x0000, 0x1078, 0x7659, 0x0040, 0x75b3, 0x2400,
- 0xac06, 0x0040, 0x75b3, 0x671c, 0xa786, 0x0006, 0x00c0, 0x75b3,
- 0xa786, 0x0007, 0x0040, 0x75b3, 0x88ff, 0x00c0, 0x759b, 0x6018,
- 0xa206, 0x00c0, 0x75b3, 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0,
- 0x75a3, 0x1078, 0x166e, 0x6010, 0x2068, 0x1078, 0x6a58, 0x0040,
- 0x75ad, 0x047e, 0x1078, 0x75fd, 0x047f, 0x0d7f, 0x1078, 0x6bb6,
- 0x88ff, 0x00c0, 0x75c6, 0xace0, 0x0008, 0x2001, 0x7715, 0x2004,
- 0xac02, 0x00c8, 0x75bd, 0x0078, 0x756f, 0xa006, 0x127f, 0x027f,
- 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5, 0x0001,
- 0x0078, 0x75be, 0x087e, 0x2041, 0x0000, 0x2c20, 0x2019, 0x0002,
- 0x6218, 0x1078, 0x5a2d, 0x1078, 0x5ace, 0x1078, 0x7562, 0x087f,
- 0x007c, 0x027e, 0x047e, 0x087e, 0x0c7e, 0x157e, 0x2c20, 0x20a9,
- 0x007f, 0x2009, 0x0000, 0x017e, 0x037e, 0x1078, 0x384c, 0x00c0,
- 0x75f2, 0x2c10, 0x2041, 0x0000, 0x1078, 0x5a2d, 0x1078, 0x5ace,
- 0x1078, 0x7562, 0x037f, 0x017f, 0x8108, 0x00f0, 0x75e3, 0x157f,
- 0x0c7f, 0x087f, 0x047f, 0x027f, 0x007c, 0x017e, 0x0f7e, 0x8dff,
- 0x0040, 0x7611, 0x6800, 0xa07d, 0x0040, 0x760e, 0x6803, 0x0000,
- 0x6b52, 0x1078, 0x3b92, 0x2f68, 0x0078, 0x7602, 0x6b52, 0x1078,
- 0x3b92, 0x0f7f, 0x017f, 0x007c, 0x0e7e, 0x047e, 0x037e, 0x2061,
- 0x7e00, 0x2071, 0x7700, 0x7444, 0x7060, 0x8001, 0xa402, 0x00c8,
- 0x763c, 0x2100, 0xac06, 0x0040, 0x762e, 0x6000, 0xa086, 0x0000,
- 0x0040, 0x762e, 0x6008, 0xa206, 0x0040, 0x7638, 0xace0, 0x0008,
- 0x2001, 0x7715, 0x2004, 0xac02, 0x00c8, 0x763c, 0x0078, 0x7619,
- 0xa085, 0x0001, 0x0078, 0x763d, 0xa006, 0x037f, 0x047f, 0x0e7f,
- 0x007c, 0x0d7e, 0x007e, 0x1078, 0x1327, 0x007f, 0x1040, 0x12cd,
- 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x685b, 0x0000,
- 0x685e, 0x6956, 0x6c46, 0x684f, 0x0000, 0x1078, 0x3b92, 0x0d7f,
- 0x007c, 0x6700, 0xa786, 0x0000, 0x0040, 0x766c, 0xa786, 0x0001,
- 0x0040, 0x766c, 0xa786, 0x000a, 0x0040, 0x766c, 0xa786, 0x0009,
- 0x0040, 0x766c, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x6018, 0x2070,
- 0x70a0, 0xa206, 0x0e7f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091,
- 0x8000, 0x2071, 0x7740, 0xd5a4, 0x0040, 0x7681, 0x7034, 0x8000,
- 0x7036, 0xd5b4, 0x0040, 0x7687, 0x7030, 0x8000, 0x7032, 0xd5ac,
- 0x0040, 0x768e, 0x2071, 0x774a, 0x1078, 0x76bd, 0x0e7f, 0x007f,
+ 0x0c7e, 0x037e, 0x157e, 0x2079, 0x8d80, 0x7938, 0x783c, 0x1078,
+ 0x2245, 0x00c0, 0x839d, 0x017e, 0x0c7e, 0x1078, 0x3f8e, 0x00c0,
+ 0x839d, 0x2011, 0x8d90, 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078,
+ 0x6f0c, 0x00c0, 0x839d, 0x017f, 0x027f, 0x027e, 0x017e, 0x2019,
+ 0x0029, 0x1078, 0x6799, 0x1078, 0x54f0, 0x087e, 0x2041, 0x0000,
+ 0x1078, 0x5419, 0x087f, 0x017f, 0x087e, 0x2041, 0x0000, 0x1078,
+ 0x84d2, 0x087f, 0x1078, 0x418b, 0x027e, 0x6204, 0xa294, 0xff00,
+ 0x8217, 0xa286, 0x0006, 0x0040, 0x8391, 0xa286, 0x0004, 0x00c0,
+ 0x8394, 0x62a0, 0x1078, 0x2566, 0x027f, 0x017f, 0x1078, 0x3d31,
+ 0x6612, 0x6516, 0xa006, 0x0078, 0x839f, 0x0c7f, 0x017f, 0x157f,
+ 0x037f, 0x0c7f, 0x0f7f, 0x007c, 0x0c7e, 0x0d7e, 0x017e, 0x2009,
+ 0x881f, 0x2104, 0xa086, 0x0074, 0x00c0, 0x83fb, 0x2069, 0x8d8e,
+ 0x690c, 0xa182, 0x0100, 0x0048, 0x83eb, 0x6908, 0xa184, 0x8000,
+ 0x0040, 0x83f7, 0xa184, 0x0800, 0x0040, 0x83f7, 0x6910, 0xa18a,
+ 0x0001, 0x0048, 0x83ef, 0x6914, 0x2069, 0x8dae, 0x6904, 0x81ff,
+ 0x00c0, 0x83e3, 0x690c, 0xa182, 0x0100, 0x0048, 0x83eb, 0x6908,
+ 0x81ff, 0x00c0, 0x83e7, 0x6910, 0xa18a, 0x0001, 0x0048, 0x83ef,
+ 0x6918, 0xa18a, 0x0001, 0x0048, 0x83f7, 0x0078, 0x8401, 0x6013,
+ 0x0100, 0x0078, 0x83fd, 0x6013, 0x0300, 0x0078, 0x83fd, 0x6013,
+ 0x0500, 0x0078, 0x83fd, 0x6013, 0x0700, 0x0078, 0x83fd, 0x6013,
+ 0x0900, 0x0078, 0x83fd, 0x6013, 0x0b00, 0x0078, 0x83fd, 0x6013,
+ 0x0f00, 0x0078, 0x83fd, 0x6013, 0x2d00, 0xa085, 0x0001, 0x0078,
+ 0x8402, 0xa006, 0x017f, 0x0d7f, 0x0c7f, 0x007c, 0x0c7e, 0x0d7e,
+ 0x027e, 0x037e, 0x157e, 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff,
+ 0xa286, 0x0006, 0x0040, 0x842a, 0xa286, 0x0004, 0x0040, 0x842a,
+ 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, 0x0040, 0x842a, 0xa286,
+ 0x0004, 0x0040, 0x842a, 0x0c7e, 0x2d60, 0x1078, 0x3fa0, 0x0c7f,
+ 0x0078, 0x8465, 0x2011, 0x8d96, 0xad98, 0x000a, 0x20a9, 0x0004,
+ 0x1078, 0x6f0c, 0x00c0, 0x8466, 0x2011, 0x8d9a, 0xad98, 0x0006,
+ 0x20a9, 0x0004, 0x1078, 0x6f0c, 0x00c0, 0x8466, 0x047e, 0x017e,
+ 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0x8852, 0x210c,
+ 0xd1a4, 0x0040, 0x8452, 0x2009, 0x0029, 0x1078, 0x86f5, 0x6800,
+ 0xc0e5, 0x6802, 0x2019, 0x0029, 0x1078, 0x54f0, 0x087e, 0x2041,
+ 0x0000, 0x1078, 0x5419, 0x2c08, 0x1078, 0x84d2, 0x087f, 0x2001,
+ 0x0007, 0x1078, 0x3f2c, 0x017f, 0x047f, 0xa006, 0x157f, 0x037f,
+ 0x027f, 0x0d7f, 0x0c7f, 0x007c, 0x0d7e, 0x2069, 0x8d8e, 0x6800,
+ 0xa086, 0x0800, 0x0040, 0x8478, 0x6013, 0x0000, 0x0078, 0x8479,
+ 0xa006, 0x0d7f, 0x007c, 0x0c7e, 0x0f7e, 0x017e, 0x027e, 0x037e,
+ 0x157e, 0x2079, 0x8d8c, 0x7930, 0x7834, 0x1078, 0x2245, 0x00c0,
+ 0x849f, 0x1078, 0x3f8e, 0x00c0, 0x849f, 0x2011, 0x8d90, 0xac98,
+ 0x000a, 0x20a9, 0x0004, 0x1078, 0x6f0c, 0x00c0, 0x849f, 0x2011,
+ 0x8d94, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078, 0x6f0c, 0x157f,
+ 0x037f, 0x027f, 0x017f, 0x0f7f, 0x0c7f, 0x007c, 0x0c7e, 0x007e,
+ 0x017e, 0x027e, 0x037e, 0x157e, 0x2011, 0x8d83, 0x2204, 0x8211,
+ 0x220c, 0x1078, 0x2245, 0x00c0, 0x84cb, 0x1078, 0x3f8e, 0x00c0,
+ 0x84cb, 0x2011, 0x8d96, 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078,
+ 0x6f0c, 0x00c0, 0x84cb, 0x2011, 0x8d9a, 0xac98, 0x0006, 0x20a9,
+ 0x0004, 0x1078, 0x6f0c, 0x157f, 0x037f, 0x027f, 0x017f, 0x007f,
+ 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x057e, 0x047e,
+ 0x027e, 0x127e, 0x2091, 0x8000, 0x2029, 0x8aab, 0x252c, 0x2021,
+ 0x8ab1, 0x2424, 0x2061, 0x8f00, 0x2071, 0x8800, 0x7644, 0x7060,
+ 0x8001, 0xa602, 0x00c8, 0x853e, 0x2100, 0xac06, 0x0040, 0x8534,
+ 0x1078, 0x870c, 0x0040, 0x8534, 0x671c, 0xa786, 0x0001, 0x0040,
+ 0x8553, 0xa786, 0x0007, 0x0040, 0x8534, 0x2500, 0xac06, 0x0040,
+ 0x8534, 0x2400, 0xac06, 0x0040, 0x8534, 0x1078, 0x8720, 0x00c0,
+ 0x8534, 0x88ff, 0x0040, 0x8510, 0x6020, 0xa906, 0x00c0, 0x8534,
+ 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x851a, 0x017e, 0x1078,
+ 0x16af, 0x017f, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, 0x8531,
+ 0xa786, 0x0003, 0x00c0, 0x8547, 0x6837, 0x0103, 0x6b4a, 0x6847,
+ 0x0000, 0x017e, 0x1078, 0x7a46, 0x1078, 0x4376, 0x017f, 0x1078,
+ 0x799b, 0x0d7f, 0x1078, 0x79a8, 0xace0, 0x000c, 0x2001, 0x8815,
+ 0x2004, 0xac02, 0x00c8, 0x853e, 0x0078, 0x84e4, 0x127f, 0x027f,
+ 0x047f, 0x057f, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x007c, 0xa786,
+ 0x0006, 0x00c0, 0x8524, 0xa386, 0x0005, 0x0040, 0x8534, 0x1078,
+ 0x86aa, 0x0078, 0x8531, 0x1078, 0x8720, 0x00c0, 0x8534, 0xa180,
+ 0x0001, 0x2004, 0xa086, 0x0018, 0x00c0, 0x8534, 0x6000, 0xa086,
+ 0x0002, 0x00c0, 0x8534, 0x1078, 0x79c1, 0x0040, 0x856f, 0x1078,
+ 0x79d5, 0x00c0, 0x8534, 0x1078, 0x6bc7, 0x0078, 0x8571, 0x1078,
+ 0x24e5, 0x1078, 0x79a8, 0x0078, 0x8534, 0x0c7e, 0x0e7e, 0x017e,
+ 0x2c08, 0x2170, 0x1078, 0x86c1, 0x017f, 0x0040, 0x8584, 0x601c,
+ 0xa084, 0x000f, 0x1079, 0x8587, 0x0e7f, 0x0c7f, 0x007c, 0x858f,
+ 0x858f, 0x858f, 0x858f, 0x858f, 0x858f, 0x8591, 0x858f, 0xa006,
+ 0x007c, 0x047e, 0x017e, 0x7018, 0xa080, 0x0028, 0x2024, 0xa4a4,
+ 0x00ff, 0x8427, 0x2c00, 0x2009, 0x0020, 0x1078, 0x86f5, 0x017f,
+ 0x047f, 0x037e, 0x2019, 0x0002, 0x1078, 0x831c, 0x037f, 0xa085,
+ 0x0001, 0x007c, 0x2001, 0x0001, 0x1078, 0x3ef1, 0x157e, 0x017e,
+ 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019, 0x8805, 0x2011, 0x8d96,
+ 0x1078, 0x6f0c, 0x037f, 0x027f, 0x017f, 0x157f, 0xa005, 0x007c,
+ 0x0f7e, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x027e, 0x127e, 0x2091,
+ 0x8000, 0x2061, 0x8f00, 0x2079, 0x0001, 0x8fff, 0x0040, 0x8624,
+ 0x2071, 0x8800, 0x7644, 0x7060, 0x8001, 0xa602, 0x00c8, 0x8624,
+ 0x88ff, 0x0040, 0x85e1, 0x2800, 0xac06, 0x00c0, 0x861a, 0x2079,
+ 0x0000, 0x1078, 0x870c, 0x0040, 0x861a, 0x2400, 0xac06, 0x0040,
+ 0x861a, 0x671c, 0xa786, 0x0006, 0x00c0, 0x861a, 0xa786, 0x0007,
+ 0x0040, 0x861a, 0x88ff, 0x00c0, 0x8600, 0x6018, 0xa206, 0x00c0,
+ 0x861a, 0x85ff, 0x0040, 0x8600, 0x6020, 0xa106, 0x00c0, 0x861a,
+ 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x860a, 0x601f, 0x0007,
+ 0x1078, 0x16af, 0x6010, 0x2068, 0x1078, 0x77ed, 0x0040, 0x8614,
+ 0x047e, 0x1078, 0x86aa, 0x047f, 0x0d7f, 0x1078, 0x79a8, 0x88ff,
+ 0x00c0, 0x862d, 0xace0, 0x000c, 0x2001, 0x8815, 0x2004, 0xac02,
+ 0x00c8, 0x8624, 0x0078, 0x85cd, 0xa006, 0x127f, 0x027f, 0x067f,
+ 0x077f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5, 0x0001, 0x0078,
+ 0x8625, 0x087e, 0x057e, 0x2041, 0x0000, 0x2029, 0x0001, 0x2c20,
+ 0x2019, 0x0002, 0x6218, 0x1078, 0x6614, 0x1078, 0x66be, 0x1078,
+ 0x85c0, 0x057f, 0x087f, 0x007c, 0x027e, 0x047e, 0x057e, 0x087e,
+ 0x0c7e, 0x157e, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009, 0x0000,
+ 0x017e, 0x037e, 0x1078, 0x3f8e, 0x00c0, 0x8664, 0x2c10, 0x2041,
+ 0x0000, 0x2508, 0x057e, 0x2029, 0x0001, 0x1078, 0x6614, 0x1078,
+ 0x66be, 0x1078, 0x85c0, 0x057f, 0x037f, 0x017f, 0x8108, 0x00f0,
+ 0x8650, 0x157f, 0x0c7f, 0x087f, 0x057f, 0x047f, 0x027f, 0x007c,
+ 0x087e, 0x057e, 0x6218, 0x2041, 0x0000, 0x2029, 0x0001, 0x2019,
+ 0x0048, 0x1078, 0x6614, 0x1078, 0x66be, 0x2c20, 0x1078, 0x85c0,
+ 0x057f, 0x087f, 0x007c, 0x027e, 0x047e, 0x057e, 0x087e, 0x0c7e,
+ 0x157e, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x037e,
+ 0x1078, 0x3f8e, 0x00c0, 0x869e, 0x2c10, 0x2041, 0x0000, 0x2828,
+ 0x1078, 0x6614, 0x1078, 0x66be, 0x1078, 0x85c0, 0x037f, 0x017f,
+ 0x8108, 0x00f0, 0x868e, 0x157f, 0x0c7f, 0x087f, 0x057f, 0x047f,
+ 0x027f, 0x007c, 0x017e, 0x0f7e, 0x8dff, 0x0040, 0x86be, 0x6800,
+ 0xa07d, 0x0040, 0x86bb, 0x6803, 0x0000, 0x6b52, 0x1078, 0x4376,
+ 0x2f68, 0x0078, 0x86af, 0x6b52, 0x1078, 0x4376, 0x0f7f, 0x017f,
+ 0x007c, 0x0e7e, 0x047e, 0x037e, 0x2061, 0x8f00, 0x2071, 0x8800,
+ 0x7444, 0x7060, 0x8001, 0xa402, 0x00c8, 0x86f0, 0x2100, 0xac06,
+ 0x0040, 0x86e2, 0x6000, 0xa086, 0x0000, 0x0040, 0x86e2, 0x6008,
+ 0xa206, 0x00c0, 0x86e2, 0x6018, 0xa1a0, 0x0006, 0x2424, 0xa406,
+ 0x0040, 0x86ec, 0xace0, 0x000c, 0x2001, 0x8815, 0x2004, 0xac02,
+ 0x00c8, 0x86f0, 0x0078, 0x86c6, 0xa085, 0x0001, 0x0078, 0x86f1,
+ 0xa006, 0x037f, 0x047f, 0x0e7f, 0x007c, 0x0d7e, 0x007e, 0x1078,
+ 0x132b, 0x007f, 0x1040, 0x12d2, 0x6837, 0x010d, 0x685e, 0x6956,
+ 0x6c46, 0x684f, 0x0000, 0xa006, 0x68b2, 0x6802, 0x683a, 0x685a,
+ 0x1078, 0x4376, 0x0d7f, 0x007c, 0x6700, 0xa786, 0x0000, 0x0040,
+ 0x871f, 0xa786, 0x0001, 0x0040, 0x871f, 0xa786, 0x000a, 0x0040,
+ 0x871f, 0xa786, 0x0009, 0x0040, 0x871f, 0xa085, 0x0001, 0x007c,
+ 0x0e7e, 0x6018, 0x2070, 0x70a0, 0xa206, 0x0e7f, 0x007c, 0x0e7e,
+ 0x6018, 0x2070, 0x7000, 0xd0ec, 0x0e7f, 0x007c, 0x127e, 0x007e,
+ 0x0e7e, 0x2091, 0x8000, 0x2071, 0x8840, 0xd5a4, 0x0040, 0x873b,
+ 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0x8741, 0x7030, 0x8000,
+ 0x7032, 0xd5ac, 0x0040, 0x8748, 0x2071, 0x884a, 0x1078, 0x8777,
+ 0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091,
+ 0x8000, 0x2071, 0x8840, 0xd5a4, 0x0040, 0x8759, 0x7034, 0x8000,
+ 0x7036, 0xd5b4, 0x0040, 0x875f, 0x7030, 0x8000, 0x7032, 0xd5ac,
+ 0x0040, 0x8766, 0x2071, 0x884a, 0x1078, 0x8777, 0x0e7f, 0x007f,
0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071,
- 0x7740, 0xd5a4, 0x0040, 0x769f, 0x7034, 0x8000, 0x7036, 0xd5b4,
- 0x0040, 0x76a5, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0040, 0x76ac,
- 0x2071, 0x774a, 0x1078, 0x76bd, 0x0e7f, 0x007f, 0x127f, 0x007c,
- 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x7742, 0x1078,
- 0x76bd, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x2e04, 0x8000, 0x2072,
- 0x00c8, 0x76c6, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x007c, 0x0e7e,
- 0x2071, 0x7740, 0x1078, 0x76bd, 0x0e7f, 0x007c, 0x0e7e, 0x2071,
- 0x7744, 0x1078, 0x76bd, 0x0e7f, 0x007c, 0x0001, 0x0002, 0x0004,
- 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400,
- 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x687d
+ 0x8842, 0x1078, 0x8777, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x2e04,
+ 0x8000, 0x2072, 0x00c8, 0x8780, 0x8e70, 0x2e04, 0x8000, 0x2072,
+ 0x007c, 0x0e7e, 0x2071, 0x8840, 0x1078, 0x8777, 0x0e7f, 0x007c,
+ 0x0e7e, 0x2071, 0x8844, 0x1078, 0x8777, 0x0e7f, 0x007c, 0x0001,
+ 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
+ 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x6f37
};
-/*
- * Firmware Version 2.00.16 (09:36 Jun 29, 1999)
- */
unsigned short risc_code2200[] = {
- 0x0470, 0x0000, 0x0000, 0x81bd, 0x0000, 0x0002, 0x0000, 0x0010,
- 0x0027, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939,
+ 0x0470, 0x0000, 0x0000, 0x7a68, 0x0000, 0x0002, 0x0000, 0x0028,
+ 0x0007, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939,
0x3920, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
0x5449, 0x4f4e, 0x2049, 0x5350, 0x3232, 0x3030, 0x2046, 0x6972,
0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
- 0x322e, 0x3030, 0x2e31, 0x3620, 0x2020, 0x2020, 0x2400, 0x20c1,
- 0x0005, 0x2001, 0x017f, 0x2003, 0x0000, 0x20c9, 0x96ff, 0x2091,
- 0x2000, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x2490,
- 0x2051, 0x9200, 0x2a70, 0x2029, 0xb100, 0x2031, 0xffff, 0x2039,
- 0xb0f5, 0x2021, 0x0200, 0x0804, 0x136b, 0x20a1, 0x91bd, 0xa00e,
- 0x20a9, 0x0743, 0x41a4, 0x3400, 0x755e, 0x7662, 0x775a, 0x7466,
- 0x746a, 0x20a1, 0x9900, 0x7160, 0x810d, 0x810d, 0x810d, 0x810d,
+ 0x322e, 0x3030, 0x2e34, 0x3020, 0x2020, 0x2020, 0x2400, 0x20c1,
+ 0x0005, 0x2001, 0x017f, 0x2003, 0x0000, 0x20c9, 0x8fff, 0x2091,
+ 0x2000, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x236e,
+ 0x2051, 0x8b00, 0x2a70, 0x2029, 0xaa00, 0x2031, 0xffff, 0x2039,
+ 0xa9f5, 0x2021, 0x0200, 0x0804, 0x137d, 0x20a1, 0x8a68, 0xa00e,
+ 0x20a9, 0x0798, 0x41a4, 0x3400, 0x755e, 0x7662, 0x775a, 0x7466,
+ 0x746a, 0x20a1, 0x9200, 0x7160, 0x810d, 0x810d, 0x810d, 0x810d,
0xa18c, 0x000f, 0x2001, 0x0009, 0xa112, 0xa00e, 0x21a8, 0x41a4,
0x3400, 0x8211, 0x1dd8, 0x7160, 0x3400, 0xa102, 0x0120, 0x0218,
- 0x20a8, 0xa00e, 0x41a4, 0x3800, 0xd08c, 0x01d8, 0x2009, 0x9200,
+ 0x20a8, 0xa00e, 0x41a4, 0x3800, 0xd08c, 0x01d8, 0x2009, 0x8b00,
0x810d, 0x810d, 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0001,
0xa112, 0x20a1, 0x1000, 0xa00e, 0x21a8, 0x41a4, 0x8211, 0x1de0,
- 0x2009, 0x9200, 0x3400, 0xa102, 0x0120, 0x0218, 0x20a8, 0xa00e,
- 0x41a4, 0x080c, 0x1322, 0x080c, 0x14b6, 0x080c, 0x1649, 0x080c,
- 0x1c81, 0x080c, 0x41d4, 0x080c, 0x7494, 0x080c, 0x1439, 0x080c,
- 0x2819, 0x080c, 0x4e42, 0x080c, 0x4757, 0x080c, 0x5874, 0x080c,
- 0x56c0, 0x080c, 0x2138, 0x080c, 0x5ed0, 0x080c, 0x532f, 0x080c,
- 0x206a, 0x080c, 0x210e, 0x2091, 0x3009, 0x7823, 0x0000, 0x1004,
- 0x10c7, 0x7820, 0xa086, 0x0002, 0x1150, 0x7823, 0x4000, 0x0e04,
- 0x10bf, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70,
- 0x7003, 0x0000, 0x2a70, 0x7000, 0xa08e, 0x0003, 0x1168, 0x080c,
- 0x36d4, 0x080c, 0x2840, 0x080c, 0x4e90, 0x080c, 0x493b, 0x080c,
- 0x58b1, 0x080c, 0x56d8, 0x0c70, 0x000b, 0x0c88, 0x10e8, 0x10e9,
- 0x11b8, 0x10e6, 0x123f, 0x131f, 0x1320, 0x1321, 0x080c, 0x13fe,
- 0x0005, 0x0126, 0x00f6, 0x2091, 0x8000, 0x080c, 0x4dc5, 0x0150,
- 0x080c, 0x4deb, 0x11f8, 0x2079, 0x0100, 0x7828, 0xa085, 0x1800,
- 0x782a, 0x00c0, 0x080c, 0x4d10, 0x7088, 0xa086, 0x0026, 0x1904,
- 0x119d, 0x2079, 0x0100, 0x7827, 0xffff, 0x782b, 0x1c2b, 0x2011,
- 0x4ce2, 0x080c, 0x5731, 0x2011, 0x8030, 0x2019, 0x0000, 0x7087,
- 0x0000, 0x00a8, 0x080c, 0x3a6a, 0x2079, 0x0100, 0x7844, 0xa005,
- 0x1904, 0x119d, 0x2011, 0x40af, 0x080c, 0x5731, 0x780f, 0x03ff,
+ 0x2009, 0x8b00, 0x3400, 0xa102, 0x0120, 0x0218, 0x20a8, 0xa00e,
+ 0x41a4, 0x080c, 0x1334, 0x080c, 0x14c2, 0x080c, 0x165b, 0x080c,
+ 0x1bc1, 0x080c, 0x410c, 0x080c, 0x6cba, 0x080c, 0x144b, 0x080c,
+ 0x273d, 0x080c, 0x4d5e, 0x080c, 0x45ef, 0x080c, 0x559c, 0x080c,
+ 0x2029, 0x080c, 0x577b, 0x080c, 0x5212, 0x080c, 0x1f59, 0x080c,
+ 0x1ffd, 0x2091, 0x3009, 0x7823, 0x0000, 0x1004, 0x10c5, 0x7820,
+ 0xa086, 0x0002, 0x1150, 0x7823, 0x4000, 0x0e04, 0x10bd, 0x781b,
+ 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000,
+ 0x2a70, 0x7000, 0xa08e, 0x0003, 0x1158, 0x080c, 0x3653, 0x080c,
+ 0x2764, 0x080c, 0x4dac, 0x080c, 0x4788, 0x080c, 0x55b4, 0x0c80,
+ 0x000b, 0x0c98, 0x10e4, 0x10e5, 0x11c0, 0x10e2, 0x1251, 0x1331,
+ 0x1332, 0x1333, 0x080c, 0x1410, 0x0005, 0x0126, 0x00f6, 0x2091,
+ 0x8000, 0x080c, 0x4c42, 0x0150, 0x080c, 0x4c68, 0x1518, 0x2079,
+ 0x0100, 0x7828, 0xa085, 0x1800, 0x782a, 0x00e0, 0x080c, 0x4b8b,
+ 0x7088, 0xa086, 0x0027, 0x1904, 0x11a5, 0x2079, 0x0100, 0x7827,
+ 0xffff, 0x782b, 0x1e2b, 0x2011, 0x4b5d, 0x080c, 0x560d, 0x2011,
+ 0x3fe7, 0x080c, 0x560d, 0x2011, 0x8030, 0x2019, 0x0000, 0x7087,
+ 0x0000, 0x00a8, 0x080c, 0x399f, 0x2079, 0x0100, 0x7844, 0xa005,
+ 0x1904, 0x11a5, 0x2011, 0x3fe7, 0x080c, 0x560d, 0x780f, 0x00ff,
0x7840, 0xa084, 0xfffb, 0x7842, 0x2011, 0x8010, 0x73c4, 0x080c,
- 0x3698, 0x080c, 0x706b, 0x2011, 0x0004, 0x080c, 0x82f3, 0x080c,
- 0x46a8, 0x080c, 0x4dc5, 0x0158, 0x080c, 0x41bd, 0x0140, 0x7087,
- 0x0001, 0x70bf, 0x0000, 0x080c, 0x3bfd, 0x0804, 0x119d, 0x70d3,
- 0x0000, 0x70cf, 0x0000, 0x706f, 0x0000, 0x7073, 0x0000, 0x080c,
- 0x11a0, 0x72c8, 0x080c, 0x4dc5, 0x1160, 0x2011, 0x0000, 0x2001,
- 0x0204, 0x2004, 0x2019, 0x94c8, 0x201a, 0x704f, 0xffff, 0x7053,
- 0x00ef, 0x2079, 0x9251, 0x7804, 0xd0ac, 0x0108, 0xc295, 0x72ca,
- 0x080c, 0x4dc5, 0x0118, 0xa296, 0x0004, 0x0500, 0x2011, 0x0001,
- 0x080c, 0x82f3, 0x080c, 0x854a, 0x7097, 0x0000, 0x709b, 0xffff,
- 0x7003, 0x0002, 0x00fe, 0x080c, 0x251c, 0x2011, 0x0005, 0x080c,
- 0x718f, 0x080c, 0x6462, 0x080c, 0x4dc5, 0x0130, 0x00c6, 0x2061,
- 0x0100, 0x60e3, 0x0008, 0x00ce, 0x012e, 0x00c8, 0x080c, 0x854a,
+ 0x3617, 0x7238, 0xc284, 0x723a, 0x2001, 0x8b0c, 0x200c, 0xc1ac,
+ 0x2102, 0x080c, 0x683e, 0x2011, 0x0004, 0x080c, 0x7b94, 0x080c,
+ 0x4581, 0x080c, 0x4c42, 0x0158, 0x080c, 0x40f5, 0x0140, 0x7087,
+ 0x0001, 0x70bf, 0x0000, 0x080c, 0x3b32, 0x0804, 0x11a5, 0x70d3,
+ 0x0000, 0x70cf, 0x0000, 0x706f, 0x0000, 0x080c, 0x11a8, 0x72c8,
+ 0x080c, 0x4c42, 0x1170, 0x2011, 0x0000, 0x2001, 0x0204, 0x2004,
+ 0x2019, 0x8d8d, 0x201a, 0x704f, 0xffff, 0x7053, 0x00ef, 0x7073,
+ 0x0000, 0x2079, 0x8b51, 0x7804, 0xd0ac, 0x0108, 0xc295, 0x72ca,
+ 0x080c, 0x4c42, 0x0118, 0xa296, 0x0004, 0x0500, 0x2011, 0x0001,
+ 0x080c, 0x7b94, 0x080c, 0x7deb, 0x7097, 0x0000, 0x709b, 0xffff,
+ 0x7003, 0x0002, 0x00fe, 0x080c, 0x23fa, 0x2011, 0x0005, 0x080c,
+ 0x695c, 0x080c, 0x5d10, 0x080c, 0x4c42, 0x0130, 0x00c6, 0x2061,
+ 0x0100, 0x60e3, 0x0008, 0x00ce, 0x012e, 0x00c8, 0x080c, 0x7deb,
0x7097, 0x0000, 0x709b, 0xffff, 0x7003, 0x0002, 0x2011, 0x0005,
- 0x080c, 0x718f, 0x080c, 0x6462, 0x080c, 0x4dc5, 0x0130, 0x00c6,
+ 0x080c, 0x695c, 0x080c, 0x5d10, 0x080c, 0x4c42, 0x0130, 0x00c6,
0x2061, 0x0100, 0x60e3, 0x0008, 0x00ce, 0x00fe, 0x012e, 0x0005,
- 0x00c6, 0x080c, 0x4dc5, 0x1118, 0x20a9, 0x0100, 0x0010, 0x20a9,
- 0x0082, 0x080c, 0x4dc5, 0x1118, 0x2009, 0x0000, 0x0010, 0x2009,
- 0x007e, 0x080c, 0x441f, 0x8108, 0x1f04, 0x11b1, 0x00ce, 0x0005,
+ 0x00c6, 0x080c, 0x4c42, 0x1118, 0x20a9, 0x0100, 0x0010, 0x20a9,
+ 0x0082, 0x080c, 0x4c42, 0x1118, 0x2009, 0x0000, 0x0010, 0x2009,
+ 0x007e, 0x080c, 0x42f5, 0x8108, 0x1f04, 0x11b9, 0x00ce, 0x0005,
0x0126, 0x2091, 0x8000, 0x7098, 0xa086, 0xffff, 0x0130, 0x080c,
- 0x251c, 0x080c, 0x6462, 0x0804, 0x123d, 0x70c8, 0xd0ac, 0x1110,
- 0xd09c, 0x0558, 0xd084, 0x0548, 0x0006, 0x70c8, 0xa084, 0x0030,
- 0x000e, 0x1138, 0x00f6, 0x2079, 0x0100, 0x790c, 0xc1b5, 0x790e,
- 0x00fe, 0xd08c, 0x01d0, 0x70cc, 0xa086, 0xffff, 0x0190, 0x080c,
- 0x25fd, 0x080c, 0x6462, 0x70c8, 0xd094, 0x1904, 0x123d, 0x2011,
- 0x0001, 0x2019, 0x0000, 0x080c, 0x2631, 0x080c, 0x6462, 0x0804,
- 0x123d, 0x70d0, 0xa005, 0x1904, 0x123d, 0x7094, 0xa005, 0x1904,
- 0x123d, 0x70c8, 0xd0a4, 0x0110, 0xd0b4, 0x05f8, 0x2001, 0x9252,
- 0x2004, 0xd0ac, 0x01c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x2009,
- 0x0000, 0x0016, 0x080c, 0x4434, 0x1118, 0x6000, 0xd0ec, 0x1138,
- 0x001e, 0x8108, 0x1f04, 0x1209, 0x00ce, 0x015e, 0x0020, 0x001e,
- 0x00ce, 0x015e, 0x0410, 0x00f6, 0x2079, 0x0100, 0x780c, 0xc0b5,
- 0x780e, 0x00fe, 0x7003, 0x0003, 0x709b, 0xffff, 0xa006, 0x080c,
- 0x23ba, 0x080c, 0x370a, 0x2001, 0x94e6, 0x2004, 0xa086, 0x0005,
- 0x1120, 0x2011, 0x0000, 0x080c, 0x718f, 0x2011, 0x0000, 0x080c,
- 0x7199, 0x080c, 0x6462, 0x080c, 0x651c, 0x012e, 0x0005, 0x0016,
- 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0x00f7,
- 0x080c, 0x4186, 0x7940, 0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4,
- 0x0110, 0x7827, 0x0040, 0xd19c, 0x0110, 0x7827, 0x0008, 0x0006,
- 0x0036, 0x0156, 0x7954, 0xd1ac, 0x1904, 0x12a5, 0x080c, 0x4dd7,
- 0x0158, 0x080c, 0x4deb, 0x1128, 0x2001, 0x94d7, 0x2003, 0x0000,
- 0x0070, 0x080c, 0x4dcd, 0x0dc0, 0x2001, 0x94d7, 0x2003, 0xaaaa,
- 0x2001, 0x94d8, 0x2003, 0x0001, 0x080c, 0x4d10, 0x0058, 0x080c,
- 0x4dc5, 0x0140, 0x2009, 0x00f8, 0x080c, 0x4186, 0x7843, 0x0090,
- 0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c,
- 0x4dc5, 0x0138, 0x7824, 0xd0ac, 0x1904, 0x130d, 0x1f04, 0x1284,
- 0x0070, 0x7824, 0x080c, 0x4de1, 0x0118, 0xd0ac, 0x1904, 0x130d,
- 0xa084, 0x1800, 0x0d98, 0x7003, 0x0001, 0x0804, 0x130d, 0x2001,
- 0x0001, 0x080c, 0x23ba, 0x0804, 0x1318, 0x7850, 0xa084, 0x0180,
- 0x7852, 0x782f, 0x0020, 0x20a9, 0x0050, 0x1d04, 0x12ad, 0x2091,
- 0x6000, 0x1f04, 0x12ad, 0x7850, 0xa084, 0x0180, 0xa085, 0x0400,
- 0x7852, 0x782f, 0x0000, 0x080c, 0x4dd7, 0x0158, 0x080c, 0x4deb,
- 0x1128, 0x2001, 0x94d7, 0x2003, 0x0000, 0x0070, 0x080c, 0x4dcd,
- 0x0dc0, 0x2001, 0x94d7, 0x2003, 0xaaaa, 0x2001, 0x94d8, 0x2003,
- 0x0001, 0x080c, 0x4d10, 0x0020, 0x2009, 0x00f8, 0x080c, 0x4186,
- 0x20a9, 0x000e, 0xe000, 0x1f04, 0x12da, 0x7850, 0xa084, 0x0180,
- 0xa085, 0x1400, 0x7852, 0x080c, 0x4dc5, 0x0120, 0x7843, 0x0090,
- 0x7843, 0x0010, 0x2019, 0x61a8, 0x7820, 0xd09c, 0x1130, 0x080c,
- 0x4dc5, 0x0130, 0x7824, 0xd0ac, 0x11c0, 0x8319, 0x1da8, 0x0080,
- 0x7827, 0x1800, 0xe000, 0xe000, 0x7824, 0x080c, 0x4de1, 0x0110,
- 0xd0ac, 0x1158, 0xa084, 0x1800, 0x0d80, 0x7003, 0x0001, 0x0028,
- 0x2001, 0x0001, 0x080c, 0x23ba, 0x0028, 0x7827, 0x0048, 0x7828,
- 0xc09d, 0x782a, 0x7850, 0xa084, 0x0180, 0xa085, 0x0400, 0x7852,
- 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x001e, 0x0005, 0x0005,
- 0x0005, 0x0005, 0x2a70, 0x2001, 0x94d7, 0x2003, 0x0000, 0x7087,
- 0x0000, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0218, 0x704f,
- 0xffff, 0x0010, 0x704f, 0x0000, 0x7057, 0xffff, 0x706f, 0x0000,
- 0x7073, 0x0000, 0x080c, 0x854a, 0x2061, 0x94c7, 0x6003, 0x0909,
- 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013, 0x00ff,
- 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0, 0x2061, 0x94cf,
- 0x6003, 0x8800, 0x6007, 0x0000, 0x600b, 0x0000, 0x600f, 0x0200,
- 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, 0x601f, 0x0000,
- 0x2061, 0x94df, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943,
- 0x600f, 0x2020, 0x0005, 0x04a0, 0x2011, 0x0000, 0x81ff, 0x0570,
- 0xa186, 0x0001, 0x1148, 0x2031, 0x8fff, 0x2039, 0xa501, 0x2021,
- 0x0100, 0x2029, 0xa500, 0x00e8, 0xa186, 0x0002, 0x1118, 0x2011,
- 0x0000, 0x00b8, 0xa186, 0x0005, 0x1118, 0x2011, 0x0001, 0x0088,
- 0xa186, 0x0009, 0x1118, 0x2011, 0x0002, 0x0058, 0xa186, 0x000a,
- 0x1118, 0x2011, 0x0002, 0x0028, 0xa186, 0x0055, 0x1110, 0x2011,
- 0x0003, 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0, 0x0804, 0x104d,
- 0xa00e, 0x2011, 0x0003, 0x2019, 0x13a7, 0x0804, 0x13f8, 0x2019,
- 0xaaaa, 0x2061, 0xffff, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04,
- 0xa306, 0x2262, 0x1110, 0xc1b5, 0xc1a5, 0x2011, 0x0000, 0x2019,
- 0x13ba, 0x04f0, 0x2019, 0xaaaa, 0x2061, 0xffff, 0x2c14, 0x2362,
- 0xe000, 0xe000, 0x2c1c, 0x2061, 0x7fff, 0xe000, 0xe000, 0x2c04,
- 0x2061, 0xffff, 0x2262, 0xa306, 0x0110, 0xc18d, 0x0008, 0xc185,
- 0x2011, 0x0002, 0x2019, 0x13d5, 0x0418, 0x2061, 0xffff, 0x2019,
- 0xaaaa, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04, 0x2262, 0xa306,
- 0x1180, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c1c, 0x2061, 0x7fff,
- 0x2c04, 0x2061, 0xffff, 0x2262, 0xa306, 0x1110, 0xc195, 0x0008,
- 0xc19d, 0x2011, 0x0001, 0x2019, 0x13f6, 0x0010, 0x0804, 0x136c,
- 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0, 0x0837, 0x2091, 0x8000,
- 0x0e04, 0x1400, 0x0006, 0x0016, 0x2079, 0x0000, 0x7818, 0xd084,
- 0x1de8, 0x001e, 0x792e, 0x000e, 0x782a, 0x000e, 0x7826, 0x3900,
- 0x783a, 0x7823, 0x8002, 0x781b, 0x0001, 0x2091, 0x5000, 0x0156,
- 0x0146, 0x20a9, 0x0010, 0x20a1, 0x95e6, 0x2091, 0x2000, 0x40a1,
- 0x20a9, 0x0010, 0x2091, 0x2200, 0x40a1, 0x20a9, 0x0010, 0x2091,
- 0x2400, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2600, 0x40a1, 0x014e,
- 0x015e, 0x2079, 0x9200, 0x7803, 0x0005, 0x2091, 0x4080, 0x0cf8,
- 0x0005, 0x2071, 0x9200, 0x715c, 0x712e, 0x2021, 0x0001, 0xa190,
- 0x0030, 0xa298, 0x0030, 0x0240, 0x7060, 0xa302, 0x1228, 0x220a,
- 0x2208, 0x2310, 0x8420, 0x0ca8, 0x3800, 0xd08c, 0x0148, 0x7060,
- 0xa086, 0x9200, 0x0128, 0x7063, 0x9200, 0x2011, 0x1000, 0x0c48,
- 0x200b, 0x0000, 0x74aa, 0x74ae, 0x70df, 0x0010, 0x0005, 0x00e6,
- 0x0126, 0x2091, 0x8000, 0x2071, 0x9200, 0x70ac, 0x0016, 0x2008,
- 0x70dc, 0xa16a, 0x2100, 0x001e, 0x0268, 0x8001, 0x70ae, 0x702c,
- 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x012e,
- 0x00ee, 0x0005, 0xa06e, 0x0cd8, 0x00e6, 0x2071, 0x9200, 0x0126,
- 0x2091, 0x8000, 0x70ac, 0x8001, 0x0260, 0x70ae, 0x702c, 0x2068,
- 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x012e, 0x00ee,
- 0x0005, 0xa06e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071,
- 0x9200, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000, 0x70ae,
- 0x012e, 0x00ee, 0x0005, 0x8dff, 0x0138, 0x6804, 0x6807, 0x0000,
- 0x0006, 0x0c49, 0x00de, 0x0cb8, 0x0005, 0x00e6, 0x2071, 0x9200,
- 0x70ac, 0xa08a, 0x0010, 0xa00d, 0x00ee, 0x0005, 0x00e6, 0x2071,
- 0x9508, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000, 0x2071,
- 0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x00ee, 0x0005, 0x00e6,
- 0x2270, 0x700b, 0x0000, 0x2071, 0x9508, 0x7018, 0xa088, 0x9511,
- 0x220a, 0x8000, 0xa084, 0x0007, 0x701a, 0x7004, 0xa005, 0x1128,
- 0x00f6, 0x2079, 0x0010, 0x0081, 0x00fe, 0x00ee, 0x0005, 0x00e6,
- 0x2071, 0x9508, 0x7004, 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010,
- 0x0019, 0x00fe, 0x00ee, 0x0005, 0x7000, 0x0002, 0x14f3, 0x1557,
- 0x1574, 0x1574, 0x1f79, 0x7018, 0x711c, 0xa106, 0x1118, 0x7007,
- 0x0000, 0x0005, 0x00d6, 0xa180, 0x9511, 0x2004, 0x700a, 0x2068,
- 0x8108, 0xa18c, 0x0007, 0x711e, 0x7803, 0x0026, 0x6824, 0x7832,
- 0x6828, 0x7836, 0x682c, 0x783a, 0x6830, 0x783e, 0x6810, 0x700e,
- 0x680c, 0x7016, 0x6804, 0x00de, 0xd084, 0x0120, 0x7007, 0x0001,
- 0x0029, 0x0005, 0x7007, 0x0002, 0x00b1, 0x0005, 0x0016, 0x0026,
- 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x1210, 0x2110, 0xa006,
- 0x700e, 0x7212, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803, 0x0041,
- 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x0136, 0x0146, 0x0156,
- 0x7014, 0x2098, 0x20a1, 0x0014, 0x7803, 0x0026, 0x710c, 0x2011,
- 0x0040, 0xa182, 0x0040, 0x1210, 0x2110, 0xa006, 0x700e, 0x22a8,
- 0x53a6, 0x8203, 0x7822, 0x7803, 0x0020, 0x3300, 0x7016, 0x7803,
- 0x0001, 0x015e, 0x014e, 0x013e, 0x002e, 0x001e, 0x0005, 0x0136,
- 0x0146, 0x0156, 0x2099, 0x930e, 0x20a1, 0x0018, 0x20a9, 0x0008,
- 0x53a3, 0x7803, 0x0020, 0x0126, 0x2091, 0x8000, 0x7803, 0x0041,
- 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x700b, 0x9309, 0x012e,
- 0x015e, 0x014e, 0x013e, 0x0005, 0x0136, 0x0146, 0x0156, 0x2001,
- 0x933d, 0x209c, 0x20a1, 0x0014, 0x7803, 0x0026, 0x2001, 0x933e,
- 0x20ac, 0x53a6, 0x2099, 0x933f, 0x20a1, 0x0018, 0x20a9, 0x0008,
- 0x53a3, 0x7803, 0x0020, 0x0126, 0x2091, 0x8000, 0x7803, 0x0001,
- 0x7007, 0x0004, 0x7000, 0xc08c, 0x7002, 0x700b, 0x933a, 0x012e,
- 0x015e, 0x014e, 0x013e, 0x0005, 0x0016, 0x00e6, 0x2071, 0x9508,
- 0x00f6, 0x2079, 0x0010, 0x7904, 0x7803, 0x0002, 0xd1fc, 0x0120,
- 0xa18c, 0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005,
- 0x14ec, 0x15b8, 0x15e2, 0x1608, 0x1638, 0x1f96, 0x15b7, 0x0cf8,
- 0xa18c, 0x0700, 0x1508, 0x0136, 0x0146, 0x0156, 0x7014, 0x20a0,
- 0x2099, 0x0014, 0x7803, 0x0040, 0x7010, 0x20a8, 0x53a5, 0x3400,
- 0x7016, 0x015e, 0x014e, 0x013e, 0x700c, 0xa005, 0x0530, 0x080c,
- 0x151e, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007,
- 0x0000, 0x080c, 0x14ec, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003,
- 0x0200, 0x0ca8, 0xa18c, 0x0700, 0x1130, 0x700c, 0xa005, 0x0168,
- 0x080c, 0x1533, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200,
- 0x7007, 0x0000, 0x080c, 0x14ec, 0x0005, 0x00d6, 0x7008, 0x2068,
- 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, 0x682e, 0x783c, 0x6832,
- 0x680b, 0x0100, 0x00de, 0x7007, 0x0000, 0x080c, 0x14ec, 0x0005,
- 0xa18c, 0x0700, 0x1540, 0x0136, 0x0146, 0x0156, 0x2001, 0x930c,
- 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040,
- 0x20a9, 0x0020, 0x53a5, 0x2001, 0x930e, 0x2004, 0xd0bc, 0x0148,
- 0x2001, 0x9317, 0x2004, 0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020,
- 0x53a5, 0x015e, 0x014e, 0x013e, 0x7007, 0x0000, 0x080c, 0x4f27,
- 0x080c, 0x14ec, 0x0005, 0x2011, 0x8003, 0x080c, 0x3698, 0x0cf8,
- 0xa18c, 0x0700, 0x1148, 0x2001, 0x933c, 0x2003, 0x0100, 0x7007,
- 0x0000, 0x080c, 0x14ec, 0x0005, 0x2011, 0x8004, 0x080c, 0x3698,
- 0x0cf8, 0x0126, 0x2091, 0x2200, 0x2079, 0x0030, 0x2071, 0x9519,
- 0x7003, 0x0000, 0x700f, 0x9520, 0x7013, 0x9520, 0x780f, 0x00f0,
- 0x012e, 0x0005, 0x6934, 0xa184, 0x0007, 0x0002, 0x1666, 0x16ab,
- 0x1666, 0x1666, 0x166a, 0x1693, 0x167a, 0x1671, 0xa085, 0x0001,
- 0x0804, 0x16c5, 0xa186, 0x0024, 0x05f0, 0xa186, 0x002c, 0x05d8,
- 0x0ca8, 0x684c, 0xd0bc, 0x0d90, 0x6860, 0x682e, 0x685c, 0x682a,
- 0x6858, 0x04c8, 0xa18c, 0x00ff, 0xa186, 0x001e, 0x1d38, 0x684c,
- 0xd0bc, 0x0d20, 0x6860, 0x682e, 0x685c, 0x682a, 0x6804, 0x681a,
- 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x1f59, 0x2005,
- 0x6832, 0x6858, 0x0440, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x1970,
- 0x684c, 0xd0ac, 0x0958, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004,
- 0xa084, 0x000f, 0xa080, 0x1f59, 0x2005, 0x6832, 0xa006, 0x682e,
- 0x682a, 0x6858, 0x0080, 0x684c, 0xd0ac, 0x0904, 0x1666, 0xa006,
- 0x682e, 0x682a, 0x6858, 0xa18c, 0x000f, 0xa188, 0x1f59, 0x210d,
- 0x6932, 0x2d08, 0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006,
- 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x0005, 0x20e1, 0x0007,
- 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x82ff, 0x0178, 0xa280,
- 0x0004, 0x00d6, 0x206c, 0x684c, 0xd0dc, 0x1120, 0x080c, 0x165a,
- 0x190c, 0x13fe, 0x6808, 0x8000, 0x680a, 0x00de, 0x0126, 0x0046,
- 0x0036, 0x0026, 0x2091, 0x2200, 0x002e, 0x003e, 0x004e, 0x7000,
- 0xa005, 0x0178, 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a,
- 0x8108, 0xa182, 0x953b, 0x0210, 0x2009, 0x9520, 0x710e, 0x012e,
- 0x0005, 0x7206, 0x2001, 0x16f7, 0x0006, 0x2260, 0x0804, 0x17e8,
- 0x0126, 0x0026, 0x0036, 0x00c6, 0x0006, 0x2091, 0x2200, 0x000e,
- 0x004e, 0x003e, 0x002e, 0x00d6, 0x00c6, 0x2460, 0x6110, 0x2168,
- 0x6a62, 0x6b5e, 0xa005, 0x05b8, 0x6808, 0xa005, 0x0904, 0x177c,
- 0x7000, 0xa005, 0x1108, 0x0430, 0x700c, 0x7110, 0xa106, 0x1904,
- 0x1784, 0x7004, 0xa406, 0x11f0, 0x2001, 0x0005, 0x2004, 0xd08c,
- 0x0130, 0x0046, 0x080c, 0x1942, 0x004e, 0x2460, 0x0c28, 0x2001,
- 0x0207, 0x2004, 0xd09c, 0x1d80, 0x7804, 0xa084, 0x6000, 0x0120,
- 0xa086, 0x6000, 0x0108, 0x0c40, 0x7803, 0x0004, 0x7003, 0x0000,
- 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004, 0x15f0, 0x2009, 0x0048,
- 0x080c, 0x7518, 0x04c8, 0x6808, 0xa005, 0x0570, 0x7000, 0xa005,
- 0x0558, 0x700c, 0x7110, 0xa106, 0x1118, 0x7004, 0xa406, 0x1520,
- 0x2001, 0x0005, 0x2004, 0xd08c, 0x0130, 0x0046, 0x080c, 0x1942,
- 0x004e, 0x2460, 0x0c40, 0x2001, 0x0207, 0x2004, 0xd09c, 0x1d80,
- 0x2001, 0x0005, 0x2004, 0xd08c, 0x1d80, 0x7804, 0xa084, 0x6000,
- 0x0118, 0xa086, 0x6000, 0x1d20, 0x7818, 0x6812, 0x781c, 0x6816,
- 0x7803, 0x0004, 0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x1120,
- 0x2009, 0x0048, 0x080c, 0x7518, 0x00ce, 0x00de, 0x012e, 0x0005,
- 0x00f6, 0x00e6, 0x0026, 0x0036, 0x0046, 0x080c, 0x1c26, 0x0026,
- 0x2071, 0x9519, 0x7000, 0xa086, 0x0000, 0x0580, 0x7004, 0xac06,
+ 0x23fa, 0x080c, 0x5d10, 0x0804, 0x124f, 0x70c8, 0xd0ac, 0x1110,
+ 0xd09c, 0x0520, 0xd084, 0x0510, 0x0006, 0x2001, 0x0103, 0x2003,
+ 0x00ff, 0x000e, 0xd08c, 0x01d0, 0x70cc, 0xa086, 0xffff, 0x0190,
+ 0x080c, 0x24f4, 0x080c, 0x5d10, 0x70c8, 0xd094, 0x1904, 0x124f,
+ 0x2011, 0x0001, 0x2019, 0x0000, 0x080c, 0x2528, 0x080c, 0x5d10,
+ 0x0804, 0x124f, 0x70d0, 0xa005, 0x1904, 0x124f, 0x7094, 0xa005,
+ 0x1904, 0x124f, 0x70c8, 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x124f,
+ 0x2001, 0x8b52, 0x2004, 0xd0ac, 0x01c0, 0x0156, 0x00c6, 0x20a9,
+ 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x430a, 0x1118, 0x6000,
+ 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x120b, 0x00ce, 0x015e,
+ 0x0020, 0x001e, 0x00ce, 0x015e, 0x0490, 0x0006, 0x2001, 0x0103,
+ 0x2003, 0x00ff, 0x000e, 0x7003, 0x0003, 0x709b, 0xffff, 0xa006,
+ 0x080c, 0x2298, 0x080c, 0x3689, 0x00f6, 0x2079, 0x0100, 0x080c,
+ 0x4c68, 0x0150, 0x080c, 0x4c42, 0x7828, 0x0118, 0xa084, 0xe1ff,
+ 0x0010, 0xa084, 0xffdf, 0x782a, 0x00fe, 0x2001, 0x8dab, 0x2004,
+ 0xa086, 0x0005, 0x1120, 0x2011, 0x0000, 0x080c, 0x695c, 0x2011,
+ 0x0000, 0x080c, 0x6966, 0x080c, 0x5d10, 0x080c, 0x5dc2, 0x012e,
+ 0x0005, 0x0016, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100,
+ 0x2009, 0x00f7, 0x080c, 0x40be, 0x7940, 0xa18c, 0x0010, 0x7942,
+ 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040, 0xd19c, 0x0110, 0x7827,
+ 0x0008, 0x0006, 0x0036, 0x0156, 0x7954, 0xd1ac, 0x1904, 0x12b7,
+ 0x080c, 0x4c54, 0x0158, 0x080c, 0x4c68, 0x1128, 0x2001, 0x8d9c,
+ 0x2003, 0x0000, 0x0070, 0x080c, 0x4c4a, 0x0dc0, 0x2001, 0x8d9c,
+ 0x2003, 0xaaaa, 0x2001, 0x8d9d, 0x2003, 0x0001, 0x080c, 0x4b8b,
+ 0x0058, 0x080c, 0x4c42, 0x0140, 0x2009, 0x00f8, 0x080c, 0x40be,
+ 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820, 0xd09c,
+ 0x1138, 0x080c, 0x4c42, 0x0138, 0x7824, 0xd0ac, 0x1904, 0x131f,
+ 0x1f04, 0x1296, 0x0070, 0x7824, 0x080c, 0x4c5e, 0x0118, 0xd0ac,
+ 0x1904, 0x131f, 0xa084, 0x1800, 0x0d98, 0x7003, 0x0001, 0x0804,
+ 0x131f, 0x2001, 0x0001, 0x080c, 0x2298, 0x0804, 0x132a, 0x7850,
+ 0xa084, 0x0180, 0x7852, 0x782f, 0x0020, 0x20a9, 0x0050, 0x1d04,
+ 0x12bf, 0x2091, 0x6000, 0x1f04, 0x12bf, 0x7850, 0xa084, 0x0180,
+ 0xa085, 0x0400, 0x7852, 0x782f, 0x0000, 0x080c, 0x4c54, 0x0158,
+ 0x080c, 0x4c68, 0x1128, 0x2001, 0x8d9c, 0x2003, 0x0000, 0x0070,
+ 0x080c, 0x4c4a, 0x0dc0, 0x2001, 0x8d9c, 0x2003, 0xaaaa, 0x2001,
+ 0x8d9d, 0x2003, 0x0001, 0x080c, 0x4b8b, 0x0020, 0x2009, 0x00f8,
+ 0x080c, 0x40be, 0x20a9, 0x000e, 0xe000, 0x1f04, 0x12ec, 0x7850,
+ 0xa084, 0x0180, 0xa085, 0x1400, 0x7852, 0x080c, 0x4c42, 0x0120,
+ 0x7843, 0x0090, 0x7843, 0x0010, 0x2019, 0x61a8, 0x7820, 0xd09c,
+ 0x1130, 0x080c, 0x4c42, 0x0130, 0x7824, 0xd0ac, 0x11c0, 0x8319,
+ 0x1da8, 0x0080, 0x7827, 0x1800, 0xe000, 0xe000, 0x7824, 0x080c,
+ 0x4c5e, 0x0110, 0xd0ac, 0x1158, 0xa084, 0x1800, 0x0d80, 0x7003,
+ 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x2298, 0x0028, 0x7827,
+ 0x0048, 0x7828, 0xc09d, 0x782a, 0x7850, 0xa084, 0x0180, 0xa085,
+ 0x0400, 0x7852, 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x001e,
+ 0x0005, 0x0005, 0x0005, 0x0005, 0x2a70, 0x2001, 0x8d9c, 0x2003,
+ 0x0000, 0x7087, 0x0000, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002,
+ 0x0218, 0x704f, 0xffff, 0x0010, 0x704f, 0x0000, 0x7057, 0xffff,
+ 0x706f, 0x0000, 0x7073, 0x0000, 0x080c, 0x7deb, 0x2061, 0x8d8c,
+ 0x6003, 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200,
+ 0x6013, 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0,
+ 0x2061, 0x8d94, 0x6003, 0x8800, 0x6007, 0x0000, 0x600b, 0x0000,
+ 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001,
+ 0x601f, 0x0000, 0x2061, 0x8da4, 0x6003, 0x514c, 0x6007, 0x4f47,
+ 0x600b, 0x4943, 0x600f, 0x2020, 0x0005, 0x04a0, 0x2011, 0x0000,
+ 0x81ff, 0x0570, 0xa186, 0x0001, 0x1148, 0x2031, 0x8fff, 0x2039,
+ 0x9e01, 0x2021, 0x0100, 0x2029, 0x9e00, 0x00e8, 0xa186, 0x0002,
+ 0x1118, 0x2011, 0x0000, 0x00b8, 0xa186, 0x0005, 0x1118, 0x2011,
+ 0x0001, 0x0088, 0xa186, 0x0009, 0x1118, 0x2011, 0x0002, 0x0058,
+ 0xa186, 0x000a, 0x1118, 0x2011, 0x0002, 0x0028, 0xa186, 0x0055,
+ 0x1110, 0x2011, 0x0003, 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0,
+ 0x0804, 0x104d, 0xa00e, 0x2011, 0x0003, 0x2019, 0x13b9, 0x0804,
+ 0x140a, 0x2019, 0xaaaa, 0x2061, 0xffff, 0x2c14, 0x2362, 0xe000,
+ 0xe000, 0x2c04, 0xa306, 0x2262, 0x1110, 0xc1b5, 0xc1a5, 0x2011,
+ 0x0000, 0x2019, 0x13cc, 0x04f0, 0x2019, 0xaaaa, 0x2061, 0xffff,
+ 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c1c, 0x2061, 0x7fff, 0xe000,
+ 0xe000, 0x2c04, 0x2061, 0xffff, 0x2262, 0xa306, 0x0110, 0xc18d,
+ 0x0008, 0xc185, 0x2011, 0x0002, 0x2019, 0x13e7, 0x0418, 0x2061,
+ 0xffff, 0x2019, 0xaaaa, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04,
+ 0x2262, 0xa306, 0x1180, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c1c,
+ 0x2061, 0x7fff, 0x2c04, 0x2061, 0xffff, 0x2262, 0xa306, 0x1110,
+ 0xc195, 0x0008, 0xc19d, 0x2011, 0x0001, 0x2019, 0x1408, 0x0010,
+ 0x0804, 0x137e, 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0, 0x0837,
+ 0x2091, 0x8000, 0x0e04, 0x1412, 0x0006, 0x0016, 0x2079, 0x0000,
+ 0x7818, 0xd084, 0x1de8, 0x001e, 0x792e, 0x000e, 0x782a, 0x000e,
+ 0x7826, 0x3900, 0x783a, 0x7823, 0x8002, 0x781b, 0x0001, 0x2091,
+ 0x5000, 0x0156, 0x0146, 0x20a9, 0x0010, 0x20a1, 0x8eaa, 0x2091,
+ 0x2000, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2200, 0x40a1, 0x20a9,
+ 0x0010, 0x2091, 0x2400, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2600,
+ 0x40a1, 0x014e, 0x015e, 0x2079, 0x8b00, 0x7803, 0x0005, 0x2091,
+ 0x4080, 0x0cf8, 0x0005, 0x2071, 0x8b00, 0x715c, 0x712e, 0x2021,
+ 0x0001, 0xa190, 0x0030, 0xa298, 0x0030, 0x0240, 0x7060, 0xa302,
+ 0x1228, 0x220a, 0x2208, 0x2310, 0x8420, 0x0ca8, 0x3800, 0xd08c,
+ 0x0148, 0x7060, 0xa086, 0x8b00, 0x0128, 0x7063, 0x8b00, 0x2011,
+ 0x1000, 0x0c48, 0x200b, 0x0000, 0x74aa, 0x74ae, 0x0005, 0x00e6,
+ 0x0126, 0x2091, 0x8000, 0x2071, 0x8b00, 0x70ac, 0xa0ea, 0x0010,
+ 0x0268, 0x8001, 0x70ae, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b,
+ 0x0000, 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e, 0x0cd8,
+ 0x00e6, 0x2071, 0x8b00, 0x0126, 0x2091, 0x8000, 0x70ac, 0x8001,
+ 0x0260, 0x70ae, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000,
+ 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e, 0x0cd8, 0x00e6,
+ 0x0126, 0x2091, 0x8000, 0x2071, 0x8b00, 0x702c, 0x206a, 0x2d00,
+ 0x702e, 0x70ac, 0x8000, 0x70ae, 0x012e, 0x00ee, 0x0005, 0x8dff,
+ 0x0138, 0x6804, 0x6807, 0x0000, 0x0006, 0x0c49, 0x00de, 0x0cb8,
+ 0x0005, 0x00e6, 0x2071, 0x8b00, 0x70ac, 0xa08a, 0x0010, 0xa00d,
+ 0x00ee, 0x0005, 0x00e6, 0x2071, 0x8dcd, 0x7007, 0x0000, 0x701b,
+ 0x0000, 0x701f, 0x0000, 0x2071, 0x0000, 0x7010, 0xa085, 0x8004,
+ 0x7012, 0x00ee, 0x0005, 0x00e6, 0x2270, 0x700b, 0x0000, 0x2071,
+ 0x8dcd, 0x7018, 0xa088, 0x8dd6, 0x220a, 0x8000, 0xa084, 0x0007,
+ 0x701a, 0x7004, 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010, 0x0081,
+ 0x00fe, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x8dcd, 0x7004, 0xa005,
+ 0x1128, 0x00f6, 0x2079, 0x0010, 0x0019, 0x00fe, 0x00ee, 0x0005,
+ 0x7000, 0x0002, 0x14fe, 0x1562, 0x157f, 0x157f, 0x7018, 0x711c,
+ 0xa106, 0x1118, 0x7007, 0x0000, 0x0005, 0x00d6, 0xa180, 0x8dd6,
+ 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007, 0x711e, 0x7803,
+ 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c, 0x783a, 0x6830,
+ 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804, 0x00de, 0xd084,
+ 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, 0x0002, 0x00b1,
+ 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040,
+ 0x1210, 0x2110, 0xa006, 0x700e, 0x7212, 0x8203, 0x7822, 0x7803,
+ 0x0020, 0x7803, 0x0041, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026,
+ 0x0136, 0x0146, 0x0156, 0x7014, 0x2098, 0x20a1, 0x0014, 0x7803,
+ 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x1210, 0x2110,
+ 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803, 0x0020,
+ 0x3300, 0x7016, 0x7803, 0x0001, 0x015e, 0x014e, 0x013e, 0x002e,
+ 0x001e, 0x0005, 0x0136, 0x0146, 0x0156, 0x2099, 0x8bf9, 0x20a1,
+ 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126, 0x2091,
+ 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002,
+ 0x700b, 0x8bf4, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005, 0x0136,
+ 0x0146, 0x0156, 0x2001, 0x8c28, 0x209c, 0x20a1, 0x0014, 0x7803,
+ 0x0026, 0x2001, 0x8c29, 0x20ac, 0x53a6, 0x2099, 0x8c2a, 0x20a1,
+ 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126, 0x2091,
+ 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c, 0x7002,
+ 0x700b, 0x8c25, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005, 0x0016,
+ 0x00e6, 0x2071, 0x8dcd, 0x00f6, 0x2079, 0x0010, 0x7904, 0x7803,
+ 0x0002, 0xd1fc, 0x0120, 0xa18c, 0x0700, 0x7004, 0x0023, 0x00fe,
+ 0x00ee, 0x001e, 0x0005, 0x14f8, 0x15c2, 0x15f0, 0x161a, 0x164a,
+ 0x15c1, 0x0cf8, 0xa18c, 0x0700, 0x1528, 0x0136, 0x0146, 0x0156,
+ 0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010, 0x20a8,
+ 0x53a5, 0x3400, 0x7016, 0x015e, 0x014e, 0x013e, 0x700c, 0xa005,
+ 0x0570, 0x7830, 0x7832, 0x7834, 0x7836, 0x080c, 0x1529, 0x0005,
+ 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007, 0x0000, 0x080c,
+ 0x14f8, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200, 0x0ca8,
+ 0xa18c, 0x0700, 0x1150, 0x700c, 0xa005, 0x0188, 0x7830, 0x7832,
+ 0x7834, 0x7836, 0x080c, 0x153e, 0x0005, 0x7008, 0xa080, 0x0002,
+ 0x2003, 0x0200, 0x7007, 0x0000, 0x080c, 0x14f8, 0x0005, 0x00d6,
+ 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, 0x682e,
+ 0x783c, 0x6832, 0x680b, 0x0100, 0x00de, 0x7007, 0x0000, 0x080c,
+ 0x14f8, 0x0005, 0xa18c, 0x0700, 0x1540, 0x0136, 0x0146, 0x0156,
+ 0x2001, 0x8bf7, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099, 0x0014,
+ 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, 0x8bf9, 0x2004,
+ 0xd0bc, 0x0148, 0x2001, 0x8c02, 0x2004, 0xa080, 0x000d, 0x20a0,
+ 0x20a9, 0x0020, 0x53a5, 0x015e, 0x014e, 0x013e, 0x7007, 0x0000,
+ 0x080c, 0x4e43, 0x080c, 0x14f8, 0x0005, 0x2011, 0x8003, 0x080c,
+ 0x3617, 0x0cf8, 0xa18c, 0x0700, 0x1148, 0x2001, 0x8c27, 0x2003,
+ 0x0100, 0x7007, 0x0000, 0x080c, 0x14f8, 0x0005, 0x2011, 0x8004,
+ 0x080c, 0x3617, 0x0cf8, 0x0126, 0x2091, 0x2200, 0x2079, 0x0030,
+ 0x2071, 0x8dde, 0x7003, 0x0000, 0x700f, 0x8de4, 0x7013, 0x8de4,
+ 0x780f, 0x00f6, 0x012e, 0x0005, 0x6934, 0xa184, 0x0007, 0x0002,
+ 0x1678, 0x16b6, 0x1678, 0x1678, 0x1678, 0x169e, 0x1685, 0x167c,
+ 0xa085, 0x0001, 0x0804, 0x16d0, 0x684c, 0xd0bc, 0x0dc8, 0x6860,
+ 0x682e, 0x685c, 0x682a, 0x6858, 0x04c8, 0xa18c, 0x00ff, 0xa186,
+ 0x001e, 0x1d70, 0x684c, 0xd0bc, 0x0d58, 0x6860, 0x682e, 0x685c,
+ 0x682a, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f,
+ 0xa080, 0x1e76, 0x2005, 0x6832, 0x6858, 0x0440, 0xa18c, 0x00ff,
+ 0xa186, 0x0015, 0x19a8, 0x684c, 0xd0ac, 0x0990, 0x6804, 0x681a,
+ 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x1e76, 0x2005,
+ 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0080, 0x684c, 0xd0ac,
+ 0x0904, 0x1678, 0xa006, 0x682e, 0x682a, 0x6858, 0xa18c, 0x000f,
+ 0xa188, 0x1e76, 0x210d, 0x6932, 0x2d08, 0x691a, 0x6826, 0x684c,
+ 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916,
+ 0x0005, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004,
+ 0x82ff, 0x0178, 0xa280, 0x0004, 0x00d6, 0x206c, 0x684c, 0xd0dc,
+ 0x1120, 0x080c, 0x166c, 0x190c, 0x1410, 0x6808, 0x8000, 0x680a,
+ 0x00de, 0x0126, 0x0046, 0x0036, 0x0026, 0x2091, 0x2200, 0x002e,
+ 0x003e, 0x004e, 0x7000, 0xa005, 0x01d0, 0x710c, 0x220a, 0x8108,
+ 0x230a, 0x8108, 0x240a, 0x8108, 0xa182, 0x8dff, 0x0210, 0x2009,
+ 0x8de4, 0x710e, 0x7010, 0xa102, 0xa082, 0x0009, 0x0118, 0xa080,
+ 0x001b, 0x1118, 0x2009, 0x0138, 0x200a, 0x012e, 0x0005, 0x7206,
+ 0x2001, 0x170d, 0x0006, 0x2260, 0x0804, 0x180c, 0x0126, 0x0026,
+ 0x0036, 0x00c6, 0x0006, 0x2091, 0x2200, 0x000e, 0x004e, 0x003e,
+ 0x002e, 0x00d6, 0x00c6, 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e,
+ 0xa005, 0x05b8, 0x6808, 0xa005, 0x0904, 0x1792, 0x7000, 0xa005,
+ 0x1108, 0x0430, 0x700c, 0x7110, 0xa106, 0x1904, 0x179a, 0x7004,
+ 0xa406, 0x11f0, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0130, 0x0046,
+ 0x080c, 0x18ee, 0x004e, 0x2460, 0x0c28, 0x2001, 0x0207, 0x2004,
+ 0xd09c, 0x1d80, 0x7804, 0xa084, 0x6000, 0x0120, 0xa086, 0x6000,
+ 0x0108, 0x0c40, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060,
+ 0x6100, 0xa18e, 0x0004, 0x15f0, 0x2009, 0x0048, 0x080c, 0x6d3f,
+ 0x04c8, 0x6808, 0xa005, 0x0570, 0x7000, 0xa005, 0x0558, 0x700c,
+ 0x7110, 0xa106, 0x1118, 0x7004, 0xa406, 0x1520, 0x2001, 0x0005,
+ 0x2004, 0xd08c, 0x0130, 0x0046, 0x080c, 0x18ee, 0x004e, 0x2460,
+ 0x0c40, 0x2001, 0x0207, 0x2004, 0xd09c, 0x1d80, 0x2001, 0x0005,
+ 0x2004, 0xd08c, 0x1d80, 0x7804, 0xa084, 0x6000, 0x0118, 0xa086,
+ 0x6000, 0x1d20, 0x7818, 0x6812, 0x781c, 0x6816, 0x7803, 0x0004,
+ 0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x1120, 0x2009, 0x0048,
+ 0x080c, 0x6d3f, 0x00ce, 0x00de, 0x012e, 0x0005, 0x00f6, 0x00e6,
+ 0x0026, 0x0036, 0x0046, 0x0056, 0x080c, 0x1b5e, 0x0026, 0x0056,
+ 0x2071, 0x8dde, 0x7000, 0xa086, 0x0000, 0x0580, 0x7004, 0xac06,
0x11f8, 0x2079, 0x0030, 0x7000, 0xa086, 0x0003, 0x01c8, 0x7804,
0xd0fc, 0x1198, 0x2001, 0x0207, 0x2004, 0xd09c, 0x1dc0, 0x7803,
0x0004, 0x7804, 0xd0ac, 0x1de8, 0x7803, 0x0002, 0x7803, 0x0009,
- 0x7003, 0x0003, 0x7007, 0x0000, 0x0018, 0x080c, 0x1942, 0x08d0,
- 0x0156, 0x20a9, 0x0009, 0x2009, 0x9520, 0x2104, 0xac06, 0x1108,
- 0x200a, 0xa188, 0x0003, 0x1f04, 0x17bd, 0x015e, 0x002e, 0x2001,
- 0x015d, 0x201c, 0x831a, 0x2302, 0x2001, 0x0138, 0x2202, 0x004e,
- 0x003e, 0x002e, 0x00ee, 0x00fe, 0x0005, 0x700c, 0x7110, 0xa106,
- 0x0904, 0x182c, 0x2104, 0x7006, 0x2060, 0x8108, 0x211c, 0x8108,
- 0x2124, 0x8108, 0xa182, 0x953b, 0x0210, 0x2009, 0x9520, 0x7112,
- 0x8cff, 0x05a0, 0x6010, 0x2068, 0x2d58, 0x6828, 0xa406, 0x1598,
- 0x682c, 0xa306, 0x1580, 0x684c, 0xd0f4, 0x1540, 0x6850, 0xd0f4,
- 0x1130, 0x7803, 0x0004, 0x6810, 0x781a, 0x6814, 0x781e, 0x6824,
- 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f,
- 0x6834, 0xa08c, 0x00ff, 0xa186, 0x0024, 0x0118, 0xa186, 0x002c,
- 0x1120, 0x2009, 0x0011, 0x00d9, 0x0038, 0x2009, 0x0011, 0x00b9,
- 0x0118, 0x2009, 0x0001, 0x0099, 0x2d58, 0x0005, 0x7803, 0x0004,
- 0x080c, 0x1be2, 0x0cd0, 0x601c, 0xa086, 0x0008, 0x1108, 0x0858,
- 0x080c, 0x1fa7, 0x1d98, 0x0838, 0x7003, 0x0000, 0x0005, 0x8aff,
- 0x0904, 0x191c, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x11b8, 0xd0f4,
- 0x1538, 0x00d6, 0x2805, 0xac68, 0x2900, 0x0002, 0x18b6, 0x1867,
- 0x1867, 0x18b6, 0x18b9, 0x18ae, 0x18b6, 0x1867, 0x18b6, 0x1878,
- 0x1878, 0x18b6, 0x18b9, 0x18b6, 0x18a6, 0x1878, 0x7803, 0x0004,
- 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x00d6, 0xd99c,
- 0x0904, 0x1909, 0x2805, 0xac68, 0x6f08, 0x6e0c, 0x0804, 0x1909,
- 0xc0f4, 0x6852, 0x6b6c, 0x6a70, 0x00d6, 0x0804, 0x1910, 0x2d10,
- 0x00de, 0x00d6, 0x6834, 0x2268, 0xa084, 0x00ff, 0xa096, 0x0024,
- 0x0904, 0x18e9, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0804, 0x1909,
- 0x2d10, 0x00de, 0x00d6, 0x6834, 0x2268, 0xa084, 0x00ff, 0xa096,
- 0x002c, 0x0904, 0x18c6, 0x7b0c, 0xd3bc, 0x01c0, 0x7004, 0x00e6,
- 0x2070, 0x701c, 0x00ee, 0xa086, 0x0008, 0x1180, 0x7b08, 0xa39c,
- 0x0fff, 0x2d20, 0x7a1c, 0x82ff, 0x1120, 0x7818, 0xa302, 0x0208,
- 0x7b18, 0xa016, 0x7a1e, 0x7b1a, 0x2468, 0x0010, 0x6b10, 0x6a14,
- 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0804, 0x1909, 0x00de, 0x00d6,
- 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x1140, 0x00de, 0x080c,
- 0x1f1b, 0x1904, 0x182f, 0xa00e, 0x0804, 0x191c, 0x00de, 0x080c,
- 0x13fe, 0x2d10, 0x00de, 0x00d6, 0x6834, 0x2268, 0xa084, 0x00ff,
- 0xa096, 0x0024, 0x0530, 0xa096, 0x002c, 0x1d80, 0x6b10, 0xa3a6,
- 0xffff, 0x1130, 0x2d10, 0x00de, 0x00d6, 0x080c, 0x59f4, 0x2268,
- 0x2d10, 0x00de, 0x00d6, 0x7314, 0x685c, 0xa086, 0x0001, 0x1120,
- 0x6868, 0xa005, 0x0108, 0x2018, 0x2268, 0x2011, 0x0000, 0x6d00,
- 0x6c04, 0x6f08, 0x6e0c, 0x780f, 0x00f0, 0xe000, 0xe000, 0xe000,
- 0x0400, 0x6b08, 0xa3a6, 0xffff, 0x1130, 0x2d10, 0x00de, 0x00d6,
- 0x080c, 0x59f4, 0x2268, 0x2d10, 0x00de, 0x00d6, 0x7314, 0x685c,
- 0xa086, 0x0001, 0x1120, 0x6868, 0xa005, 0x0108, 0x2018, 0x2268,
- 0x2011, 0x0000, 0x6d00, 0x6c04, 0x780f, 0x00f0, 0xe000, 0xe000,
- 0xe000, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902,
- 0x7000, 0x8000, 0x7002, 0x00de, 0x6828, 0xa300, 0x682a, 0x682c,
- 0xa201, 0x682e, 0x080c, 0x1f1b, 0x0005, 0x080c, 0x13fe, 0x7803,
- 0x0004, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068, 0x7003, 0x0000,
- 0x080c, 0x1c02, 0x080c, 0x82ee, 0x0170, 0x6808, 0x8001, 0x680a,
- 0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff, 0x682f, 0xffff,
- 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x80f6, 0x0804, 0x1b4b,
- 0x080c, 0x13fe, 0x0126, 0x2091, 0x2200, 0x0006, 0x0016, 0x2b68,
- 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x1978,
- 0xa184, 0x0003, 0xa086, 0x0003, 0x0d58, 0x7000, 0x0002, 0x195f,
- 0x1961, 0x1aa6, 0x1b20, 0x1b3a, 0x195f, 0x195f, 0x195f, 0x080c,
- 0x13fe, 0x8001, 0x7002, 0xa184, 0x0880, 0x1904, 0x19a8, 0x6834,
- 0xa084, 0x00ff, 0xa086, 0x0024, 0x0130, 0x6834, 0xa084, 0x00ff,
- 0xa086, 0x002c, 0x1518, 0x6864, 0x8000, 0x6866, 0xd19c, 0x0140,
- 0x7004, 0x2060, 0x2009, 0x0102, 0x080c, 0x7518, 0x0804, 0x1a64,
- 0x8aff, 0x0130, 0x2009, 0x0001, 0x080c, 0x182f, 0x0804, 0x1b4b,
- 0x7004, 0x2060, 0x2009, 0x0106, 0x080c, 0x7518, 0x7007, 0x0000,
- 0x7803, 0x0009, 0x7003, 0x0003, 0x0804, 0x1b4b, 0xd19c, 0x1904,
- 0x1a49, 0x8aff, 0x0904, 0x1a49, 0x2009, 0x0001, 0x080c, 0x182f,
- 0x0904, 0x1b4b, 0x2009, 0x0001, 0x080c, 0x182f, 0x0804, 0x1b4b,
- 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, 0x1904, 0x1a18, 0x6834,
- 0xa084, 0x00ff, 0xa086, 0x0024, 0x0130, 0x6834, 0xa084, 0x00ff,
- 0xa086, 0x002c, 0x1138, 0xd19c, 0x0128, 0x6864, 0x8000, 0x6866,
- 0x0804, 0x1978, 0x0026, 0x0036, 0x7c20, 0x7d24, 0x7e30, 0x7f34,
- 0x7818, 0x6812, 0x781c, 0x6816, 0x2001, 0x0201, 0x2004, 0xa005,
- 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803, 0x0009, 0x7003, 0x0004,
- 0x0070, 0x6834, 0xa084, 0x00ff, 0xa086, 0x0024, 0x0140, 0x6834,
- 0xa084, 0x00ff, 0xa086, 0x002c, 0x0110, 0x080c, 0x1b4f, 0x6b28,
- 0x6a2c, 0x2400, 0x686e, 0xa31a, 0x2500, 0x6872, 0xa213, 0x6b2a,
- 0x6a2e, 0x003e, 0x002e, 0x6e1e, 0x6f22, 0x080c, 0x1f31, 0x2a00,
- 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852,
- 0x6808, 0x8001, 0x680a, 0x1148, 0x684c, 0xd0e4, 0x0130, 0x7004,
- 0x2060, 0x2009, 0x0048, 0x080c, 0x7518, 0x7000, 0xa086, 0x0004,
- 0x0904, 0x1b4b, 0x7003, 0x0000, 0x080c, 0x17d5, 0x0804, 0x1b4b,
- 0x0056, 0x7d0c, 0xd5bc, 0x1110, 0x080c, 0x9171, 0x005e, 0x080c,
- 0x1c02, 0x7004, 0x7007, 0x0000, 0x2060, 0x601c, 0xa086, 0x0009,
- 0x1198, 0x790c, 0x0016, 0x2009, 0x0106, 0x080c, 0x7518, 0x001e,
- 0xd0ec, 0x1118, 0x2009, 0x0009, 0x0010, 0x2009, 0x0019, 0x7902,
- 0x7003, 0x0003, 0x0804, 0x1b4b, 0x682b, 0xffff, 0x682f, 0xffff,
- 0x6808, 0x8001, 0x680a, 0x697c, 0x791a, 0x6980, 0x791e, 0x0804,
- 0x1b4b, 0x7818, 0x6812, 0x7a1c, 0x6a16, 0xd19c, 0x0118, 0xa205,
- 0x1904, 0x19a8, 0x684c, 0xc0f5, 0x684e, 0x7814, 0xa005, 0x1180,
- 0x7003, 0x0000, 0x6808, 0x8001, 0x680a, 0x1130, 0x7004, 0x2060,
- 0x2009, 0x0048, 0x080c, 0x7518, 0x080c, 0x17d5, 0x0804, 0x1b4b,
- 0x7818, 0x6812, 0x781c, 0x6816, 0x7814, 0x7908, 0xa18c, 0x0fff,
- 0xa188, 0x0007, 0x8114, 0x8214, 0x8214, 0xa10a, 0x8104, 0x8004,
- 0x8004, 0xa20a, 0x810b, 0x810b, 0x810b, 0x080c, 0x1c40, 0x7803,
- 0x0004, 0x780f, 0xffff, 0x7803, 0x0001, 0x7804, 0xd0fc, 0x0de8,
- 0x7803, 0x0002, 0x7803, 0x0004, 0x780f, 0x00f0, 0x7004, 0x7007,
- 0x0000, 0x2060, 0x2009, 0x0048, 0x080c, 0x7518, 0x080c, 0x1c62,
- 0x0958, 0x7908, 0xd1ec, 0x1118, 0x2009, 0x0009, 0x0010, 0x2009,
- 0x0019, 0x7902, 0x7003, 0x0003, 0x0804, 0x1b4b, 0x8001, 0x7002,
- 0xd194, 0x0178, 0x7804, 0xd0fc, 0x1904, 0x194a, 0xd09c, 0x11a8,
- 0x8aff, 0x0904, 0x1b4b, 0x2009, 0x0001, 0x080c, 0x182f, 0x0804,
- 0x1b4b, 0xa184, 0x0888, 0x1148, 0x8aff, 0x0904, 0x1b4b, 0x2009,
- 0x0001, 0x080c, 0x182f, 0x0804, 0x1b4b, 0x7803, 0x0004, 0x7003,
- 0x0000, 0xd1bc, 0x1904, 0x1b0d, 0x0026, 0x0036, 0x7c20, 0x7d24,
- 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, 0x2001, 0x0201,
- 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803, 0x0009,
- 0x7003, 0x0004, 0x0020, 0x0016, 0x080c, 0x1b4f, 0x001e, 0x6b28,
- 0x6a2c, 0x080c, 0x1f31, 0x00d6, 0x2805, 0xac68, 0x6034, 0xd09c,
- 0x1128, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0020, 0x6810, 0xa31a,
- 0x6814, 0xa213, 0x00de, 0xd194, 0x0904, 0x19e9, 0x2a00, 0x6826,
- 0x2c00, 0x681a, 0x2800, 0x6832, 0x6808, 0x8001, 0x680a, 0x6b2a,
- 0x6a2e, 0x003e, 0x002e, 0x0804, 0x1a64, 0x0056, 0x7d0c, 0x080c,
- 0x9171, 0x005e, 0x080c, 0x1c02, 0x682b, 0xffff, 0x682f, 0xffff,
- 0x6808, 0x8001, 0x680a, 0x697c, 0x791a, 0x6980, 0x791e, 0x0458,
- 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, 0x0180, 0x6808,
- 0x8001, 0x680a, 0x1160, 0x7004, 0x2060, 0x2009, 0x0048, 0x601c,
- 0xa086, 0x0009, 0x1110, 0x080c, 0x13fe, 0x080c, 0x7518, 0x080c,
- 0x17d5, 0x0088, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060,
- 0x6010, 0xa005, 0x0da0, 0x2068, 0x6808, 0x8000, 0x680a, 0x6c28,
- 0x6b2c, 0x080c, 0x17e8, 0x001e, 0x000e, 0x012e, 0x0005, 0x700c,
- 0x7110, 0xa106, 0x0904, 0x1bd6, 0x7004, 0x0016, 0x210c, 0xa106,
- 0x001e, 0x0904, 0x1bd6, 0x00d6, 0x00c6, 0x216c, 0x2d00, 0xa005,
- 0x0904, 0x1bd4, 0x6810, 0x2068, 0x6834, 0xa084, 0x00ff, 0xa086,
- 0x0024, 0x0904, 0x1bd4, 0x6834, 0xa084, 0x00ff, 0xa086, 0x002c,
- 0x0904, 0x1bd4, 0x6850, 0xd0fc, 0x0558, 0x8108, 0x2104, 0x6b2c,
- 0xa306, 0x1904, 0x1bd4, 0x8108, 0x2104, 0x6a28, 0xa206, 0x1904,
- 0x1bd4, 0x6850, 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822, 0x6870,
- 0x7826, 0x681c, 0x7832, 0x6820, 0x7836, 0x6818, 0x2060, 0x6034,
- 0xd09c, 0x0150, 0x6830, 0x2005, 0x00d6, 0xac68, 0x6808, 0x783a,
- 0x680c, 0x783e, 0x00de, 0x0490, 0xa006, 0x783a, 0x783e, 0x0470,
- 0x8108, 0x2104, 0xa005, 0x1580, 0x8108, 0x2104, 0xa005, 0x1560,
- 0x6850, 0xc0f5, 0x6852, 0x6830, 0x2005, 0x6918, 0xa160, 0x6834,
- 0xd09c, 0x1170, 0x6008, 0x7822, 0x686e, 0x600c, 0x7826, 0x6872,
- 0x6000, 0x7832, 0x6004, 0x7836, 0xa006, 0x783a, 0x783e, 0x0070,
- 0x6010, 0x7822, 0x686e, 0x6014, 0x7826, 0x6872, 0x6000, 0x7832,
- 0x6004, 0x7836, 0x6008, 0x783a, 0x600c, 0x783e, 0x6810, 0x781a,
- 0x6814, 0x781e, 0x7803, 0x0011, 0x00ce, 0x00de, 0x0005, 0x2011,
- 0x0201, 0x2009, 0x003c, 0x2204, 0xa005, 0x1118, 0x8109, 0x1dd8,
- 0x0005, 0x0005, 0x0ca1, 0x01e0, 0x7908, 0xd1ec, 0x1160, 0x080c,
- 0x1c62, 0x0148, 0x7803, 0x0009, 0x7904, 0xd1fc, 0x0de8, 0x7803,
- 0x0006, 0x0c29, 0x0168, 0x780c, 0xd0a4, 0x1150, 0x7007, 0x0000,
- 0x080c, 0x1c62, 0x0130, 0x7803, 0x0019, 0x7003, 0x0003, 0x0008,
- 0x0009, 0x0005, 0x00c6, 0x0411, 0x20e1, 0x9028, 0x700c, 0x7110,
- 0xa106, 0x0190, 0x2104, 0xa005, 0x0130, 0x2060, 0x6010, 0x2060,
- 0x6008, 0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0x953b, 0x0210,
- 0x2009, 0x9520, 0x7112, 0x0c50, 0x2001, 0x015d, 0x200c, 0x810a,
- 0x2102, 0x2001, 0x0138, 0x2202, 0x00ce, 0x0005, 0x2001, 0x0138,
- 0x2014, 0x2003, 0x0000, 0x2021, 0xb015, 0x2001, 0x0141, 0x201c,
- 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0xa39c, 0x0048, 0x1138,
- 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70, 0x0005,
- 0x3c00, 0x0006, 0x00e6, 0x2071, 0x0200, 0x7808, 0xa084, 0xf000,
- 0xa10d, 0x08e1, 0x20e1, 0x7000, 0x7324, 0x7420, 0x7028, 0x7028,
- 0x7426, 0x7037, 0x0001, 0x810f, 0x712e, 0x702f, 0x0100, 0x7037,
- 0x0008, 0x7326, 0x7422, 0x2001, 0x0138, 0x2202, 0x00ee, 0x000e,
+ 0x7003, 0x0003, 0x7007, 0x0000, 0x0018, 0x080c, 0x18ee, 0x08d0,
+ 0x0156, 0x20a9, 0x0009, 0x2009, 0x8de4, 0x2104, 0xac06, 0x1108,
+ 0x200a, 0xa188, 0x0003, 0x1f04, 0x17d5, 0x015e, 0x005e, 0x002e,
+ 0x2001, 0x015d, 0x201c, 0x831a, 0x2302, 0x2001, 0x0160, 0x2502,
+ 0x2001, 0x0138, 0x2202, 0x005e, 0x004e, 0x003e, 0x002e, 0x00ee,
+ 0x00fe, 0x0005, 0x700c, 0x7110, 0xa106, 0x0904, 0x1841, 0x2104,
+ 0x7006, 0x2060, 0x8108, 0x211c, 0x8108, 0x2124, 0x8108, 0xa182,
+ 0x8dff, 0x0210, 0x2009, 0x8de4, 0x7112, 0x700c, 0xa106, 0x1120,
+ 0x2001, 0x0138, 0x2003, 0x0008, 0x8cff, 0x0538, 0x6010, 0x2068,
+ 0x2d58, 0x6828, 0xa406, 0x1520, 0x682c, 0xa306, 0x1508, 0x684c,
+ 0xd0f4, 0x11d8, 0x6850, 0xd0f4, 0x1130, 0x7803, 0x0004, 0x6810,
+ 0x781a, 0x6814, 0x781e, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830,
+ 0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009, 0x0011, 0x00a9, 0x0118,
+ 0x2009, 0x0001, 0x0089, 0x2d58, 0x0005, 0x080c, 0x1b10, 0x0ce0,
+ 0x601c, 0xa086, 0x0008, 0x1108, 0x08d0, 0x080c, 0x1e96, 0x1da8,
+ 0x08b0, 0x7003, 0x0000, 0x0005, 0x8aff, 0x0904, 0x18c8, 0xa03e,
+ 0x2730, 0x6850, 0xd0fc, 0x11b8, 0xd0f4, 0x1538, 0x00d6, 0x2805,
+ 0xac68, 0x2900, 0x0002, 0x18b2, 0x187c, 0x187c, 0x18b2, 0x18b2,
+ 0x18ab, 0x18b2, 0x187c, 0x18b2, 0x1881, 0x1881, 0x18b2, 0x18b2,
+ 0x18b2, 0x18a3, 0x1881, 0x7803, 0x0004, 0xc0fc, 0x6852, 0x6b6c,
+ 0x6a70, 0x6d1c, 0x6c20, 0x00d6, 0xd99c, 0x0904, 0x18b5, 0x2805,
+ 0xac68, 0x6f08, 0x6e0c, 0x0804, 0x18b5, 0xc0f4, 0x6852, 0x6b6c,
+ 0x6a70, 0x00d6, 0x0804, 0x18bc, 0x6b08, 0x6a0c, 0x6d00, 0x6c04,
+ 0x04a0, 0x7b0c, 0xd3bc, 0x01c0, 0x7004, 0x00e6, 0x2070, 0x701c,
+ 0x00ee, 0xa086, 0x0008, 0x1180, 0x7b08, 0xa39c, 0x0fff, 0x2d20,
+ 0x7a1c, 0x82ff, 0x1120, 0x7818, 0xa302, 0x0208, 0x7b18, 0xa016,
+ 0x7a1e, 0x7b1a, 0x2468, 0x0010, 0x6b10, 0x6a14, 0x6d00, 0x6c04,
+ 0x6f08, 0x6e0c, 0x0090, 0x00de, 0x00d6, 0x6834, 0xa084, 0x00ff,
+ 0xa086, 0x001e, 0x1138, 0x00de, 0x080c, 0x1e38, 0x1904, 0x1844,
+ 0xa00e, 0x00b0, 0x00de, 0x080c, 0x1410, 0x7b22, 0x7a26, 0x7d32,
+ 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x00de,
+ 0x6828, 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x080c, 0x1e38,
+ 0x0005, 0x080c, 0x1410, 0x7803, 0x0004, 0x7004, 0x2060, 0x00d6,
+ 0x6010, 0x2068, 0x7003, 0x0000, 0x080c, 0x1b30, 0x080c, 0x7b8f,
+ 0x0170, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916,
+ 0x682b, 0xffff, 0x682f, 0xffff, 0x6850, 0xc0bd, 0x6852, 0x00de,
+ 0x080c, 0x795f, 0x0804, 0x1a87, 0x080c, 0x1410, 0x0126, 0x2091,
+ 0x2200, 0x0006, 0x0016, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803,
+ 0x0002, 0xa184, 0x0700, 0x1978, 0xa184, 0x0003, 0xa086, 0x0003,
+ 0x0d58, 0x7000, 0x0002, 0x190b, 0x190d, 0x19e8, 0x1a62, 0x1a76,
+ 0x190b, 0x190b, 0x190b, 0x080c, 0x1410, 0x8001, 0x7002, 0xa184,
+ 0x0880, 0x1190, 0xd19c, 0x1904, 0x198b, 0x8aff, 0x0904, 0x198b,
+ 0x2009, 0x0001, 0x080c, 0x1844, 0x0904, 0x1a87, 0x2009, 0x0001,
+ 0x080c, 0x1844, 0x0804, 0x1a87, 0x7803, 0x0004, 0x7003, 0x0000,
+ 0xd1bc, 0x1904, 0x1975, 0x0026, 0x0036, 0x7c20, 0x7d24, 0x7e30,
+ 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, 0x2001, 0x0201, 0x2004,
+ 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803, 0x0009, 0x7003,
+ 0x0004, 0x0010, 0x080c, 0x1a8b, 0x6b28, 0x6a2c, 0x2400, 0x686e,
+ 0xa31a, 0x2500, 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x003e, 0x002e,
+ 0x6e1e, 0x6f22, 0x080c, 0x1e4e, 0x2a00, 0x6826, 0x2c00, 0x681a,
+ 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852, 0x6808, 0x8001, 0x680a,
+ 0x1148, 0x684c, 0xd0e4, 0x0130, 0x7004, 0x2060, 0x2009, 0x0048,
+ 0x080c, 0x6d3f, 0x7000, 0xa086, 0x0004, 0x0904, 0x1a87, 0x7003,
+ 0x0000, 0x080c, 0x17f2, 0x0804, 0x1a87, 0x0056, 0x7d0c, 0xd5bc,
+ 0x1110, 0x080c, 0x8a1c, 0x005e, 0x080c, 0x1b30, 0x682b, 0xffff,
+ 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x791a, 0x6980,
+ 0x791e, 0x0804, 0x1a87, 0x7818, 0x6812, 0x7a1c, 0x6a16, 0xd19c,
+ 0x0118, 0xa205, 0x1904, 0x1924, 0x684c, 0xc0f5, 0x684e, 0x7814,
+ 0xa005, 0x1180, 0x7003, 0x0000, 0x6808, 0x8001, 0x680a, 0x1130,
+ 0x7004, 0x2060, 0x2009, 0x0048, 0x080c, 0x6d3f, 0x080c, 0x17f2,
+ 0x0804, 0x1a87, 0x7818, 0x6812, 0x781c, 0x6816, 0x7814, 0x7908,
+ 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214, 0x8214, 0xa10a,
+ 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b, 0x810b, 0x080c,
+ 0x1b7d, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803, 0x0001, 0x7804,
+ 0xd0fc, 0x0de8, 0x7803, 0x0002, 0x7803, 0x0004, 0x780f, 0x00f6,
+ 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048, 0x080c, 0x6d3f,
+ 0x080c, 0x1ba2, 0x0958, 0x7908, 0xd1ec, 0x1118, 0x2009, 0x0009,
+ 0x0010, 0x2009, 0x0019, 0x7902, 0x7003, 0x0003, 0x0804, 0x1a87,
+ 0x8001, 0x7002, 0xd194, 0x0178, 0x7804, 0xd0fc, 0x1904, 0x18f6,
+ 0xd09c, 0x11a8, 0x8aff, 0x0904, 0x1a87, 0x2009, 0x0001, 0x080c,
+ 0x1844, 0x0804, 0x1a87, 0xa184, 0x0888, 0x1148, 0x8aff, 0x0904,
+ 0x1a87, 0x2009, 0x0001, 0x080c, 0x1844, 0x0804, 0x1a87, 0x7803,
+ 0x0004, 0x7003, 0x0000, 0xd1bc, 0x1904, 0x1a4f, 0x0026, 0x0036,
+ 0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816,
+ 0x2001, 0x0201, 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128,
+ 0x7803, 0x0009, 0x7003, 0x0004, 0x0020, 0x0016, 0x080c, 0x1a8b,
+ 0x001e, 0x6b28, 0x6a2c, 0x080c, 0x1e4e, 0x00d6, 0x2805, 0xac68,
+ 0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0020,
+ 0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0xd194, 0x0904, 0x1946,
+ 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6808, 0x8001,
+ 0x680a, 0x6b2a, 0x6a2e, 0x003e, 0x002e, 0x0804, 0x19a6, 0x0056,
+ 0x7d0c, 0x080c, 0x8a1c, 0x005e, 0x080c, 0x1b30, 0x682b, 0xffff,
+ 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x791a, 0x6980,
+ 0x791e, 0x0428, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d,
+ 0x0150, 0x6808, 0x8001, 0x680a, 0x1130, 0x7004, 0x2060, 0x2009,
+ 0x0048, 0x080c, 0x6d3f, 0x080c, 0x17f2, 0x0088, 0x7803, 0x0004,
+ 0x7003, 0x0000, 0x7004, 0x2060, 0x6010, 0xa005, 0x0da0, 0x2068,
+ 0x6808, 0x8000, 0x680a, 0x6c28, 0x6b2c, 0x080c, 0x180c, 0x001e,
+ 0x000e, 0x012e, 0x0005, 0x700c, 0x7110, 0xa106, 0x0904, 0x1b04,
+ 0x7004, 0x0016, 0x210c, 0xa106, 0x001e, 0x0904, 0x1b04, 0x00d6,
+ 0x00c6, 0x216c, 0x2d00, 0xa005, 0x0904, 0x1b02, 0x6810, 0x2068,
+ 0x6850, 0xd0fc, 0x0558, 0x8108, 0x2104, 0x6b2c, 0xa306, 0x1904,
+ 0x1b02, 0x8108, 0x2104, 0x6a28, 0xa206, 0x1904, 0x1b02, 0x6850,
+ 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822, 0x6870, 0x7826, 0x681c,
+ 0x7832, 0x6820, 0x7836, 0x6818, 0x2060, 0x6034, 0xd09c, 0x0150,
+ 0x6830, 0x2005, 0x00d6, 0xac68, 0x6808, 0x783a, 0x680c, 0x783e,
+ 0x00de, 0x0490, 0xa006, 0x783a, 0x783e, 0x0470, 0x8108, 0x2104,
+ 0xa005, 0x1580, 0x8108, 0x2104, 0xa005, 0x1560, 0x6850, 0xc0f5,
+ 0x6852, 0x6830, 0x2005, 0x6918, 0xa160, 0x6834, 0xd09c, 0x1170,
+ 0x6008, 0x7822, 0x686e, 0x600c, 0x7826, 0x6872, 0x6000, 0x7832,
+ 0x6004, 0x7836, 0xa006, 0x783a, 0x783e, 0x0070, 0x6010, 0x7822,
+ 0x686e, 0x6014, 0x7826, 0x6872, 0x6000, 0x7832, 0x6004, 0x7836,
+ 0x6008, 0x783a, 0x600c, 0x783e, 0x6810, 0x781a, 0x6814, 0x781e,
+ 0x7803, 0x0011, 0x00ce, 0x00de, 0x0005, 0x2011, 0x0201, 0x2009,
+ 0x003c, 0x2204, 0xa005, 0x1118, 0x8109, 0x1dd8, 0x0005, 0x0005,
+ 0x0ca1, 0x01e0, 0x7908, 0xd1ec, 0x1160, 0x080c, 0x1ba2, 0x0148,
+ 0x7803, 0x0009, 0x7904, 0xd1fc, 0x0de8, 0x7803, 0x0006, 0x0c29,
+ 0x0168, 0x780c, 0xd0a4, 0x1150, 0x7007, 0x0000, 0x080c, 0x1ba2,
+ 0x0130, 0x7803, 0x0019, 0x7003, 0x0003, 0x0008, 0x0009, 0x0005,
+ 0x00c6, 0x0461, 0x20e1, 0x9028, 0x700c, 0x7110, 0xa106, 0x01c8,
+ 0x2104, 0xa005, 0x0130, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001,
+ 0x600a, 0xa188, 0x0003, 0xa182, 0x8dff, 0x0210, 0x2009, 0x8de4,
+ 0x7112, 0x700c, 0xa106, 0x1d40, 0x2001, 0x0138, 0x2003, 0x0008,
+ 0x0c18, 0x2001, 0x015d, 0x200c, 0x810a, 0x2102, 0x2001, 0x0160,
+ 0x2502, 0x2001, 0x0138, 0x2202, 0x00ce, 0x0005, 0x2001, 0x0138,
+ 0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000,
+ 0x2021, 0xb015, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001,
+ 0x0109, 0x201c, 0xa39c, 0x0048, 0x1138, 0x2001, 0x0111, 0x201c,
+ 0x83ff, 0x1110, 0x8421, 0x1d70, 0x0005, 0x3c00, 0x0006, 0x00e6,
+ 0x2071, 0x0200, 0x7808, 0xa084, 0xf000, 0xa10d, 0x08b9, 0x20e1,
+ 0x7000, 0x7324, 0x7420, 0x7028, 0x7028, 0x7426, 0x7037, 0x0001,
+ 0x810f, 0x712e, 0x702f, 0x0100, 0x7037, 0x0008, 0x7326, 0x7422,
+ 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x00ee, 0x000e,
0x20e0, 0x0005, 0x3c00, 0x0006, 0x7908, 0xa18c, 0x0fff, 0xa182,
0x0009, 0x0218, 0xa085, 0x0001, 0x0088, 0x2001, 0x020a, 0x81ff,
0x0130, 0x20e1, 0x6000, 0x200c, 0x200c, 0x200c, 0x200c, 0x20e1,
0x7000, 0x200c, 0x200c, 0x7003, 0x0000, 0xa006, 0x000e, 0x20e0,
- 0x0005, 0x00e6, 0x2071, 0x953b, 0x7003, 0x0000, 0x00ee, 0x0005,
- 0x00d6, 0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc, 0x1904, 0x1d0d,
- 0x6934, 0xa184, 0x0007, 0x0002, 0x1c9c, 0x1cf8, 0x1c9c, 0x1c9e,
- 0x1c9c, 0x1cdf, 0x1cbe, 0x1cad, 0x080c, 0x13fe, 0x2100, 0xa084,
- 0x00ff, 0xa086, 0x0013, 0x0904, 0x1cf8, 0x2100, 0xa084, 0x00ff,
- 0xa086, 0x001b, 0x0904, 0x1cf8, 0x0c78, 0x684c, 0xd0b4, 0x0904,
- 0x1e15, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c,
- 0x680a, 0x6880, 0x680e, 0x6958, 0x0804, 0x1d00, 0x6834, 0xa084,
- 0x00ff, 0xa086, 0x001e, 0x19c0, 0x684c, 0xd0b4, 0x0904, 0x1e15,
- 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a,
- 0x6880, 0x680e, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084,
- 0x000f, 0xa080, 0x1f59, 0x2005, 0x6832, 0x6958, 0x0450, 0xa18c,
- 0x00ff, 0xa186, 0x0015, 0x1548, 0x684c, 0xd0b4, 0x0904, 0x1e15,
- 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
- 0x1f59, 0x2005, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0088,
- 0x684c, 0xd0b4, 0x0904, 0x191d, 0x6958, 0xa006, 0x682e, 0x682a,
- 0x2d00, 0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x1f59, 0x2005,
- 0x6832, 0x6926, 0x684c, 0xc0dd, 0x684e, 0x00de, 0x0005, 0x00f6,
- 0x2079, 0x0020, 0x7804, 0xd0fc, 0x190c, 0x1e3b, 0x00e6, 0x00d6,
- 0x2071, 0x953b, 0x7000, 0xa005, 0x1904, 0x1d81, 0x00c6, 0x7206,
- 0xa280, 0x0004, 0x205c, 0x7004, 0x2068, 0x7803, 0x0004, 0x6818,
- 0x00d6, 0x2068, 0x686c, 0x7812, 0x6890, 0x00f6, 0x20e1, 0x9040,
- 0x2079, 0x0200, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x00fe,
- 0x00de, 0x2b68, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040,
- 0x6034, 0xa0cc, 0x000f, 0x6908, 0xa184, 0x0007, 0x0128, 0x0016,
- 0x2009, 0x0008, 0xa102, 0x001e, 0xa108, 0x791a, 0x7116, 0x701e,
- 0x680c, 0xa081, 0x0000, 0x781e, 0x701a, 0xa006, 0x700e, 0x7012,
- 0x7004, 0x692c, 0x6814, 0xa106, 0x1120, 0x6928, 0x6810, 0xa106,
- 0x0158, 0x0036, 0x0046, 0x6b14, 0x6c10, 0x080c, 0x1fa7, 0x004e,
- 0x003e, 0x0110, 0x00ce, 0x00a8, 0x8aff, 0x1120, 0x00ce, 0xa085,
- 0x0001, 0x0078, 0x0126, 0x2091, 0x8000, 0x2079, 0x0020, 0x2009,
- 0x0001, 0x0059, 0x0118, 0x2009, 0x0001, 0x0039, 0x012e, 0x00ce,
- 0xa006, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x0076, 0x0066, 0x0056,
- 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1e0e, 0x700c, 0x7214,
- 0xa23a, 0x7010, 0x7218, 0xa203, 0x0a04, 0x1e0d, 0xa705, 0x0904,
- 0x1e0d, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x11a8, 0x00d6, 0x2805,
- 0xac68, 0x2900, 0x0002, 0x1ddc, 0x1dc1, 0x1dc1, 0x1ddc, 0x1ddc,
- 0x1dd5, 0x1ddc, 0x1dc1, 0x1ddc, 0x1dc6, 0x1dc6, 0x1ddc, 0x1ddc,
- 0x1ddc, 0x1dcd, 0x1dc6, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c,
- 0x6c20, 0xd99c, 0x05c8, 0x00d6, 0x2805, 0xac68, 0x6f08, 0x6e0c,
- 0x0490, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x0468, 0x6b10, 0x6a14,
- 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0430, 0x00de, 0x00d6, 0x6834,
- 0xa084, 0x00ff, 0xa086, 0x001e, 0x1138, 0x00de, 0x080c, 0x1f1b,
- 0x1904, 0x1d8b, 0xa00e, 0x0490, 0x2d10, 0x00de, 0x00d6, 0x6834,
- 0xa084, 0x00ff, 0xa086, 0x0013, 0x2268, 0x09d8, 0x2d10, 0x00de,
- 0x00d6, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001b, 0x2268, 0x09b0,
- 0x00de, 0x080c, 0x13fe, 0x00de, 0x7b22, 0x7a26, 0x7d32, 0x7c36,
- 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300,
- 0x682a, 0x682c, 0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010,
- 0xa201, 0x7012, 0x080c, 0x1f1b, 0x0008, 0xa006, 0x002e, 0x003e,
- 0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x13fe, 0x2001,
- 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
- 0x0000, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068, 0x080c, 0x82ee,
- 0x0118, 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x80f6, 0x20e1,
- 0x9040, 0x080c, 0x7366, 0x2011, 0x0000, 0x080c, 0x7199, 0x080c,
- 0x651c, 0x0804, 0x1ef0, 0x0126, 0x2091, 0x2400, 0x0006, 0x0016,
- 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x2079, 0x0020, 0x2071, 0x953b,
- 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700,
- 0x1930, 0x7000, 0x0002, 0x1ef0, 0x1e57, 0x1ec3, 0x1eee, 0x8001,
- 0x7002, 0xd19c, 0x1170, 0x8aff, 0x0540, 0x2009, 0x0001, 0x080c,
- 0x1d85, 0x0904, 0x1ef0, 0x2009, 0x0001, 0x080c, 0x1d85, 0x0804,
- 0x1ef0, 0x7803, 0x0004, 0xd194, 0x0148, 0x6850, 0xc0fc, 0x6852,
- 0x8aff, 0x1148, 0x684c, 0xc0f5, 0x684e, 0x0028, 0x080c, 0x1f31,
- 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800,
- 0x6832, 0x7003, 0x0000, 0x0804, 0x1ef0, 0x711c, 0x81ff, 0x0190,
- 0x7918, 0x7922, 0x7827, 0x0000, 0x7803, 0x0001, 0x7000, 0x8000,
- 0x7002, 0x700c, 0xa100, 0x700e, 0x7010, 0xa081, 0x0000, 0x7012,
- 0x0804, 0x1ef0, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006,
- 0x2079, 0x0100, 0x7a14, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816,
- 0x7820, 0xd0bc, 0x1de8, 0x79c8, 0x000e, 0xa102, 0x001e, 0x0006,
- 0x0016, 0x79c4, 0x000e, 0xa102, 0x78c6, 0x000e, 0x78ca, 0xa284,
- 0x0004, 0xa085, 0x0012, 0x7816, 0x002e, 0x00fe, 0x7803, 0x0008,
- 0x7003, 0x0000, 0x0468, 0x8001, 0x7002, 0xd194, 0x0168, 0x7804,
- 0xd0fc, 0x1904, 0x1e4b, 0xd19c, 0x11f8, 0x8aff, 0x0508, 0x2009,
- 0x0001, 0x080c, 0x1d85, 0x00e0, 0x0026, 0x0036, 0x6b28, 0x6a2c,
- 0x080c, 0x1f31, 0x00d6, 0x2805, 0xac68, 0x6034, 0xd09c, 0x1128,
- 0x6808, 0xa31a, 0x680c, 0xa213, 0x0020, 0x6810, 0xa31a, 0x6814,
- 0xa213, 0x00de, 0x0804, 0x1e76, 0x0804, 0x1e76, 0x080c, 0x13fe,
- 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x001e, 0x000e, 0x012e, 0x0005,
- 0x00f6, 0x00e6, 0x2071, 0x953b, 0x7000, 0xa086, 0x0000, 0x01c0,
- 0x2079, 0x0020, 0x20e1, 0x9040, 0x7804, 0xd0fc, 0x0dd8, 0x080c,
- 0x1e3b, 0x7000, 0xa086, 0x0000, 0x1da8, 0x7803, 0x0004, 0x7804,
- 0xd0ac, 0x1de8, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000,
- 0x00ee, 0x00fe, 0x0005, 0x8840, 0x2805, 0xa005, 0x1170, 0x6004,
- 0xa005, 0x0168, 0x681a, 0x2060, 0x6034, 0xa084, 0x000f, 0xa080,
- 0x1f59, 0x2045, 0x88ff, 0x090c, 0x13fe, 0x8a51, 0x0005, 0x2050,
- 0x0005, 0x8a50, 0x8841, 0x2805, 0xa005, 0x1190, 0x2c00, 0xad06,
- 0x0120, 0x6000, 0xa005, 0x1108, 0x2d00, 0x2060, 0x681a, 0x6034,
- 0xa084, 0x000f, 0xa080, 0x1f69, 0x2045, 0x88ff, 0x090c, 0x13fe,
- 0x0005, 0x0000, 0x0011, 0x0015, 0x0019, 0x001d, 0x0021, 0x0025,
- 0x0029, 0x0000, 0x000f, 0x0015, 0x001b, 0x0021, 0x0027, 0x0000,
- 0x0000, 0x0000, 0x1f4e, 0x1f4a, 0x1f4e, 0x1f4e, 0x1f58, 0x0000,
- 0x1f4e, 0x0000, 0x1f55, 0x1f52, 0x1f55, 0x1f55, 0x0000, 0x1f58,
- 0x1f55, 0x0000, 0x1f50, 0x1f50, 0x0000, 0x1f50, 0x1f58, 0x0000,
- 0x1f50, 0x0000, 0x1f56, 0x1f56, 0x0000, 0x1f56, 0x0000, 0x1f58,
- 0x1f56, 0x0136, 0x0146, 0x0156, 0x2099, 0x9359, 0x20a1, 0x0018,
- 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126, 0x2091, 0x8000,
- 0x7803, 0x0041, 0x7007, 0x0005, 0x7000, 0xc094, 0x7002, 0x700b,
- 0x9354, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005, 0x2099, 0x0014,
- 0x7803, 0x0040, 0x2001, 0x9359, 0x2004, 0x2010, 0x080c, 0x59a7,
- 0x080c, 0x5949, 0x7007, 0x0000, 0x080c, 0x14ec, 0x0005, 0x00a6,
- 0x0096, 0x0086, 0x6858, 0xa055, 0x0904, 0x2036, 0x2d60, 0x6034,
- 0xa0cc, 0x000f, 0xa9c0, 0x1f59, 0xa986, 0x0007, 0x0130, 0xa986,
- 0x000e, 0x0118, 0xa986, 0x000f, 0x1120, 0x605c, 0xa422, 0x6060,
- 0xa31a, 0x2805, 0xa045, 0x1140, 0x0310, 0x0804, 0x2036, 0x6004,
- 0xa065, 0x0904, 0x2036, 0x0c18, 0x2805, 0xa005, 0x01a8, 0xac68,
- 0xd99c, 0x1128, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0020, 0x6810,
- 0xa422, 0x6814, 0xa31b, 0x0620, 0x2300, 0xa405, 0x0150, 0x8a51,
- 0x0904, 0x2036, 0x8840, 0x0c40, 0x6004, 0xa065, 0x0904, 0x2036,
- 0x0830, 0x8a51, 0x0904, 0x2036, 0x8840, 0x2805, 0xa005, 0x1158,
- 0x6004, 0xa065, 0x0904, 0x2036, 0x6034, 0xa0cc, 0x000f, 0xa9c0,
- 0x1f59, 0x2805, 0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0458,
- 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x00d6, 0x2b68, 0x6c6e,
- 0x6b72, 0x00de, 0xd99c, 0x1168, 0x6908, 0x2400, 0xa122, 0x690c,
- 0x2300, 0xa11b, 0x0a0c, 0x13fe, 0x6800, 0xa420, 0x6804, 0xa319,
- 0x0060, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, 0x0a0c,
- 0x13fe, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, 0x6b22,
- 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832, 0x2a00,
- 0x6826, 0x000e, 0x000e, 0x000e, 0xa006, 0x0028, 0x008e, 0x009e,
- 0x00ae, 0xa085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004, 0xa084,
- 0x0007, 0x0002, 0x204a, 0x204b, 0x204e, 0x2051, 0x2056, 0x2059,
- 0x205e, 0x2063, 0x0005, 0x080c, 0x1e3b, 0x0005, 0x080c, 0x1942,
- 0x0005, 0x080c, 0x1942, 0x080c, 0x1e3b, 0x0005, 0x080c, 0x159c,
- 0x0005, 0x080c, 0x1e3b, 0x080c, 0x159c, 0x0005, 0x080c, 0x1942,
- 0x080c, 0x159c, 0x0005, 0x080c, 0x1942, 0x080c, 0x1e3b, 0x080c,
- 0x159c, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071,
- 0x9780, 0x2069, 0x9200, 0x2009, 0x0004, 0x7912, 0x7817, 0x0004,
- 0x080c, 0x23e6, 0x781b, 0x0002, 0x783b, 0x001f, 0x20e1, 0x8700,
- 0x012e, 0x0005, 0x0126, 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c,
- 0x210b, 0xa084, 0x0007, 0x0002, 0x20a6, 0x2094, 0x2097, 0x209a,
- 0x209f, 0x20a1, 0x20a3, 0x20a5, 0x080c, 0x5338, 0x0078, 0x080c,
- 0x536c, 0x0060, 0x080c, 0x5338, 0x080c, 0x536c, 0x0038, 0x0041,
- 0x0028, 0x0031, 0x0018, 0x0021, 0x0008, 0x0011, 0x012e, 0x0005,
- 0x0006, 0x0016, 0x0026, 0x7930, 0xa184, 0x0003, 0x0118, 0x20e1,
- 0x9040, 0x00b8, 0xa184, 0x0030, 0x0150, 0x6a00, 0xa286, 0x0003,
- 0x1108, 0x0010, 0x080c, 0x4105, 0x20e1, 0x9010, 0x0050, 0xa184,
- 0x00c0, 0x0110, 0x080c, 0x13fe, 0xa184, 0x0300, 0x0110, 0x20e1,
- 0x9020, 0x7932, 0x002e, 0x001e, 0x000e, 0x0005, 0x0016, 0x00e6,
- 0x00f6, 0x2071, 0x9200, 0x7128, 0x2001, 0x94ca, 0x2102, 0x2001,
- 0x94d2, 0x2102, 0xa182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400,
- 0xa182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0xa182, 0x02c1,
- 0x1218, 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349, 0x1218, 0x2009,
- 0x0005, 0x0070, 0xa182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040,
- 0xa182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002,
- 0x2079, 0x0200, 0x7912, 0x7817, 0x0004, 0x080c, 0x23e6, 0x00fe,
- 0x00ee, 0x001e, 0x0005, 0x7938, 0x080c, 0x13fe, 0x0126, 0x2091,
- 0x2400, 0x2061, 0x0100, 0x2071, 0x9200, 0x6024, 0x6026, 0x080c,
- 0x2425, 0x6050, 0xa084, 0xfe7f, 0x6052, 0x2009, 0x00ef, 0x6132,
- 0x6136, 0x080c, 0x2435, 0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0008,
- 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000,
- 0x6007, 0x0c9f, 0x600f, 0x03ff, 0x602b, 0x002f, 0x012e, 0x0005,
- 0x2001, 0x9230, 0x2003, 0x0000, 0x2001, 0x922f, 0x2003, 0x0001,
- 0x0005, 0x0126, 0x2091, 0x2400, 0x0006, 0x0016, 0x0026, 0x6124,
- 0x0066, 0x2031, 0x9232, 0x2634, 0xa6b4, 0x0028, 0x006e, 0x11c0,
- 0x6020, 0xd0bc, 0x01a8, 0xd1bc, 0x0198, 0x783c, 0xa005, 0x0180,
- 0x00e6, 0x0006, 0x2070, 0x701c, 0xa086, 0x0009, 0x000e, 0x00ee,
- 0x1138, 0x00e6, 0x783c, 0x2070, 0x7008, 0xd0fc, 0x00ee, 0x1130,
- 0xa184, 0x1c2c, 0x1118, 0xa184, 0x0007, 0x002a, 0xa195, 0x0004,
- 0xa284, 0x0007, 0x0002, 0x2195, 0x217b, 0x217e, 0x2181, 0x2186,
- 0x2188, 0x218c, 0x2190, 0x080c, 0x5ee3, 0x00b8, 0x080c, 0x5fbe,
- 0x00a0, 0x080c, 0x5fbe, 0x080c, 0x5ee3, 0x0078, 0x0099, 0x0068,
- 0x080c, 0x5ee3, 0x0079, 0x0048, 0x080c, 0x5fbe, 0x0059, 0x0028,
- 0x080c, 0x5fbe, 0x080c, 0x5ee3, 0x0029, 0x002e, 0x001e, 0x000e,
- 0x012e, 0x0005, 0xd19c, 0x1904, 0x238f, 0x080c, 0x4dc5, 0x01a0,
- 0x080c, 0x4deb, 0x15c0, 0x6024, 0xa084, 0x1800, 0x1108, 0x0498,
- 0x2001, 0x94d7, 0x2003, 0xaaaa, 0x2001, 0x94d8, 0x2003, 0x0001,
- 0x080c, 0x4d10, 0x0804, 0x238f, 0xd1ac, 0x1528, 0x6024, 0xd0dc,
- 0x1130, 0xd0e4, 0x1148, 0xd0d4, 0x1180, 0x0804, 0x238f, 0x2001,
- 0x94d8, 0x2003, 0x0000, 0x0068, 0xa085, 0x0001, 0x080c, 0x4e05,
- 0x2001, 0x94d8, 0x2003, 0x0002, 0x0020, 0x2001, 0x94d8, 0x2003,
- 0x0003, 0x0016, 0x2001, 0x9200, 0x2003, 0x0001, 0x080c, 0x4d10,
- 0x001e, 0x0804, 0x238f, 0x6220, 0xd1bc, 0x0568, 0xd2bc, 0x0558,
- 0x783c, 0xa005, 0x0540, 0x00e6, 0x2070, 0x7008, 0xd0fc, 0x00ee,
- 0x0510, 0x6028, 0xc0bc, 0x602a, 0x0026, 0x0036, 0x6288, 0x638c,
- 0x608b, 0xbc91, 0x608f, 0xffff, 0x6043, 0x0001, 0xe000, 0xe000,
- 0x6027, 0x0080, 0x6017, 0x0000, 0x6043, 0x0000, 0x628a, 0x638e,
- 0x003e, 0x002e, 0x0016, 0x2001, 0x9295, 0x200c, 0xc184, 0x2102,
- 0x001e, 0x0804, 0x23b6, 0xd1ac, 0x0904, 0x22d7, 0x080c, 0x4dc5,
- 0x1550, 0x6027, 0x0020, 0x0006, 0x0026, 0x0036, 0x2001, 0x94d8,
- 0x080c, 0x4de1, 0x11d8, 0x2011, 0x9225, 0x2204, 0xa005, 0x1140,
- 0x8000, 0x2012, 0x2011, 0x8036, 0x2019, 0x0001, 0x080c, 0x3698,
- 0x2001, 0x94d8, 0x2003, 0x0001, 0x2001, 0x9200, 0x2003, 0x0001,
- 0x080c, 0x4d10, 0x003e, 0x002e, 0x000e, 0x0005, 0x003e, 0x002e,
- 0x000e, 0x080c, 0x4ca5, 0x0016, 0x0046, 0x00c6, 0x644c, 0xa486,
- 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a, 0x6043, 0x0090, 0x6043,
- 0x0010, 0x74c6, 0xa48c, 0xff00, 0xa196, 0xff00, 0x01e8, 0x7050,
- 0xa084, 0x00ff, 0x810f, 0xa116, 0x01b8, 0x7130, 0xd18c, 0x11a0,
- 0x2011, 0x9252, 0x2214, 0xd2ec, 0x0118, 0xc18d, 0x7132, 0x0060,
- 0x6240, 0xa294, 0x0010, 0x0904, 0x22ad, 0x6248, 0xa294, 0xff00,
- 0xa296, 0xff00, 0x1904, 0x22ad, 0x70bc, 0xa005, 0x1138, 0x0036,
- 0x73c4, 0x2011, 0x8013, 0x080c, 0x3698, 0x003e, 0x7130, 0xc185,
- 0x7132, 0x2011, 0x9252, 0x220c, 0xd1a4, 0x01d0, 0x0016, 0x2009,
- 0x0001, 0x2011, 0x0100, 0x080c, 0x585b, 0x2019, 0x000e, 0x080c,
- 0x9071, 0xa484, 0x00ff, 0xa080, 0x2719, 0x200d, 0xa18c, 0xff00,
- 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x080c, 0x90d7, 0x001e,
- 0xd1ac, 0x1128, 0x2019, 0x0004, 0x080c, 0x264b, 0x0070, 0x0156,
- 0x20a9, 0x007f, 0x2009, 0x0000, 0x080c, 0x4434, 0x1110, 0x080c,
- 0x41e0, 0x8108, 0x1f04, 0x22a4, 0x015e, 0x00ce, 0x004e, 0x2011,
- 0x0003, 0x080c, 0x718f, 0x2011, 0x0002, 0x080c, 0x7199, 0x080c,
- 0x708d, 0x080c, 0x57a1, 0x0036, 0x2019, 0x0000, 0x080c, 0x7110,
- 0x003e, 0x60e3, 0x0000, 0x001e, 0x2001, 0x9200, 0x2014, 0xa296,
- 0x0004, 0x1128, 0xd19c, 0x1118, 0x6228, 0xc29d, 0x622a, 0x2003,
- 0x0001, 0x2001, 0x9222, 0x2003, 0x0000, 0x6027, 0x0020, 0xd194,
- 0x0904, 0x238f, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x2340, 0x080c,
- 0x57a1, 0x080c, 0x6f1e, 0x6027, 0x0004, 0x00f6, 0x2019, 0x94ee,
- 0x2304, 0xa07d, 0x0570, 0x7804, 0xa086, 0x0032, 0x1550, 0x00d6,
- 0x00c6, 0x00e6, 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, 0x608e,
- 0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0,
- 0x6043, 0x0000, 0x6803, 0x1000, 0x6803, 0x0000, 0x618e, 0x628a,
- 0x080c, 0x6389, 0x080c, 0x6462, 0x7810, 0x2070, 0x7037, 0x0103,
- 0x2f60, 0x080c, 0x74f2, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e,
- 0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000,
- 0x0120, 0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061,
- 0x94e5, 0x6028, 0xa09a, 0x0002, 0x1238, 0x8000, 0x602a, 0x00ce,
- 0x080c, 0x6f11, 0x0804, 0x238e, 0x2019, 0x94ee, 0x2304, 0xa065,
- 0x0120, 0x2009, 0x0027, 0x080c, 0x7518, 0x00ce, 0x0804, 0x238e,
- 0xd2bc, 0x0904, 0x238e, 0x080c, 0x57ae, 0x6017, 0x0010, 0x6027,
- 0x0004, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0120,
- 0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061, 0x94e5,
- 0x6044, 0xa09a, 0x0002, 0x12e0, 0x8000, 0x6046, 0x603c, 0x00ce,
- 0xa005, 0x0560, 0x2009, 0x07d0, 0x080c, 0x57a6, 0xa080, 0x0007,
- 0x2004, 0xa086, 0x0006, 0x1118, 0x6017, 0x0012, 0x00f8, 0xa080,
- 0x0007, 0x2004, 0xa086, 0x0009, 0x0db8, 0x6017, 0x0016, 0x00b0,
- 0x0036, 0x2019, 0x0001, 0x080c, 0x7110, 0x003e, 0x2019, 0x94f4,
- 0x2304, 0xa065, 0x0150, 0x2009, 0x004f, 0x601c, 0xa086, 0x0009,
- 0x1110, 0x2009, 0x0105, 0x080c, 0x7518, 0x00ce, 0x001e, 0xd19c,
- 0x0528, 0x0016, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c,
- 0x718f, 0x2011, 0x0002, 0x080c, 0x7199, 0x080c, 0x708d, 0x080c,
- 0x57a1, 0x0036, 0x2019, 0x0000, 0x080c, 0x7110, 0x003e, 0x60e3,
- 0x0000, 0x080c, 0x918b, 0x080c, 0x91a6, 0x2001, 0x9200, 0x2003,
- 0x0004, 0x6027, 0x0008, 0x080c, 0x123f, 0x001e, 0xa18c, 0xffd0,
- 0x6126, 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0126,
- 0x2091, 0x8000, 0x2071, 0x9200, 0x71bc, 0x70be, 0xa116, 0x01b8,
- 0x81ff, 0x0128, 0x2011, 0x8011, 0x080c, 0x3698, 0x0080, 0x2011,
- 0x8012, 0x080c, 0x3698, 0x0036, 0x00c6, 0x080c, 0x2480, 0x2061,
- 0x0100, 0x2019, 0x0028, 0x080c, 0x264b, 0x00ce, 0x003e, 0x012e,
- 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x00c6, 0x00f6,
- 0x0006, 0x0026, 0x2061, 0x0100, 0xa190, 0x23f9, 0x2205, 0x60f2,
- 0x2011, 0x2406, 0x2205, 0x60ee, 0x002e, 0x000e, 0x00fe, 0x00ce,
- 0x0005, 0x0840, 0x0840, 0x0840, 0x0580, 0x0420, 0x0348, 0x02c0,
- 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x0140, 0x00f8,
- 0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff, 0x2130, 0xa094,
- 0xff00, 0x1110, 0x81ff, 0x0118, 0x080c, 0x550c, 0x0038, 0xa080,
- 0x2719, 0x200d, 0xa18c, 0xff00, 0x810f, 0xa006, 0x0005, 0xa080,
- 0x2719, 0x200d, 0xa18c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140,
- 0x2001, 0x9214, 0x2003, 0x00ef, 0x20a9, 0x0010, 0xa006, 0x6852,
- 0x6856, 0x1f04, 0x2430, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026,
- 0x2069, 0x0140, 0x2001, 0x9214, 0x2102, 0x8114, 0x8214, 0x8214,
- 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0xa006, 0x82ff, 0x1128,
- 0xa184, 0x000f, 0xa080, 0x91ac, 0x2005, 0x6856, 0x8211, 0x1f04,
- 0x2445, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x9200,
- 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005,
- 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980,
- 0xa116, 0x0180, 0xa112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001,
- 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x2475,
- 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005,
- 0x2001, 0x9252, 0x2004, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0xa006,
- 0x0046, 0x2020, 0x2009, 0x002e, 0x080c, 0x90d7, 0x004e, 0x0005,
- 0x24b0, 0x24b4, 0x24b8, 0x24be, 0x24c4, 0x24ca, 0x24d0, 0x24d8,
- 0x24df, 0x24e4, 0x24e9, 0x24f0, 0x24f7, 0x24fe, 0x2505, 0x250e,
- 0x2517, 0x2517, 0x2517, 0x2517, 0x2517, 0x2517, 0x2517, 0x2517,
- 0x2517, 0x2517, 0x2517, 0x2517, 0x2517, 0x2517, 0x2517, 0x2517,
- 0x0106, 0x0006, 0x0804, 0x2519, 0x0106, 0x0006, 0x0804, 0x2519,
- 0x0106, 0x0006, 0x080c, 0x2141, 0x0804, 0x2519, 0x0106, 0x0006,
- 0x080c, 0x2141, 0x0804, 0x2519, 0x0106, 0x0006, 0x080c, 0x203c,
- 0x0804, 0x2519, 0x0106, 0x0006, 0x080c, 0x203c, 0x0804, 0x2519,
- 0x0106, 0x0006, 0x080c, 0x2141, 0x080c, 0x203c, 0x0804, 0x2519,
- 0x0106, 0x0006, 0x080c, 0x2141, 0x080c, 0x203c, 0x04d0, 0x0106,
- 0x0006, 0x080c, 0x2082, 0x04a8, 0x0106, 0x0006, 0x080c, 0x2082,
- 0x0480, 0x0106, 0x0006, 0x080c, 0x2141, 0x080c, 0x2082, 0x0448,
- 0x0106, 0x0006, 0x080c, 0x2141, 0x080c, 0x2082, 0x0410, 0x0106,
- 0x0006, 0x080c, 0x203c, 0x080c, 0x2082, 0x00d8, 0x0106, 0x0006,
- 0x080c, 0x203c, 0x080c, 0x2082, 0x00a0, 0x0106, 0x0006, 0x080c,
- 0x2141, 0x080c, 0x203c, 0x080c, 0x2082, 0x0058, 0x0106, 0x0006,
- 0x080c, 0x2141, 0x080c, 0x203c, 0x080c, 0x2082, 0x0010, 0xe000,
- 0x0cf0, 0x000e, 0x010e, 0x000d, 0x00c6, 0x0026, 0x2041, 0x007e,
- 0x70c8, 0xd09c, 0x0110, 0x2041, 0x007f, 0xd094, 0x2001, 0x9214,
- 0x203c, 0x15d8, 0x7284, 0x82ff, 0x05c0, 0x0036, 0x7398, 0xa38e,
- 0xffff, 0x1110, 0x2019, 0x0001, 0x8314, 0xa2e0, 0x98c0, 0x2c04,
- 0xa38c, 0x0001, 0x0120, 0xa084, 0xff00, 0x8007, 0x0010, 0xa084,
- 0x00ff, 0xa70e, 0x01c8, 0xa08e, 0x00ff, 0x01d0, 0x2009, 0x0000,
- 0x080c, 0x240b, 0x080c, 0x4400, 0x1188, 0x6004, 0xa084, 0x00ff,
- 0xa086, 0x0006, 0x1120, 0x080c, 0x25b1, 0x0140, 0x0028, 0x080c,
- 0x26ad, 0x080c, 0x25d7, 0x0110, 0x8318, 0x08b0, 0x739a, 0x0010,
- 0x709b, 0xffff, 0x003e, 0x0804, 0x25ae, 0xa780, 0x2719, 0x203d,
- 0xa7bc, 0xff00, 0x873f, 0x7098, 0xa096, 0xffff, 0x0128, 0xa812,
- 0x12c8, 0x709b, 0xffff, 0x04b8, 0x2009, 0x0000, 0x70c8, 0xd09c,
- 0x0120, 0xd094, 0x0110, 0x2009, 0x007e, 0x2001, 0x94d7, 0x2004,
- 0xa005, 0x0120, 0x2009, 0x007e, 0x2041, 0x007f, 0x2100, 0xa802,
- 0x20a8, 0x0020, 0x2008, 0x2810, 0xa202, 0x20a8, 0x2700, 0x0156,
- 0x0016, 0xa106, 0x0180, 0x080c, 0x4400, 0x11a8, 0x6004, 0xa084,
- 0x00ff, 0xa086, 0x0006, 0x1118, 0x00a1, 0x0168, 0x0020, 0x080c,
- 0x26ad, 0x04a9, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x258e,
- 0x709b, 0xffff, 0x0018, 0x001e, 0x015e, 0x719a, 0x002e, 0x00ce,
- 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x080c, 0x749c,
- 0x01c8, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c,
- 0x43d1, 0x2001, 0x0000, 0x080c, 0x43e3, 0x0126, 0x2091, 0x8000,
- 0x7094, 0x8000, 0x7096, 0x012e, 0x2009, 0x0004, 0x080c, 0x7518,
- 0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016,
- 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x080c, 0x749c, 0x01c8, 0x2d00,
- 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x43d1, 0x2001,
- 0x0002, 0x080c, 0x43e3, 0x0126, 0x2091, 0x8000, 0x7094, 0x8000,
- 0x7096, 0x012e, 0x2009, 0x0002, 0x080c, 0x7518, 0xa085, 0x0001,
- 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x0026, 0x2009,
- 0x0080, 0x080c, 0x4400, 0x1120, 0x0031, 0x0110, 0x70cf, 0xffff,
- 0x002e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68,
- 0x080c, 0x749c, 0x01c8, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001,
- 0x0000, 0x080c, 0x43d1, 0x2001, 0x0002, 0x080c, 0x43e3, 0x0126,
- 0x2091, 0x8000, 0x70d0, 0x8000, 0x70d2, 0x012e, 0x2009, 0x0002,
- 0x080c, 0x7518, 0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e,
- 0x0005, 0x00c6, 0x00d6, 0x2009, 0x007f, 0x080c, 0x4400, 0x1180,
- 0x2c68, 0x080c, 0x749c, 0x0160, 0x2d00, 0x601a, 0x6312, 0x601f,
- 0x0001, 0x620a, 0x2009, 0x0022, 0x080c, 0x7518, 0xa085, 0x0001,
- 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026,
- 0x080c, 0x6133, 0x080c, 0x60dc, 0x080c, 0x7a8c, 0x20a9, 0x007f,
- 0x2009, 0x0000, 0x0016, 0x080c, 0x4434, 0x1120, 0x080c, 0x460d,
- 0x080c, 0x41e0, 0x001e, 0x8108, 0x1f04, 0x265a, 0x002e, 0x003e,
- 0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0026,
- 0x0016, 0x6218, 0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c,
- 0x6127, 0x0086, 0x2041, 0x0000, 0x080c, 0x606d, 0x2c08, 0x080c,
- 0x8ee4, 0x008e, 0x001e, 0x2e60, 0x080c, 0x460d, 0x6210, 0x6314,
- 0x080c, 0x41e0, 0x6212, 0x6316, 0x001e, 0x002e, 0x003e, 0x00ce,
- 0x00ee, 0x0005, 0x00e6, 0x0006, 0x6018, 0xa080, 0x0028, 0x2004,
- 0xa086, 0x0080, 0x0150, 0x2071, 0x9200, 0x7094, 0xa005, 0x0110,
- 0x8001, 0x7096, 0x000e, 0x00ee, 0x0005, 0x2071, 0x9200, 0x70d0,
- 0xa005, 0x0dc0, 0x8001, 0x70d2, 0x0ca8, 0x6000, 0xc08c, 0x6002,
- 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x0156,
- 0x2178, 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0098, 0x2001, 0x9252,
+ 0x0005, 0x00e6, 0x2071, 0x8dff, 0x7003, 0x0000, 0x00ee, 0x0005,
+ 0x00d6, 0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc, 0x1904, 0x1c3e,
+ 0x6934, 0xa184, 0x0007, 0x0002, 0x1bdc, 0x1c29, 0x1bdc, 0x1bdc,
+ 0x1bdc, 0x1c10, 0x1bef, 0x1bde, 0x080c, 0x1410, 0x684c, 0xd0b4,
+ 0x0904, 0x1d32, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812,
+ 0x687c, 0x680a, 0x6880, 0x680e, 0x6958, 0x0804, 0x1c31, 0x6834,
+ 0xa084, 0x00ff, 0xa086, 0x001e, 0x1d38, 0x684c, 0xd0b4, 0x0904,
+ 0x1d32, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c,
+ 0x680a, 0x6880, 0x680e, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004,
+ 0xa084, 0x000f, 0xa080, 0x1e76, 0x2005, 0x6832, 0x6958, 0x0450,
+ 0xa18c, 0x00ff, 0xa186, 0x0015, 0x1548, 0x684c, 0xd0b4, 0x0904,
+ 0x1d32, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f,
+ 0xa080, 0x1e76, 0x2005, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a,
+ 0x0088, 0x684c, 0xd0b4, 0x0904, 0x18c9, 0x6958, 0xa006, 0x682e,
+ 0x682a, 0x2d00, 0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x1e76,
+ 0x2005, 0x6832, 0x6926, 0x684c, 0xc0dd, 0x684e, 0x00de, 0x0005,
+ 0x00f6, 0x2079, 0x0020, 0x7804, 0xd0fc, 0x190c, 0x1d58, 0x00e6,
+ 0x00d6, 0x2071, 0x8dff, 0x7000, 0xa005, 0x1904, 0x1cb2, 0x00c6,
+ 0x7206, 0xa280, 0x0004, 0x205c, 0x7004, 0x2068, 0x7803, 0x0004,
+ 0x6818, 0x00d6, 0x2068, 0x686c, 0x7812, 0x6890, 0x00f6, 0x20e1,
+ 0x9040, 0x2079, 0x0200, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6,
+ 0x00fe, 0x00de, 0x2b68, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830,
+ 0x2040, 0x6034, 0xa0cc, 0x000f, 0x6908, 0xa184, 0x0007, 0x0128,
+ 0x0016, 0x2009, 0x0008, 0xa102, 0x001e, 0xa108, 0x791a, 0x7116,
+ 0x701e, 0x680c, 0xa081, 0x0000, 0x781e, 0x701a, 0xa006, 0x700e,
+ 0x7012, 0x7004, 0x692c, 0x6814, 0xa106, 0x1120, 0x6928, 0x6810,
+ 0xa106, 0x0158, 0x0036, 0x0046, 0x6b14, 0x6c10, 0x080c, 0x1e96,
+ 0x004e, 0x003e, 0x0110, 0x00ce, 0x00a8, 0x8aff, 0x1120, 0x00ce,
+ 0xa085, 0x0001, 0x0078, 0x0126, 0x2091, 0x8000, 0x2079, 0x0020,
+ 0x2009, 0x0001, 0x0059, 0x0118, 0x2009, 0x0001, 0x0039, 0x012e,
+ 0x00ce, 0xa006, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x0076, 0x0066,
+ 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1d2b, 0x700c,
+ 0x7214, 0xa23a, 0x7010, 0x7218, 0xa203, 0x0a04, 0x1d2a, 0xa705,
+ 0x0904, 0x1d2a, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x11a8, 0x00d6,
+ 0x2805, 0xac68, 0x2900, 0x0002, 0x1d0d, 0x1cf2, 0x1cf2, 0x1d0d,
+ 0x1d0d, 0x1d06, 0x1d0d, 0x1cf2, 0x1d0d, 0x1cf7, 0x1cf7, 0x1d0d,
+ 0x1d0d, 0x1d0d, 0x1cfe, 0x1cf7, 0xc0fc, 0x6852, 0x6b6c, 0x6a70,
+ 0x6d1c, 0x6c20, 0xd99c, 0x0528, 0x00d6, 0x2805, 0xac68, 0x6f08,
+ 0x6e0c, 0x00f0, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x00c8, 0x6b10,
+ 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0090, 0x00de, 0x00d6,
+ 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x1138, 0x00de, 0x080c,
+ 0x1e38, 0x1904, 0x1cbc, 0xa00e, 0x00f0, 0x00de, 0x080c, 0x1410,
+ 0x00de, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902,
+ 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, 0x682a, 0x682c, 0xa201,
+ 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, 0xa201, 0x7012, 0x080c,
+ 0x1e38, 0x0008, 0xa006, 0x002e, 0x003e, 0x004e, 0x005e, 0x006e,
+ 0x007e, 0x0005, 0x080c, 0x1410, 0x2001, 0x0105, 0x2003, 0x0010,
+ 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060,
+ 0x00d6, 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0118, 0x6850, 0xc0bd,
+ 0x6852, 0x00de, 0x080c, 0x795f, 0x20e1, 0x9040, 0x080c, 0x6b33,
+ 0x2011, 0x0000, 0x080c, 0x6966, 0x080c, 0x5dc2, 0x0804, 0x1e0d,
+ 0x0126, 0x2091, 0x2400, 0x0006, 0x0016, 0x00f6, 0x00e6, 0x00d6,
+ 0x00c6, 0x2079, 0x0020, 0x2071, 0x8dff, 0x2b68, 0x6818, 0x2060,
+ 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x1930, 0x7000, 0x0002,
+ 0x1e0d, 0x1d74, 0x1de0, 0x1e0b, 0x8001, 0x7002, 0xd19c, 0x1170,
+ 0x8aff, 0x0540, 0x2009, 0x0001, 0x080c, 0x1cb6, 0x0904, 0x1e0d,
+ 0x2009, 0x0001, 0x080c, 0x1cb6, 0x0804, 0x1e0d, 0x7803, 0x0004,
+ 0xd194, 0x0148, 0x6850, 0xc0fc, 0x6852, 0x8aff, 0x1148, 0x684c,
+ 0xc0f5, 0x684e, 0x0028, 0x080c, 0x1e4e, 0x6850, 0xc0fd, 0x6852,
+ 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000,
+ 0x0804, 0x1e0d, 0x711c, 0x81ff, 0x0190, 0x7918, 0x7922, 0x7827,
+ 0x0000, 0x7803, 0x0001, 0x7000, 0x8000, 0x7002, 0x700c, 0xa100,
+ 0x700e, 0x7010, 0xa081, 0x0000, 0x7012, 0x0804, 0x1e0d, 0x00f6,
+ 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14,
+ 0xa284, 0x0184, 0xa085, 0x0012, 0x7816, 0x7820, 0xd0bc, 0x1de8,
+ 0x79c8, 0x000e, 0xa102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e,
+ 0xa102, 0x78c6, 0x000e, 0x78ca, 0xa284, 0x0184, 0xa085, 0x0012,
+ 0x7816, 0x002e, 0x00fe, 0x7803, 0x0008, 0x7003, 0x0000, 0x0468,
+ 0x8001, 0x7002, 0xd194, 0x0168, 0x7804, 0xd0fc, 0x1904, 0x1d68,
+ 0xd19c, 0x11f8, 0x8aff, 0x0508, 0x2009, 0x0001, 0x080c, 0x1cb6,
+ 0x00e0, 0x0026, 0x0036, 0x6b28, 0x6a2c, 0x080c, 0x1e4e, 0x00d6,
+ 0x2805, 0xac68, 0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c,
+ 0xa213, 0x0020, 0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0x0804,
+ 0x1d93, 0x0804, 0x1d93, 0x080c, 0x1410, 0x00ce, 0x00de, 0x00ee,
+ 0x00fe, 0x001e, 0x000e, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071,
+ 0x8dff, 0x7000, 0xa086, 0x0000, 0x01c0, 0x2079, 0x0020, 0x20e1,
+ 0x9040, 0x7804, 0xd0fc, 0x0dd8, 0x080c, 0x1d58, 0x7000, 0xa086,
+ 0x0000, 0x1da8, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x1de8, 0x20e1,
+ 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005,
+ 0x8840, 0x2805, 0xa005, 0x1170, 0x6004, 0xa005, 0x0168, 0x681a,
+ 0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x1e76, 0x2045, 0x88ff,
+ 0x090c, 0x1410, 0x8a51, 0x0005, 0x2050, 0x0005, 0x8a50, 0x8841,
+ 0x2805, 0xa005, 0x1190, 0x2c00, 0xad06, 0x0120, 0x6000, 0xa005,
+ 0x1108, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080,
+ 0x1e86, 0x2045, 0x88ff, 0x090c, 0x1410, 0x0005, 0x0000, 0x0011,
+ 0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f,
+ 0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x1e6b,
+ 0x1e67, 0x0000, 0x0000, 0x1e75, 0x0000, 0x1e6b, 0x0000, 0x1e72,
+ 0x1e6f, 0x0000, 0x0000, 0x0000, 0x1e75, 0x1e72, 0x0000, 0x1e6d,
+ 0x1e6d, 0x0000, 0x0000, 0x1e75, 0x0000, 0x1e6d, 0x0000, 0x1e73,
+ 0x1e73, 0x0000, 0x0000, 0x0000, 0x1e75, 0x1e73, 0x00a6, 0x0096,
+ 0x0086, 0x6858, 0xa055, 0x0904, 0x1f25, 0x2d60, 0x6034, 0xa0cc,
+ 0x000f, 0xa9c0, 0x1e76, 0xa986, 0x0007, 0x0130, 0xa986, 0x000e,
+ 0x0118, 0xa986, 0x000f, 0x1120, 0x605c, 0xa422, 0x6060, 0xa31a,
+ 0x2805, 0xa045, 0x1140, 0x0310, 0x0804, 0x1f25, 0x6004, 0xa065,
+ 0x0904, 0x1f25, 0x0c18, 0x2805, 0xa005, 0x01a8, 0xac68, 0xd99c,
+ 0x1128, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0020, 0x6810, 0xa422,
+ 0x6814, 0xa31b, 0x0620, 0x2300, 0xa405, 0x0150, 0x8a51, 0x0904,
+ 0x1f25, 0x8840, 0x0c40, 0x6004, 0xa065, 0x0904, 0x1f25, 0x0830,
+ 0x8a51, 0x0904, 0x1f25, 0x8840, 0x2805, 0xa005, 0x1158, 0x6004,
+ 0xa065, 0x0904, 0x1f25, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x1e76,
+ 0x2805, 0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0458, 0x8422,
+ 0x8420, 0x831a, 0xa399, 0x0000, 0x00d6, 0x2b68, 0x6c6e, 0x6b72,
+ 0x00de, 0xd99c, 0x1168, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300,
+ 0xa11b, 0x0a0c, 0x1410, 0x6800, 0xa420, 0x6804, 0xa319, 0x0060,
+ 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, 0x0a0c, 0x1410,
+ 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, 0x6b22, 0x6850,
+ 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832, 0x2a00, 0x6826,
+ 0x000e, 0x000e, 0x000e, 0xa006, 0x0028, 0x008e, 0x009e, 0x00ae,
+ 0xa085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004, 0xa084, 0x0007,
+ 0x0002, 0x1f39, 0x1f3a, 0x1f3d, 0x1f40, 0x1f45, 0x1f48, 0x1f4d,
+ 0x1f52, 0x0005, 0x080c, 0x1d58, 0x0005, 0x080c, 0x18ee, 0x0005,
+ 0x080c, 0x18ee, 0x080c, 0x1d58, 0x0005, 0x080c, 0x15a7, 0x0005,
+ 0x080c, 0x1d58, 0x080c, 0x15a7, 0x0005, 0x080c, 0x18ee, 0x080c,
+ 0x15a7, 0x0005, 0x080c, 0x18ee, 0x080c, 0x1d58, 0x080c, 0x15a7,
+ 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x9080,
+ 0x2069, 0x8b00, 0x2009, 0x0004, 0x7912, 0x7817, 0x0004, 0x080c,
+ 0x22c4, 0x781b, 0x0002, 0x783b, 0x001f, 0x20e1, 0x8700, 0x012e,
+ 0x0005, 0x0126, 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x1ffa,
+ 0xa084, 0x0007, 0x0002, 0x1f95, 0x1f83, 0x1f86, 0x1f89, 0x1f8e,
+ 0x1f90, 0x1f92, 0x1f94, 0x080c, 0x521b, 0x0078, 0x080c, 0x5242,
+ 0x0060, 0x080c, 0x521b, 0x080c, 0x5242, 0x0038, 0x0041, 0x0028,
+ 0x0031, 0x0018, 0x0021, 0x0008, 0x0011, 0x012e, 0x0005, 0x0006,
+ 0x0016, 0x0026, 0x7930, 0xa184, 0x0003, 0x0118, 0x20e1, 0x9040,
+ 0x00b8, 0xa184, 0x0030, 0x0150, 0x6a00, 0xa286, 0x0003, 0x1108,
+ 0x0010, 0x080c, 0x403d, 0x20e1, 0x9010, 0x0050, 0xa184, 0x00c0,
+ 0x0110, 0x080c, 0x1410, 0xa184, 0x0300, 0x0110, 0x20e1, 0x9020,
+ 0x7932, 0x002e, 0x001e, 0x000e, 0x0005, 0x0016, 0x00e6, 0x00f6,
+ 0x2071, 0x8b00, 0x7128, 0x2001, 0x8d8f, 0x2102, 0x2001, 0x8d97,
+ 0x2102, 0xa182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, 0xa182,
+ 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0xa182, 0x02c1, 0x1218,
+ 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349, 0x1218, 0x2009, 0x0005,
+ 0x0070, 0xa182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, 0xa182,
+ 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, 0x2079,
+ 0x0200, 0x7912, 0x7817, 0x0004, 0x080c, 0x22c4, 0x00fe, 0x00ee,
+ 0x001e, 0x0005, 0x7938, 0x080c, 0x1410, 0x0126, 0x2091, 0x2400,
+ 0x2061, 0x0100, 0x2071, 0x8b00, 0x6024, 0x6026, 0x6053, 0x0030,
+ 0x080c, 0x2303, 0x6050, 0xa084, 0xfe7f, 0x6052, 0x2009, 0x00ef,
+ 0x6132, 0x6136, 0x080c, 0x2313, 0x60e7, 0x0000, 0x61ea, 0x60e3,
+ 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f,
+ 0x0000, 0x6007, 0x0e9f, 0x600f, 0x00ff, 0x602b, 0x002f, 0x012e,
+ 0x0005, 0x2001, 0x8b30, 0x2003, 0x0000, 0x2001, 0x8b2f, 0x2003,
+ 0x0001, 0x0005, 0x0126, 0x2091, 0x2400, 0x0006, 0x0016, 0x0026,
+ 0x6124, 0xa184, 0x1e2c, 0x1118, 0xa184, 0x0007, 0x002a, 0xa195,
+ 0x0004, 0xa284, 0x0007, 0x0002, 0x2066, 0x204c, 0x204f, 0x2052,
+ 0x2057, 0x2059, 0x205d, 0x2061, 0x080c, 0x578e, 0x00b8, 0x080c,
+ 0x5869, 0x00a0, 0x080c, 0x5869, 0x080c, 0x578e, 0x0078, 0x0099,
+ 0x0068, 0x080c, 0x578e, 0x0079, 0x0048, 0x080c, 0x5869, 0x0059,
+ 0x0028, 0x080c, 0x5869, 0x080c, 0x578e, 0x0029, 0x002e, 0x001e,
+ 0x000e, 0x012e, 0x0005, 0xd19c, 0x1904, 0x226d, 0x080c, 0x4c42,
+ 0x0560, 0x7000, 0xa086, 0x0003, 0x0198, 0x6024, 0xa084, 0x1800,
+ 0x0178, 0x080c, 0x4c68, 0x0118, 0x080c, 0x4c54, 0x1148, 0x6027,
+ 0x0020, 0x6043, 0x0000, 0x2001, 0x8d9c, 0x2003, 0xaaaa, 0x0458,
+ 0x080c, 0x4c68, 0x1904, 0x20cf, 0x6024, 0xa084, 0x1800, 0x1108,
+ 0x04f0, 0x2001, 0x8d9c, 0x2003, 0xaaaa, 0x2001, 0x8d9d, 0x2003,
+ 0x0001, 0x080c, 0x4b8b, 0x0804, 0x226d, 0xd1ac, 0x1580, 0x6024,
+ 0xd0dc, 0x1188, 0xd0e4, 0x11a0, 0xd0d4, 0x11d8, 0xd0cc, 0x0148,
+ 0x7088, 0xa086, 0x0027, 0x1128, 0x6028, 0xc0cc, 0x602a, 0x080c,
+ 0x4b52, 0x0804, 0x226d, 0x2001, 0x8d9d, 0x2003, 0x0000, 0x0068,
+ 0xa085, 0x0001, 0x080c, 0x4c82, 0x2001, 0x8d9d, 0x2003, 0x0002,
+ 0x0020, 0x080c, 0x4d10, 0x0804, 0x226d, 0x0016, 0x2001, 0x8b00,
+ 0x2003, 0x0001, 0x080c, 0x4b8b, 0x001e, 0x0804, 0x226d, 0xd1ac,
+ 0x0904, 0x21b5, 0x080c, 0x4c42, 0x1550, 0x6027, 0x0020, 0x0006,
+ 0x0026, 0x0036, 0x2001, 0x8d9d, 0x080c, 0x4c5e, 0x11d8, 0x2011,
+ 0x8b25, 0x2204, 0xa005, 0x1140, 0x8000, 0x2012, 0x2011, 0x8036,
+ 0x2019, 0x0001, 0x080c, 0x3617, 0x2001, 0x8d9d, 0x2003, 0x0001,
+ 0x2001, 0x8b00, 0x2003, 0x0001, 0x080c, 0x4b8b, 0x003e, 0x002e,
+ 0x000e, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x4b06, 0x0016,
+ 0x0046, 0x00c6, 0x644c, 0xa486, 0xf0f0, 0x1138, 0x2061, 0x0100,
+ 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74c6, 0xa48c, 0xff00,
+ 0x7034, 0xd084, 0x0178, 0xa186, 0xf800, 0x1160, 0x7038, 0xd084,
+ 0x1148, 0xc085, 0x703a, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c,
+ 0x3617, 0x003e, 0xa196, 0xff00, 0x01e8, 0x7050, 0xa084, 0x00ff,
+ 0x810f, 0xa116, 0x01b8, 0x7130, 0xd18c, 0x11a0, 0x2011, 0x8b52,
+ 0x2214, 0xd2ec, 0x0118, 0xc18d, 0x7132, 0x0060, 0x6240, 0xa294,
+ 0x0010, 0x0904, 0x218b, 0x6248, 0xa294, 0xff00, 0xa296, 0xff00,
+ 0x1904, 0x218b, 0x7034, 0xd08c, 0x1140, 0x2001, 0x8b0c, 0x200c,
+ 0xd1ac, 0x1904, 0x218b, 0xc1ad, 0x2102, 0x0036, 0x73c4, 0x2011,
+ 0x8013, 0x080c, 0x3617, 0x003e, 0x7130, 0xc185, 0x7132, 0x2011,
+ 0x8b52, 0x220c, 0xd1a4, 0x01d0, 0x0016, 0x2009, 0x0001, 0x2011,
+ 0x0100, 0x080c, 0x5734, 0x2019, 0x000e, 0x080c, 0x891c, 0xa484,
+ 0x00ff, 0xa080, 0x263d, 0x200d, 0xa18c, 0xff00, 0x810f, 0x8127,
+ 0xa006, 0x2009, 0x000e, 0x080c, 0x8982, 0x001e, 0xd1ac, 0x1128,
+ 0x2019, 0x0004, 0x080c, 0x2542, 0x0070, 0x0156, 0x20a9, 0x007f,
+ 0x2009, 0x0000, 0x080c, 0x430a, 0x1110, 0x080c, 0x4118, 0x8108,
+ 0x1f04, 0x2182, 0x015e, 0x00ce, 0x004e, 0x2011, 0x0003, 0x080c,
+ 0x695c, 0x2011, 0x0002, 0x080c, 0x6966, 0x080c, 0x6862, 0x080c,
+ 0x567a, 0x0036, 0x2019, 0x0000, 0x080c, 0x68e5, 0x003e, 0x60e3,
+ 0x0000, 0x001e, 0x2001, 0x8b00, 0x2014, 0xa296, 0x0004, 0x1128,
+ 0xd19c, 0x1118, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001,
+ 0x8b22, 0x2003, 0x0000, 0x6027, 0x0020, 0xd194, 0x0904, 0x226d,
+ 0x0016, 0x6220, 0xd2b4, 0x0904, 0x221e, 0x080c, 0x567a, 0x080c,
+ 0x66f7, 0x6027, 0x0004, 0x00f6, 0x2019, 0x8db3, 0x2304, 0xa07d,
+ 0x0570, 0x7804, 0xa086, 0x0032, 0x1550, 0x00d6, 0x00c6, 0x00e6,
+ 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, 0x608e, 0x7808, 0x608a,
+ 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0, 0x6043, 0x0000,
+ 0x6803, 0x1000, 0x6803, 0x0000, 0x618e, 0x628a, 0x080c, 0x5c37,
+ 0x080c, 0x5d10, 0x7810, 0x2070, 0x7037, 0x0103, 0x2f60, 0x080c,
+ 0x6d18, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x0005, 0x00fe,
+ 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0120, 0x6803,
+ 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061, 0x8daa, 0x6028,
+ 0xa09a, 0x0002, 0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0x66ea,
+ 0x0804, 0x226c, 0x2019, 0x8db3, 0x2304, 0xa065, 0x0120, 0x2009,
+ 0x0027, 0x080c, 0x6d3f, 0x00ce, 0x0804, 0x226c, 0xd2bc, 0x0904,
+ 0x226c, 0x080c, 0x5687, 0x6014, 0xa084, 0x0184, 0xa085, 0x0010,
+ 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084,
+ 0x4000, 0x0120, 0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6,
+ 0x2061, 0x8daa, 0x6044, 0xa09a, 0x0002, 0x12f0, 0x8000, 0x6046,
+ 0x603c, 0x00ce, 0xa005, 0x0540, 0x2009, 0x07d0, 0x080c, 0x567f,
+ 0xa080, 0x0007, 0x2004, 0xa086, 0x0006, 0x1138, 0x6114, 0xa18c,
+ 0x0184, 0xa18d, 0x0012, 0x6116, 0x00b8, 0x6114, 0xa18c, 0x0184,
+ 0xa18d, 0x0016, 0x6116, 0x0080, 0x0036, 0x2019, 0x0001, 0x080c,
+ 0x68e5, 0x003e, 0x2019, 0x8db9, 0x2304, 0xa065, 0x0120, 0x2009,
+ 0x004f, 0x080c, 0x6d3f, 0x00ce, 0x001e, 0xd19c, 0x0528, 0x0016,
+ 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0x695c, 0x2011,
+ 0x0002, 0x080c, 0x6966, 0x080c, 0x6862, 0x080c, 0x567a, 0x0036,
+ 0x2019, 0x0000, 0x080c, 0x68e5, 0x003e, 0x60e3, 0x0000, 0x080c,
+ 0x8a36, 0x080c, 0x8a51, 0x2001, 0x8b00, 0x2003, 0x0004, 0x6027,
+ 0x0008, 0x080c, 0x1251, 0x001e, 0xa18c, 0xffd0, 0x6126, 0x0005,
+ 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000,
+ 0x2071, 0x8b00, 0x71bc, 0x70be, 0xa116, 0x01b8, 0x81ff, 0x0128,
+ 0x2011, 0x8011, 0x080c, 0x3617, 0x0080, 0x2011, 0x8012, 0x080c,
+ 0x3617, 0x0036, 0x00c6, 0x080c, 0x235e, 0x2061, 0x0100, 0x2019,
+ 0x0028, 0x080c, 0x2542, 0x00ce, 0x003e, 0x012e, 0x00fe, 0x00ee,
+ 0x002e, 0x001e, 0x000e, 0x0005, 0x00c6, 0x00f6, 0x0006, 0x0026,
+ 0x2061, 0x0100, 0xa190, 0x22d7, 0x2205, 0x60f2, 0x2011, 0x22e4,
+ 0x2205, 0x60ee, 0x002e, 0x000e, 0x00fe, 0x00ce, 0x0005, 0x0840,
+ 0x0840, 0x0840, 0x0580, 0x0420, 0x0348, 0x02c0, 0x0258, 0x0210,
+ 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x0140, 0x00f8, 0x00d0, 0x00b0,
+ 0x00a0, 0x2028, 0xa18c, 0x00ff, 0x2130, 0xa094, 0xff00, 0x1110,
+ 0x81ff, 0x0118, 0x080c, 0x53f4, 0x0038, 0xa080, 0x263d, 0x200d,
+ 0xa18c, 0xff00, 0x810f, 0xa006, 0x0005, 0xa080, 0x263d, 0x200d,
+ 0xa18c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x8b14,
+ 0x2003, 0x00ef, 0x20a9, 0x0010, 0xa006, 0x6852, 0x6856, 0x1f04,
+ 0x230e, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140,
+ 0x2001, 0x8b14, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9,
+ 0x0010, 0x6853, 0x0000, 0xa006, 0x82ff, 0x1128, 0xa184, 0x000f,
+ 0xa080, 0x8a57, 0x2005, 0x6856, 0x8211, 0x1f04, 0x2323, 0x002e,
+ 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x8b00, 0x6030, 0x0110,
+ 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6,
+ 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0xa116, 0x0180,
+ 0xa112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, 0x0018,
+ 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x2353, 0x680f, 0x0000,
+ 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x2001, 0x8b52,
0x2004, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020,
- 0x2009, 0x002d, 0x080c, 0x90d7, 0x004e, 0x20a9, 0x00ff, 0x2011,
- 0x0000, 0x0026, 0xa288, 0x936e, 0x210c, 0x81ff, 0x0508, 0x8fff,
- 0x0559, 0x2019, 0x0029, 0x080c, 0x6127, 0x0086, 0x2041, 0x0000,
- 0x080c, 0x606d, 0x00c6, 0x0026, 0x2160, 0x6204, 0xa294, 0x00ff,
- 0x2001, 0x0004, 0x8007, 0xa215, 0x6206, 0x002e, 0x00ce, 0x0016,
- 0x2c08, 0x080c, 0x8ee4, 0x001e, 0x008e, 0x2160, 0x080c, 0x460d,
- 0x002e, 0x8210, 0x1f04, 0x26d1, 0x015e, 0x001e, 0x002e, 0x003e,
- 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x2001,
- 0x9252, 0x2004, 0xd0c4, 0x0148, 0xd0a4, 0x0138, 0xa006, 0x2220,
- 0x8427, 0x2009, 0x0029, 0x080c, 0x90d7, 0x001e, 0x002e, 0x004e,
- 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc,
- 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1,
- 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6,
- 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4,
- 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa,
- 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d,
- 0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282,
- 0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074,
- 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a,
- 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559,
- 0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d,
- 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043,
- 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932,
- 0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227,
- 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18,
- 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000,
- 0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000,
- 0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00,
- 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900,
- 0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200,
- 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00,
- 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000,
- 0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600,
- 0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00,
- 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900,
- 0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000,
- 0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000,
- 0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x2009, 0x002e, 0x080c, 0x8982, 0x004e, 0x0005, 0x238e, 0x2392,
+ 0x2396, 0x239c, 0x23a2, 0x23a8, 0x23ae, 0x23b6, 0x23bd, 0x23c2,
+ 0x23c7, 0x23ce, 0x23d5, 0x23dc, 0x23e3, 0x23ec, 0x23f5, 0x23f5,
+ 0x23f5, 0x23f5, 0x23f5, 0x23f5, 0x23f5, 0x23f5, 0x23f5, 0x23f5,
+ 0x23f5, 0x23f5, 0x23f5, 0x23f5, 0x23f5, 0x23f5, 0x0106, 0x0006,
+ 0x0804, 0x23f7, 0x0106, 0x0006, 0x0804, 0x23f7, 0x0106, 0x0006,
+ 0x080c, 0x2032, 0x0804, 0x23f7, 0x0106, 0x0006, 0x080c, 0x2032,
+ 0x0804, 0x23f7, 0x0106, 0x0006, 0x080c, 0x1f2b, 0x0804, 0x23f7,
+ 0x0106, 0x0006, 0x080c, 0x1f2b, 0x0804, 0x23f7, 0x0106, 0x0006,
+ 0x080c, 0x2032, 0x080c, 0x1f2b, 0x0804, 0x23f7, 0x0106, 0x0006,
+ 0x080c, 0x2032, 0x080c, 0x1f2b, 0x04d0, 0x0106, 0x0006, 0x080c,
+ 0x1f71, 0x04a8, 0x0106, 0x0006, 0x080c, 0x1f71, 0x0480, 0x0106,
+ 0x0006, 0x080c, 0x2032, 0x080c, 0x1f71, 0x0448, 0x0106, 0x0006,
+ 0x080c, 0x2032, 0x080c, 0x1f71, 0x0410, 0x0106, 0x0006, 0x080c,
+ 0x1f2b, 0x080c, 0x1f71, 0x00d8, 0x0106, 0x0006, 0x080c, 0x1f2b,
+ 0x080c, 0x1f71, 0x00a0, 0x0106, 0x0006, 0x080c, 0x2032, 0x080c,
+ 0x1f2b, 0x080c, 0x1f71, 0x0058, 0x0106, 0x0006, 0x080c, 0x2032,
+ 0x080c, 0x1f2b, 0x080c, 0x1f71, 0x0010, 0xe000, 0x0cf0, 0x000e,
+ 0x010e, 0x000d, 0x00c6, 0x0026, 0x2041, 0x007e, 0x70c8, 0xd09c,
+ 0x0110, 0x2041, 0x007f, 0xd094, 0x2001, 0x8b14, 0x203c, 0x1904,
+ 0x2454, 0x7284, 0xd284, 0x0904, 0x2454, 0xd28c, 0x1904, 0x2454,
+ 0x0036, 0x7398, 0xa38e, 0xffff, 0x1110, 0x2019, 0x0001, 0x8314,
+ 0xa2e0, 0x91c0, 0x2c04, 0xa38c, 0x0001, 0x0120, 0xa084, 0xff00,
+ 0x8007, 0x0010, 0xa084, 0x00ff, 0xa70e, 0x0528, 0xa08e, 0x00ff,
+ 0x1160, 0x2011, 0x8b52, 0x2214, 0xd2ec, 0x1508, 0x7284, 0xc28d,
+ 0x7286, 0x709b, 0xffff, 0x003e, 0x00f8, 0x2009, 0x0000, 0x080c,
+ 0x22e9, 0x080c, 0x42d6, 0x1188, 0x6004, 0xa084, 0x00ff, 0xa086,
+ 0x0006, 0x1120, 0x080c, 0x24a8, 0x0140, 0x0028, 0x080c, 0x25a4,
+ 0x080c, 0x24ce, 0x0110, 0x8318, 0x0850, 0x739a, 0x0010, 0x709b,
+ 0xffff, 0x003e, 0x0804, 0x24a5, 0xa780, 0x263d, 0x203d, 0xa7bc,
+ 0xff00, 0x873f, 0x7098, 0xa096, 0xffff, 0x0128, 0xa812, 0x12c8,
+ 0x709b, 0xffff, 0x04f8, 0x2009, 0x0000, 0x70c8, 0xd09c, 0x0120,
+ 0xd094, 0x0110, 0x2009, 0x007e, 0x2001, 0x8d9c, 0x2004, 0xa005,
+ 0x0120, 0x2009, 0x007e, 0x2041, 0x007f, 0x2100, 0xa802, 0x20a8,
+ 0x0020, 0x2008, 0x2810, 0xa202, 0x20a8, 0x2700, 0x0156, 0x0016,
+ 0xa106, 0x01c0, 0x080c, 0x42d6, 0x11e8, 0x6004, 0xa084, 0x00ff,
+ 0xa086, 0x0006, 0x1120, 0x080c, 0x2610, 0x0160, 0x0020, 0x7284,
+ 0xd28c, 0x0120, 0x0038, 0x00a1, 0x0168, 0x0020, 0x080c, 0x25a4,
+ 0x04a9, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x247d, 0x709b,
+ 0xffff, 0x0018, 0x001e, 0x015e, 0x719a, 0x002e, 0x00ce, 0x0005,
+ 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x080c, 0x6cc2, 0x01c8,
+ 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x42a7,
+ 0x2001, 0x0000, 0x080c, 0x42b9, 0x0126, 0x2091, 0x8000, 0x7094,
+ 0x8000, 0x7096, 0x012e, 0x2009, 0x0004, 0x080c, 0x6d3f, 0xa085,
+ 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076,
+ 0x00d6, 0x00c6, 0x2c68, 0x080c, 0x6cc2, 0x01c8, 0x2d00, 0x601a,
+ 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x42a7, 0x2001, 0x0002,
+ 0x080c, 0x42b9, 0x0126, 0x2091, 0x8000, 0x7094, 0x8000, 0x7096,
+ 0x012e, 0x2009, 0x0002, 0x080c, 0x6d3f, 0xa085, 0x0001, 0x00ce,
+ 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x0026, 0x2009, 0x0080,
+ 0x080c, 0x42d6, 0x1120, 0x0031, 0x0110, 0x70cf, 0xffff, 0x002e,
+ 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x080c,
+ 0x6cc2, 0x01c8, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001, 0x0000,
+ 0x080c, 0x42a7, 0x2001, 0x0002, 0x080c, 0x42b9, 0x0126, 0x2091,
+ 0x8000, 0x70d0, 0x8000, 0x70d2, 0x012e, 0x2009, 0x0002, 0x080c,
+ 0x6d3f, 0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005,
+ 0x00c6, 0x00d6, 0x2009, 0x007f, 0x080c, 0x42d6, 0x1180, 0x2c68,
+ 0x080c, 0x6cc2, 0x0160, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001,
+ 0x620a, 0x2009, 0x0022, 0x080c, 0x6d3f, 0xa085, 0x0001, 0x00de,
+ 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x080c,
+ 0x59e1, 0x080c, 0x598b, 0x080c, 0x72cc, 0x20a9, 0x007f, 0x2009,
+ 0x0000, 0x0016, 0x080c, 0x430a, 0x1120, 0x080c, 0x44e6, 0x080c,
+ 0x4118, 0x001e, 0x8108, 0x1f04, 0x2551, 0x002e, 0x003e, 0x006e,
+ 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016,
+ 0x6218, 0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x59d5,
+ 0x0086, 0x2041, 0x0000, 0x080c, 0x5911, 0x2c08, 0x080c, 0x878f,
+ 0x008e, 0x001e, 0x2e60, 0x080c, 0x44e6, 0x6210, 0x6314, 0x080c,
+ 0x4118, 0x6212, 0x6316, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee,
+ 0x0005, 0x00e6, 0x0006, 0x6018, 0xa080, 0x0028, 0x2004, 0xa086,
+ 0x0080, 0x0150, 0x2071, 0x8b00, 0x7094, 0xa005, 0x0110, 0x8001,
+ 0x7096, 0x000e, 0x00ee, 0x0005, 0x2071, 0x8b00, 0x70d0, 0xa005,
+ 0x0dc0, 0x8001, 0x70d2, 0x0ca8, 0x6000, 0xc08c, 0x6002, 0x0005,
+ 0x00f6, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178,
+ 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0098, 0x2001, 0x8b52, 0x2004,
+ 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, 0x2009,
+ 0x002d, 0x080c, 0x8982, 0x004e, 0x20a9, 0x00ff, 0x2011, 0x0000,
+ 0x0026, 0xa288, 0x8c34, 0x210c, 0x81ff, 0x0508, 0x8fff, 0x0559,
+ 0x2019, 0x0029, 0x080c, 0x59d5, 0x0086, 0x2041, 0x0000, 0x080c,
+ 0x5911, 0x00c6, 0x0026, 0x2160, 0x6204, 0xa294, 0x00ff, 0x2001,
+ 0x0004, 0x8007, 0xa215, 0x6206, 0x002e, 0x00ce, 0x0016, 0x2c08,
+ 0x080c, 0x878f, 0x001e, 0x008e, 0x2160, 0x080c, 0x44e6, 0x002e,
+ 0x8210, 0x1f04, 0x25c8, 0x015e, 0x001e, 0x002e, 0x003e, 0x00ce,
+ 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x2001, 0x8b52,
+ 0x2004, 0xd0c4, 0x0148, 0xd0a4, 0x0138, 0xa006, 0x2220, 0x8427,
+ 0x2009, 0x0029, 0x080c, 0x8982, 0x001e, 0x002e, 0x004e, 0x0005,
+ 0x0016, 0x0026, 0x0036, 0x00c6, 0x7284, 0x82ff, 0x01f8, 0xa290,
+ 0x8b52, 0x2214, 0xd2ac, 0x11d0, 0x2100, 0x080c, 0x22fd, 0x81ff,
+ 0x01b8, 0x2019, 0x0001, 0x8314, 0xa2e0, 0x91c0, 0x2c04, 0xd384,
+ 0x0120, 0xa084, 0xff00, 0x8007, 0x0010, 0xa084, 0x00ff, 0xa116,
+ 0x0138, 0xa096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0xa085, 0x0001,
+ 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x7eef, 0x7de8, 0x7ce4,
+ 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5,
+ 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb,
+ 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba,
+ 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae,
+ 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5,
+ 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, 0x6690,
+ 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, 0x607a,
+ 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, 0x806e,
+ 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965,
+ 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, 0x5353,
+ 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49,
+ 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, 0x8036,
+ 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, 0x462c,
+ 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, 0x401f,
+ 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08,
+ 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, 0x3600,
+ 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, 0x8000,
+ 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000,
+ 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, 0x2600,
+ 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, 0x2000,
+ 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00,
+ 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, 0x1300,
+ 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00,
+ 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, 0x0700,
+ 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, 0x0300,
+ 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000,
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
- 0x8000, 0x2071, 0x9296, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016,
- 0x703a, 0x703e, 0x7033, 0x92a6, 0x7037, 0x92a6, 0x7007, 0x0001,
- 0x2061, 0x92e6, 0x6003, 0x0002, 0x0005, 0x1004, 0x283f, 0x0e04,
- 0x283f, 0x2071, 0x9296, 0x2b78, 0x7818, 0xd084, 0x1140, 0x2a60,
- 0x7820, 0xa08e, 0x0069, 0x1904, 0x2924, 0x0804, 0x28bd, 0x0005,
- 0x2071, 0x9296, 0x7004, 0x0002, 0x2848, 0x2849, 0x2852, 0x2863,
- 0x0005, 0x1004, 0x2851, 0x0e04, 0x2851, 0x2b78, 0x7818, 0xd084,
- 0x01e8, 0x0005, 0x2b78, 0x2061, 0x92e6, 0x6008, 0xa08e, 0x0100,
- 0x0128, 0xa086, 0x0200, 0x0904, 0x291e, 0x0005, 0x7014, 0x2068,
- 0x2a60, 0x7018, 0x0807, 0x7010, 0x2068, 0x6834, 0xa086, 0x0103,
- 0x0108, 0x0005, 0x2a60, 0x2b78, 0x7018, 0x0807, 0x2a60, 0x7820,
- 0xa08a, 0x0040, 0x1210, 0x61bc, 0x0042, 0x2100, 0xa08a, 0x003f,
- 0x1a04, 0x291b, 0x61bc, 0x0804, 0x28bd, 0x28ff, 0x292a, 0x2932,
- 0x2936, 0x293e, 0x2944, 0x2948, 0x2951, 0x2954, 0x295e, 0x2961,
- 0x291b, 0x291b, 0x291b, 0x2964, 0x291b, 0x2973, 0x298a, 0x29a1,
- 0x2a18, 0x2a1d, 0x2a46, 0x2a97, 0x2aa8, 0x2ac6, 0x2af2, 0x2afc,
- 0x2b09, 0x2b1c, 0x2b3c, 0x2b45, 0x2b7b, 0x2b81, 0x291b, 0x2ba4,
- 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x2ba8, 0x2bae, 0x291b,
- 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x2bb6,
- 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x2bc3, 0x2bc9, 0x291b,
- 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x0002, 0x2bdb, 0x2c2e,
- 0x2c88, 0x2c98, 0x291b, 0x2cb2, 0x309c, 0x291b, 0x291b, 0x291b,
- 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x295e, 0x2961,
- 0x291b, 0x291b, 0x309e, 0x291b, 0x291b, 0x291b, 0x291b, 0x291b,
- 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x291b, 0x30a2, 0x31e7,
- 0x31fb, 0x3215, 0x3276, 0x32c7, 0x32d2, 0x3309, 0x3318, 0x3327,
- 0x3336, 0x335e, 0x33a8, 0x340a, 0x3417, 0x3501, 0x35f6, 0x361f,
- 0x3716, 0x3732, 0x373e, 0x3777, 0x381e, 0x3878, 0x38ff, 0x3908,
- 0x390b, 0x3920, 0x393b, 0x39ab, 0x3a5b, 0x713c, 0x0000, 0x2021,
- 0x4000, 0x080c, 0x3675, 0x0126, 0x2091, 0x8000, 0x0e04, 0x290b,
- 0x7818, 0xd084, 0x0110, 0x012e, 0x0cb0, 0x7c22, 0x7926, 0x7a2a,
- 0x7b2e, 0x781b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091,
- 0x5000, 0x012e, 0x0005, 0x2021, 0x4001, 0x0c18, 0x2021, 0x4002,
- 0x0c00, 0x2021, 0x4003, 0x08e8, 0x2021, 0x4005, 0x08d0, 0x2021,
- 0x4006, 0x08b8, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930,
- 0x0804, 0x3682, 0x7823, 0x0004, 0x7824, 0x0807, 0xa02e, 0x2520,
- 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0804, 0x3685, 0x7924, 0x7828,
- 0x2114, 0x200a, 0x0804, 0x28ff, 0x7924, 0x2114, 0x0804, 0x28ff,
- 0x2099, 0x0009, 0x20a1, 0x0009, 0x20a9, 0x0007, 0x53a3, 0x0804,
- 0x28ff, 0x7824, 0x2060, 0x0090, 0x2009, 0x0002, 0x2011, 0x0000,
- 0x2019, 0x0010, 0x783b, 0x0027, 0x0804, 0x28ff, 0x7d38, 0x7c3c,
- 0x0858, 0x7d38, 0x7c3c, 0x08a0, 0x2061, 0x1000, 0xe10c, 0xa006,
- 0x2c15, 0xa200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0xa005, 0x0904,
- 0x28ff, 0x0804, 0x2921, 0x2069, 0x9251, 0x7824, 0x7930, 0xa11a,
- 0x1a04, 0x2927, 0x8019, 0x0904, 0x2927, 0x684a, 0x6942, 0x782c,
- 0x6852, 0x7828, 0x6856, 0xa006, 0x685a, 0x685e, 0x080c, 0x4e5d,
- 0x0804, 0x28ff, 0x2069, 0x9251, 0x7824, 0x7934, 0xa11a, 0x1a04,
- 0x2927, 0x8019, 0x0904, 0x2927, 0x684e, 0x6946, 0x782c, 0x6862,
- 0x7828, 0x6866, 0xa006, 0x686a, 0x686e, 0x080c, 0x47d8, 0x0804,
- 0x28ff, 0xa02e, 0x2520, 0x81ff, 0x1904, 0x2924, 0x7924, 0x7b28,
- 0x7a2c, 0x20a9, 0x0005, 0x20a1, 0x929d, 0x41a1, 0x080c, 0x3641,
- 0x0904, 0x2924, 0x2009, 0x0023, 0x080c, 0x3682, 0x701b, 0x29b9,
- 0x0005, 0x6834, 0x2008, 0xa084, 0x00ff, 0xa096, 0x0011, 0x0120,
- 0xa096, 0x0019, 0x1904, 0x2924, 0x810f, 0xa18c, 0x00ff, 0x0904,
- 0x2924, 0x710e, 0x700c, 0x8001, 0x0528, 0x700e, 0x080c, 0x3641,
- 0x0904, 0x2924, 0x2009, 0x0023, 0x2061, 0x92e6, 0x6224, 0x6328,
- 0x642c, 0x6530, 0xa290, 0x0046, 0xa399, 0x0000, 0xa4a1, 0x0000,
- 0xa5a9, 0x0000, 0x080c, 0x3682, 0x701b, 0x29e7, 0x0005, 0x6834,
- 0xa084, 0x00ff, 0xa096, 0x0002, 0x0120, 0xa096, 0x000a, 0x1904,
- 0x2924, 0x08c0, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x080c,
- 0x4337, 0x1128, 0x7007, 0x0003, 0x701b, 0x2a01, 0x0005, 0x080c,
- 0x492c, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0x929d,
- 0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
- 0x0000, 0xad80, 0x000d, 0x2009, 0x0023, 0x012e, 0x0804, 0x3685,
- 0x61a4, 0x7824, 0x60a6, 0x0804, 0x28ff, 0x2091, 0x8000, 0x7823,
- 0x4000, 0x7827, 0x4953, 0x782b, 0x5020, 0x782f, 0x2020, 0x2009,
- 0x017f, 0x2104, 0x7832, 0x3f00, 0x7836, 0x2061, 0x0100, 0x6200,
- 0x2061, 0x0200, 0x603c, 0x8007, 0xa205, 0x783a, 0x2009, 0x04fd,
- 0x2104, 0x783e, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080,
- 0x2071, 0x0010, 0x20c1, 0x00f0, 0x0804, 0x0427, 0x81ff, 0x1904,
- 0x2924, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4434, 0x1904,
- 0x2927, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0210, 0x0804,
- 0x2927, 0x7c28, 0x7d2c, 0x080c, 0x45d4, 0xd28c, 0x1118, 0x080c,
- 0x457f, 0x0010, 0x080c, 0x45ad, 0x1518, 0x2061, 0x9900, 0x0126,
- 0x2091, 0x8000, 0x6000, 0xa086, 0x0000, 0x0148, 0x6010, 0xa06d,
- 0x0130, 0x683c, 0xa406, 0x1118, 0x6840, 0xa506, 0x0150, 0x012e,
- 0xace0, 0x000c, 0x2001, 0x9216, 0x2004, 0xac02, 0x1a04, 0x2924,
- 0x0c30, 0x080c, 0x80f6, 0x012e, 0x0904, 0x2924, 0x0804, 0x28ff,
- 0xa00e, 0x2001, 0x0005, 0x080c, 0x492c, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x852d, 0x080c, 0x4809, 0x012e, 0x0804, 0x28ff, 0x81ff,
- 0x1904, 0x2924, 0x080c, 0x3656, 0x0904, 0x2927, 0x080c, 0x44d4,
- 0x0904, 0x2924, 0x080c, 0x45e0, 0x0904, 0x2924, 0x0804, 0x28ff,
- 0x81ff, 0x1904, 0x2924, 0x080c, 0x3666, 0x0904, 0x2927, 0x080c,
- 0x4644, 0x0904, 0x2924, 0x2019, 0x0005, 0x080c, 0x45fb, 0x0904,
- 0x2924, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2927, 0x8003, 0x800b,
- 0x810b, 0xa108, 0x080c, 0x573d, 0x0804, 0x28ff, 0x0126, 0x2091,
- 0x8000, 0x81ff, 0x1508, 0x2029, 0x00ff, 0x644c, 0x2400, 0xa506,
- 0x01b0, 0x2508, 0x080c, 0x4434, 0x1190, 0x080c, 0x4644, 0x01a0,
- 0x2019, 0x0004, 0x080c, 0x45fb, 0x0178, 0x7824, 0xa08a, 0x1000,
- 0x1270, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c, 0x573d, 0x8529,
- 0x1e28, 0x012e, 0x0804, 0x28ff, 0x012e, 0x0804, 0x2924, 0x012e,
- 0x0804, 0x2927, 0x080c, 0x3656, 0x0904, 0x2927, 0x080c, 0x453a,
- 0x080c, 0x45d4, 0x0804, 0x28ff, 0x81ff, 0x1904, 0x2924, 0x080c,
- 0x3656, 0x0904, 0x2927, 0x080c, 0x452b, 0x080c, 0x45d4, 0x0804,
- 0x28ff, 0x81ff, 0x1904, 0x2924, 0x080c, 0x3656, 0x0904, 0x2927,
- 0x080c, 0x45af, 0x0904, 0x2924, 0x080c, 0x4373, 0x080c, 0x4578,
- 0x080c, 0x45d4, 0x0804, 0x28ff, 0x080c, 0x3656, 0x0904, 0x2927,
- 0x080c, 0x44d4, 0x0904, 0x2924, 0x62a0, 0x2019, 0x0005, 0x00c6,
- 0x080c, 0x460d, 0x2061, 0x0000, 0x080c, 0x6127, 0x0086, 0x2041,
- 0x0000, 0x080c, 0x606d, 0x2c08, 0x080c, 0x8ee4, 0x008e, 0x00ce,
- 0x080c, 0x45d4, 0x0804, 0x28ff, 0x080c, 0x3656, 0x0904, 0x2927,
- 0x080c, 0x45d4, 0x2208, 0x0804, 0x28ff, 0x0156, 0x00d6, 0x00e6,
- 0x2069, 0x9328, 0x6810, 0x6914, 0xa10a, 0x1210, 0x2009, 0x0000,
- 0x6816, 0x2011, 0x0000, 0x2019, 0x0000, 0x20a9, 0x007e, 0x2069,
- 0x936e, 0x2d04, 0xa075, 0x0130, 0x704c, 0x0071, 0xa210, 0x7080,
- 0x0059, 0xa318, 0x8d68, 0x1f04, 0x2b59, 0x2300, 0xa218, 0x00ee,
- 0x00de, 0x015e, 0x0804, 0x28ff, 0x00f6, 0x0016, 0xa07d, 0x0140,
- 0x2001, 0x0000, 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0,
- 0x001e, 0x00fe, 0x0005, 0x2069, 0x9328, 0x6910, 0x62a8, 0x0804,
- 0x28ff, 0x81ff, 0x1904, 0x2924, 0x614c, 0xa190, 0x2719, 0x2215,
- 0xa294, 0x00ff, 0x636c, 0x83ff, 0x0108, 0x6270, 0x67c8, 0xd79c,
- 0x0118, 0x2031, 0x0001, 0x0060, 0xd7ac, 0x0118, 0x2031, 0x0003,
- 0x0038, 0xd7a4, 0x0118, 0x2031, 0x0002, 0x0010, 0x2031, 0x0000,
- 0x7e3a, 0x7f3e, 0x0804, 0x28ff, 0x613c, 0x6240, 0x0804, 0x28ff,
- 0x080c, 0x3666, 0x0904, 0x2927, 0x0804, 0x28ff, 0x080c, 0x3666,
- 0x0904, 0x2927, 0x6244, 0x6338, 0x0804, 0x28ff, 0x613c, 0x6240,
- 0x7824, 0x603e, 0x7b28, 0x6342, 0x2069, 0x9251, 0x831f, 0xa305,
- 0x6816, 0x0804, 0x28ff, 0x080c, 0x3666, 0x0904, 0x2927, 0x0804,
- 0x28ff, 0x080c, 0x3666, 0x0904, 0x2927, 0x7828, 0xa00d, 0x0904,
- 0x2927, 0x782c, 0xa005, 0x0904, 0x2927, 0x6244, 0x6146, 0x6338,
- 0x603a, 0x0804, 0x28ff, 0x2001, 0x9200, 0x2004, 0xa086, 0x0003,
- 0x1904, 0x2924, 0x00c6, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c,
- 0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001, 0x9214, 0x2004, 0xa085,
- 0xff00, 0x0078, 0xa182, 0x007f, 0x1698, 0xa188, 0x2719, 0x210d,
- 0xa18c, 0x00ff, 0x2001, 0x9214, 0x2004, 0xa116, 0x0548, 0x810f,
- 0xa105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x749c, 0x000e,
- 0x01e0, 0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x080c, 0x3641,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0x8b81, 0x7003,
+ 0x0002, 0xa006, 0x7012, 0x7016, 0x703a, 0x703e, 0x7033, 0x8b91,
+ 0x7037, 0x8b91, 0x7007, 0x0001, 0x2061, 0x8bd1, 0x6003, 0x0002,
+ 0x0005, 0x1004, 0x2763, 0x0e04, 0x2763, 0x2071, 0x8b81, 0x2b78,
+ 0x7818, 0xd084, 0x1140, 0x2a60, 0x7820, 0xa08e, 0x0069, 0x1904,
+ 0x2848, 0x0804, 0x27e1, 0x0005, 0x2071, 0x8b81, 0x7004, 0x0002,
+ 0x276c, 0x276d, 0x2776, 0x2787, 0x0005, 0x1004, 0x2775, 0x0e04,
+ 0x2775, 0x2b78, 0x7818, 0xd084, 0x01e8, 0x0005, 0x2b78, 0x2061,
+ 0x8bd1, 0x6008, 0xa08e, 0x0100, 0x0128, 0xa086, 0x0200, 0x0904,
+ 0x2842, 0x0005, 0x7014, 0x2068, 0x2a60, 0x7018, 0x0807, 0x7010,
+ 0x2068, 0x6834, 0xa086, 0x0103, 0x0108, 0x0005, 0x2a60, 0x2b78,
+ 0x7018, 0x0807, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x1210, 0x61bc,
+ 0x0042, 0x2100, 0xa08a, 0x003f, 0x1a04, 0x283f, 0x61bc, 0x0804,
+ 0x27e1, 0x2823, 0x284e, 0x2856, 0x285a, 0x2862, 0x2868, 0x286c,
+ 0x2875, 0x2878, 0x2882, 0x2885, 0x283f, 0x283f, 0x283f, 0x2888,
+ 0x283f, 0x2897, 0x28ae, 0x28c5, 0x293c, 0x2941, 0x296a, 0x29bb,
+ 0x29cc, 0x29ea, 0x2a21, 0x2a2b, 0x2a38, 0x2a4b, 0x2a6b, 0x2a74,
+ 0x2aaa, 0x2ab0, 0x283f, 0x2ad3, 0x283f, 0x283f, 0x283f, 0x283f,
+ 0x283f, 0x2ad7, 0x2ae1, 0x283f, 0x283f, 0x283f, 0x283f, 0x283f,
+ 0x283f, 0x283f, 0x283f, 0x2ae9, 0x283f, 0x283f, 0x283f, 0x283f,
+ 0x283f, 0x2af6, 0x2afe, 0x283f, 0x283f, 0x283f, 0x283f, 0x283f,
+ 0x283f, 0x0002, 0x2b10, 0x2b63, 0x2bbd, 0x2bcd, 0x283f, 0x2be7,
+ 0x2ff7, 0x393f, 0x283f, 0x283f, 0x283f, 0x283f, 0x283f, 0x283f,
+ 0x283f, 0x283f, 0x2882, 0x2885, 0x283f, 0x283f, 0x2ff9, 0x283f,
+ 0x283f, 0x283f, 0x283f, 0x283f, 0x283f, 0x283f, 0x283f, 0x283f,
+ 0x283f, 0x283f, 0x2ffd, 0x314a, 0x315e, 0x3178, 0x31d9, 0x322a,
+ 0x3235, 0x326c, 0x327b, 0x328a, 0x3299, 0x32c1, 0x330b, 0x336d,
+ 0x337a, 0x3474, 0x356e, 0x3597, 0x3695, 0x36b1, 0x36bd, 0x36f6,
+ 0x378d, 0x283f, 0x283f, 0x283f, 0x283f, 0x37f5, 0x3810, 0x3880,
+ 0x3930, 0x713c, 0x0000, 0x2021, 0x4000, 0x080c, 0x35f4, 0x0126,
+ 0x2091, 0x8000, 0x0e04, 0x282f, 0x7818, 0xd084, 0x0110, 0x012e,
+ 0x0cb0, 0x7c22, 0x7926, 0x7a2a, 0x7b2e, 0x781b, 0x0001, 0x2091,
+ 0x4080, 0x7007, 0x0001, 0x2091, 0x5000, 0x012e, 0x0005, 0x2021,
+ 0x4001, 0x0c18, 0x2021, 0x4002, 0x0c00, 0x2021, 0x4003, 0x08e8,
+ 0x2021, 0x4005, 0x08d0, 0x2021, 0x4006, 0x08b8, 0xa02e, 0x2520,
+ 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0804, 0x3601, 0x7823, 0x0004,
+ 0x7824, 0x0807, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930,
+ 0x0804, 0x3604, 0x7924, 0x7828, 0x2114, 0x200a, 0x0804, 0x2823,
+ 0x7924, 0x2114, 0x0804, 0x2823, 0x2099, 0x0009, 0x20a1, 0x0009,
+ 0x20a9, 0x0007, 0x53a3, 0x0804, 0x2823, 0x7824, 0x2060, 0x0090,
+ 0x2009, 0x0002, 0x2011, 0x0000, 0x2019, 0x0028, 0x783b, 0x0007,
+ 0x0804, 0x2823, 0x7d38, 0x7c3c, 0x0858, 0x7d38, 0x7c3c, 0x08a0,
+ 0x2061, 0x1000, 0xe10c, 0xa006, 0x2c15, 0xa200, 0x8c60, 0x8109,
+ 0x1dd8, 0x2010, 0xa005, 0x0904, 0x2823, 0x0804, 0x2845, 0x2069,
+ 0x8b51, 0x7824, 0x7930, 0xa11a, 0x1a04, 0x284b, 0x8019, 0x0904,
+ 0x284b, 0x684a, 0x6942, 0x782c, 0x6852, 0x7828, 0x6856, 0xa006,
+ 0x685a, 0x685e, 0x080c, 0x4d79, 0x0804, 0x2823, 0x2069, 0x8b51,
+ 0x7824, 0x7934, 0xa11a, 0x1a04, 0x284b, 0x8019, 0x0904, 0x284b,
+ 0x684e, 0x6946, 0x782c, 0x6862, 0x7828, 0x6866, 0xa006, 0x686a,
+ 0x686e, 0x080c, 0x4670, 0x0804, 0x2823, 0xa02e, 0x2520, 0x81ff,
+ 0x1904, 0x2848, 0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1,
+ 0x8b88, 0x41a1, 0x080c, 0x35c0, 0x0904, 0x2848, 0x2009, 0x0023,
+ 0x080c, 0x3601, 0x701b, 0x28dd, 0x0005, 0x6834, 0x2008, 0xa084,
+ 0x00ff, 0xa096, 0x0011, 0x0120, 0xa096, 0x0019, 0x1904, 0x2848,
+ 0x810f, 0xa18c, 0x00ff, 0x0904, 0x2848, 0x710e, 0x700c, 0x8001,
+ 0x0528, 0x700e, 0x080c, 0x35c0, 0x0904, 0x2848, 0x2009, 0x0023,
+ 0x2061, 0x8bd1, 0x6224, 0x6328, 0x642c, 0x6530, 0xa290, 0x0046,
+ 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x080c, 0x3601,
+ 0x701b, 0x290b, 0x0005, 0x6834, 0xa084, 0x00ff, 0xa096, 0x0002,
+ 0x0120, 0xa096, 0x000a, 0x1904, 0x2848, 0x08c0, 0x7010, 0x2068,
+ 0x6838, 0xc0fd, 0x683a, 0x080c, 0x420d, 0x1128, 0x7007, 0x0003,
+ 0x701b, 0x2925, 0x0005, 0x080c, 0x4773, 0x0126, 0x2091, 0x8000,
+ 0x20a9, 0x0005, 0x2099, 0x8b88, 0x530a, 0x2100, 0xa210, 0xa399,
+ 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0xad80, 0x000d, 0x2009,
+ 0x0023, 0x012e, 0x0804, 0x3604, 0x61a4, 0x7824, 0x60a6, 0x0804,
+ 0x2823, 0x2091, 0x8000, 0x7823, 0x4000, 0x7827, 0x4953, 0x782b,
+ 0x5020, 0x782f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7832, 0x3f00,
+ 0x7836, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007,
+ 0xa205, 0x783a, 0x2009, 0x04fd, 0x2104, 0x783e, 0x781b, 0x0001,
+ 0x2091, 0x5000, 0x2091, 0x4080, 0x2071, 0x0010, 0x20c1, 0x00f0,
+ 0x0804, 0x0427, 0x81ff, 0x1904, 0x2848, 0x7924, 0x810f, 0xa18c,
+ 0x00ff, 0x080c, 0x430a, 0x1904, 0x284b, 0x7e38, 0xa684, 0x3fff,
+ 0xa082, 0x4000, 0x0210, 0x0804, 0x284b, 0x7c28, 0x7d2c, 0x080c,
+ 0x44ad, 0xd28c, 0x1118, 0x080c, 0x4458, 0x0010, 0x080c, 0x4486,
+ 0x1518, 0x2061, 0x9200, 0x0126, 0x2091, 0x8000, 0x6000, 0xa086,
+ 0x0000, 0x0148, 0x6010, 0xa06d, 0x0130, 0x683c, 0xa406, 0x1118,
+ 0x6840, 0xa506, 0x0150, 0x012e, 0xace0, 0x000c, 0x2001, 0x8b16,
+ 0x2004, 0xac02, 0x1a04, 0x2848, 0x0c30, 0x080c, 0x795f, 0x012e,
+ 0x0904, 0x2848, 0x0804, 0x2823, 0xa00e, 0x2001, 0x0005, 0x080c,
+ 0x4773, 0x0126, 0x2091, 0x8000, 0x080c, 0x7dce, 0x080c, 0x46a1,
+ 0x012e, 0x0804, 0x2823, 0x81ff, 0x1904, 0x2848, 0x080c, 0x35d5,
+ 0x0904, 0x284b, 0x080c, 0x43ad, 0x0904, 0x2848, 0x080c, 0x44b9,
+ 0x0904, 0x2848, 0x0804, 0x2823, 0x81ff, 0x1904, 0x2848, 0x080c,
+ 0x35e5, 0x0904, 0x284b, 0x080c, 0x451d, 0x0904, 0x2848, 0x2019,
+ 0x0005, 0x080c, 0x44d4, 0x0904, 0x2848, 0x7828, 0xa08a, 0x1000,
+ 0x1a04, 0x284b, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c, 0x5619,
+ 0x0804, 0x2823, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, 0x2009,
+ 0x0001, 0x0448, 0x2029, 0x00ff, 0x644c, 0x2400, 0xa506, 0x01f0,
+ 0x2508, 0x080c, 0x430a, 0x11d0, 0x080c, 0x451d, 0x1128, 0x2009,
+ 0x0002, 0x62ac, 0x2518, 0x00b8, 0x2019, 0x0004, 0x080c, 0x44d4,
+ 0x1118, 0x2009, 0x0006, 0x0078, 0x7824, 0xa08a, 0x1000, 0x1270,
+ 0x8003, 0x800b, 0x810b, 0xa108, 0x080c, 0x5619, 0x8529, 0x1ae8,
+ 0x012e, 0x0804, 0x2823, 0x012e, 0x0804, 0x2848, 0x012e, 0x0804,
+ 0x284b, 0x080c, 0x35d5, 0x0904, 0x284b, 0x080c, 0x4413, 0x080c,
+ 0x44ad, 0x0804, 0x2823, 0x81ff, 0x1904, 0x2848, 0x080c, 0x35d5,
+ 0x0904, 0x284b, 0x080c, 0x4404, 0x080c, 0x44ad, 0x0804, 0x2823,
+ 0x81ff, 0x1904, 0x2848, 0x080c, 0x35d5, 0x0904, 0x284b, 0x080c,
+ 0x4488, 0x0904, 0x2848, 0x080c, 0x4249, 0x080c, 0x4451, 0x080c,
+ 0x44ad, 0x0804, 0x2823, 0x080c, 0x35d5, 0x0904, 0x284b, 0x080c,
+ 0x43ad, 0x0904, 0x2848, 0x62a0, 0x2019, 0x0005, 0x00c6, 0x080c,
+ 0x44e6, 0x2061, 0x0000, 0x080c, 0x59d5, 0x0086, 0x2041, 0x0000,
+ 0x080c, 0x5911, 0x2c08, 0x080c, 0x878f, 0x008e, 0x00ce, 0x080c,
+ 0x44ad, 0x0804, 0x2823, 0x080c, 0x35d5, 0x0904, 0x284b, 0x080c,
+ 0x44ad, 0x2208, 0x0804, 0x2823, 0x0156, 0x00d6, 0x00e6, 0x2069,
+ 0x8c13, 0x6810, 0x6914, 0xa10a, 0x1210, 0x2009, 0x0000, 0x6816,
+ 0x2011, 0x0000, 0x2019, 0x0000, 0x20a9, 0x007e, 0x2069, 0x8c34,
+ 0x2d04, 0xa075, 0x0130, 0x704c, 0x0071, 0xa210, 0x7080, 0x0059,
+ 0xa318, 0x8d68, 0x1f04, 0x2a88, 0x2300, 0xa218, 0x00ee, 0x00de,
+ 0x015e, 0x0804, 0x2823, 0x00f6, 0x0016, 0xa07d, 0x0140, 0x2001,
+ 0x0000, 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e,
+ 0x00fe, 0x0005, 0x2069, 0x8c13, 0x6910, 0x62a8, 0x0804, 0x2823,
+ 0x81ff, 0x1904, 0x2848, 0x614c, 0xa190, 0x263d, 0x2215, 0xa294,
+ 0x00ff, 0x636c, 0x83ff, 0x0108, 0x6270, 0x67c8, 0xd79c, 0x0118,
+ 0x2031, 0x0001, 0x0060, 0xd7ac, 0x0118, 0x2031, 0x0003, 0x0038,
+ 0xd7a4, 0x0118, 0x2031, 0x0002, 0x0010, 0x2031, 0x0000, 0x7e3a,
+ 0x7f3e, 0x0804, 0x2823, 0x613c, 0x6240, 0x0804, 0x2823, 0x0126,
+ 0x2091, 0x8000, 0x6134, 0xa006, 0x2010, 0x2018, 0x012e, 0x0804,
+ 0x2823, 0x080c, 0x35e5, 0x0904, 0x284b, 0x6244, 0x6338, 0x0804,
+ 0x2823, 0x613c, 0x6240, 0x7824, 0x603e, 0x7b28, 0x6342, 0x2069,
+ 0x8b51, 0x831f, 0xa305, 0x6816, 0x0804, 0x2823, 0x0126, 0x2091,
+ 0x8000, 0x7824, 0x6036, 0x012e, 0x0804, 0x2823, 0x080c, 0x35e5,
+ 0x0904, 0x284b, 0x7828, 0xa00d, 0x0904, 0x284b, 0x782c, 0xa005,
+ 0x0904, 0x284b, 0x6244, 0x6146, 0x6338, 0x603a, 0x0804, 0x2823,
+ 0x2001, 0x8b00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2848, 0x00c6,
+ 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff,
+ 0x1130, 0x2001, 0x8b14, 0x2004, 0xa085, 0xff00, 0x0078, 0xa182,
+ 0x007f, 0x1698, 0xa188, 0x263d, 0x210d, 0xa18c, 0x00ff, 0x2001,
+ 0x8b14, 0x2004, 0xa116, 0x0548, 0x810f, 0xa105, 0x0126, 0x2091,
+ 0x8000, 0x0006, 0x080c, 0x6cc2, 0x000e, 0x01e0, 0x601a, 0x600b,
+ 0xbc09, 0x601f, 0x0001, 0x080c, 0x35c0, 0x01d0, 0x6837, 0x0000,
+ 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x701b,
+ 0x2bb6, 0x2d00, 0x6012, 0x2009, 0x0032, 0x080c, 0x6d3f, 0x012e,
+ 0x00ce, 0x0005, 0x00ce, 0x0804, 0x2848, 0x00ce, 0x0804, 0x284b,
+ 0x080c, 0x6d18, 0x0cb8, 0x2001, 0x8b00, 0x2004, 0xa086, 0x0003,
+ 0x1904, 0x2848, 0x00c6, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c,
+ 0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001, 0x8b14, 0x2004, 0xa085,
+ 0xff00, 0x0078, 0xa182, 0x007f, 0x1698, 0xa188, 0x263d, 0x210d,
+ 0xa18c, 0x00ff, 0x2001, 0x8b14, 0x2004, 0xa116, 0x0548, 0x810f,
+ 0xa105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x6cc2, 0x000e,
+ 0x01e0, 0x601a, 0x600b, 0xbc05, 0x601f, 0x0001, 0x080c, 0x35c0,
0x01d0, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838,
- 0xc0fd, 0x683a, 0x701b, 0x2c81, 0x2d00, 0x6012, 0x2009, 0x0032,
- 0x080c, 0x7518, 0x012e, 0x00ce, 0x0005, 0x00ce, 0x0804, 0x2924,
- 0x00ce, 0x0804, 0x2927, 0x080c, 0x74f2, 0x0cb8, 0x2001, 0x9200,
- 0x2004, 0xa086, 0x0003, 0x1904, 0x2924, 0x00c6, 0x2061, 0x0100,
- 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001,
- 0x9214, 0x2004, 0xa085, 0xff00, 0x0078, 0xa182, 0x007f, 0x1698,
- 0xa188, 0x2719, 0x210d, 0xa18c, 0x00ff, 0x2001, 0x9214, 0x2004,
- 0xa116, 0x0548, 0x810f, 0xa105, 0x0126, 0x2091, 0x8000, 0x0006,
- 0x080c, 0x749c, 0x000e, 0x01e0, 0x601a, 0x600b, 0xbc05, 0x601f,
- 0x0001, 0x080c, 0x3641, 0x01d0, 0x6837, 0x0000, 0x7007, 0x0003,
- 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x701b, 0x2c81, 0x2d00,
- 0x6012, 0x2009, 0x0032, 0x080c, 0x7518, 0x012e, 0x00ce, 0x0005,
- 0x00ce, 0x0804, 0x2924, 0x00ce, 0x0804, 0x2927, 0x080c, 0x74f2,
- 0x0cb8, 0x6830, 0xa086, 0x0100, 0x0904, 0x2924, 0x0804, 0x28ff,
- 0x2061, 0x9566, 0x0126, 0x2091, 0x8000, 0x6000, 0xd084, 0x0128,
- 0x6104, 0x6208, 0x012e, 0x0804, 0x28ff, 0x012e, 0x0804, 0x2927,
- 0x81ff, 0x1904, 0x2924, 0x080c, 0x4dc5, 0x0904, 0x2924, 0x0126,
- 0x2091, 0x8000, 0x6244, 0x6064, 0xa202, 0x0248, 0xa085, 0x0001,
- 0x080c, 0x2455, 0x080c, 0x3bfd, 0x012e, 0x0804, 0x28ff, 0x012e,
- 0x0804, 0x2927, 0x0126, 0x2091, 0x8000, 0x7824, 0xa084, 0x0007,
- 0x0002, 0x2cc4, 0x2ccd, 0x2cd4, 0x2cc1, 0x2cc1, 0x2cc1, 0x2cc1,
- 0x2cc1, 0x012e, 0x0804, 0x2927, 0x2009, 0x0114, 0x2104, 0xa085,
- 0x0800, 0x200a, 0x080c, 0x2e1e, 0x0070, 0x2009, 0x010b, 0x200b,
- 0x0010, 0x080c, 0x2e1e, 0x0038, 0x81ff, 0x0128, 0x012e, 0x2021,
- 0x400b, 0x0804, 0x2901, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6,
- 0x00d6, 0x00e6, 0x00f6, 0x2009, 0x0101, 0x210c, 0x0016, 0x2001,
- 0x0138, 0x200c, 0x2003, 0x0001, 0x0016, 0x2001, 0x007a, 0x2034,
- 0x2001, 0x007b, 0x202c, 0xa006, 0x2048, 0x2050, 0x2058, 0x080c,
- 0x302f, 0x080c, 0x2f99, 0xa03e, 0x2720, 0x00f6, 0x00e6, 0x00c6,
- 0x2d60, 0x2071, 0x953b, 0x2079, 0x0020, 0x2011, 0x0001, 0x080c,
- 0x2f45, 0x080c, 0x2f45, 0x00ce, 0x00ee, 0x00fe, 0x080c, 0x2ea6,
- 0x080c, 0x2f6d, 0x080c, 0x2eea, 0x080c, 0x2e65, 0x080c, 0x2e96,
- 0x00f6, 0x2079, 0x0100, 0x7824, 0xd094, 0x01d8, 0x7817, 0x0010,
- 0x2079, 0x0140, 0x2001, 0x0109, 0x2004, 0xd0ac, 0x11a8, 0x7804,
- 0xd0dc, 0x0dc0, 0x2079, 0x0100, 0x7827, 0x0086, 0x7817, 0x0032,
- 0x7824, 0xd0ac, 0x1148, 0xd0bc, 0x0dd8, 0x7827, 0x0080, 0xa026,
- 0x7c16, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x2e06, 0x00fe,
- 0x0804, 0x2dd0, 0x00fe, 0x1d04, 0x2d55, 0x2091, 0x6000, 0x8420,
- 0xa486, 0x0064, 0x1150, 0x8948, 0x2001, 0x007a, 0x2602, 0x2001,
- 0x007b, 0x2502, 0x080c, 0x2e06, 0x0088, 0x87ff, 0x0140, 0x2001,
- 0x0201, 0x2004, 0xa005, 0x1904, 0x2d10, 0x8739, 0x0038, 0x2001,
- 0x9519, 0x2004, 0xa086, 0x0000, 0x1904, 0x2d10, 0x2001, 0x0033,
- 0x2003, 0x00f0, 0x8631, 0x1208, 0x8529, 0x2500, 0xa605, 0x0904,
- 0x2dd0, 0x7824, 0xd0bc, 0x0128, 0x2900, 0xaa05, 0xab05, 0x1904,
- 0x2dd0, 0x6033, 0x000d, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824,
- 0xd0ac, 0x1148, 0x2001, 0x9519, 0x2003, 0x0003, 0x2001, 0x0030,
- 0x2003, 0x0009, 0x0040, 0x6027, 0x0001, 0x2001, 0x0075, 0x2004,
- 0xa005, 0x0108, 0x6026, 0x2c00, 0x601a, 0x20e1, 0x9040, 0x2d00,
- 0x681a, 0x6833, 0x000d, 0x7824, 0xd0a4, 0x1180, 0x6827, 0x0000,
- 0x00c6, 0x20a9, 0x0008, 0x2061, 0x0020, 0x6003, 0x0008, 0x2001,
- 0x0203, 0x2004, 0x1f04, 0x2da5, 0x00ce, 0x0040, 0x6827, 0x0001,
- 0x2001, 0x0074, 0x2004, 0xa005, 0x0108, 0x6826, 0x00f6, 0x00c6,
- 0x2079, 0x0100, 0x2061, 0x0020, 0x7827, 0x0002, 0x2001, 0x0072,
- 0x2004, 0xa084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x0073, 0x2004,
- 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x2cfd,
- 0x2061, 0x0100, 0x6027, 0x0002, 0x20e1, 0x9028, 0x6050, 0xa084,
- 0xf7ef, 0x6052, 0x602f, 0x0000, 0x001e, 0x61e2, 0x001e, 0x6106,
- 0x7824, 0xa084, 0x0003, 0xa086, 0x0002, 0x0148, 0x602c, 0xc0ac,
- 0x602e, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x2908,
- 0x2a10, 0x2b18, 0x2b00, 0xaa05, 0xa905, 0x00fe, 0x00ee, 0x00de,
- 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804,
- 0x28ff, 0x012e, 0x2021, 0x400c, 0x0804, 0x2901, 0x2001, 0x0105,
- 0x2003, 0x0010, 0x2001, 0x0030, 0x2003, 0x0004, 0x2001, 0x0020,
- 0x2003, 0x0004, 0x2001, 0x9519, 0x2003, 0x0000, 0x2001, 0x953b,
- 0x2003, 0x0000, 0x20e1, 0xf000, 0xa026, 0x0005, 0x00f6, 0x2079,
- 0x0100, 0x7850, 0xa084, 0x0990, 0x7852, 0x782c, 0xa085, 0x0020,
- 0x782e, 0x20a9, 0x0008, 0x1d04, 0x2e2b, 0x2091, 0x6000, 0x1f04,
- 0x2e2b, 0x7850, 0xa085, 0x0400, 0x7852, 0x784b, 0xf7f7, 0x7843,
- 0x0090, 0x7843, 0x0010, 0x20a9, 0x000e, 0xe000, 0x1f04, 0x2e3d,
+ 0xc0fd, 0x683a, 0x701b, 0x2bb6, 0x2d00, 0x6012, 0x2009, 0x0032,
+ 0x080c, 0x6d3f, 0x012e, 0x00ce, 0x0005, 0x00ce, 0x0804, 0x2848,
+ 0x00ce, 0x0804, 0x284b, 0x080c, 0x6d18, 0x0cb8, 0x6830, 0xa086,
+ 0x0100, 0x0904, 0x2848, 0x0804, 0x2823, 0x2061, 0x8e2a, 0x0126,
+ 0x2091, 0x8000, 0x6000, 0xd084, 0x0128, 0x6104, 0x6208, 0x012e,
+ 0x0804, 0x2823, 0x012e, 0x0804, 0x284b, 0x81ff, 0x1904, 0x2848,
+ 0x080c, 0x4c42, 0x0904, 0x2848, 0x0126, 0x2091, 0x8000, 0x6244,
+ 0x6064, 0xa202, 0x0248, 0xa085, 0x0001, 0x080c, 0x2333, 0x080c,
+ 0x3b32, 0x012e, 0x0804, 0x2823, 0x012e, 0x0804, 0x284b, 0x0126,
+ 0x2091, 0x8000, 0x7824, 0xa084, 0x0007, 0x0002, 0x2bf9, 0x2c02,
+ 0x2c09, 0x2bf6, 0x2bf6, 0x2bf6, 0x2bf6, 0x2bf6, 0x012e, 0x0804,
+ 0x284b, 0x2009, 0x0114, 0x2104, 0xa085, 0x0800, 0x200a, 0x080c,
+ 0x2d63, 0x0070, 0x2009, 0x010b, 0x200b, 0x0010, 0x080c, 0x2d63,
+ 0x0038, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x2825,
+ 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
+ 0x2009, 0x0101, 0x210c, 0x0016, 0x2001, 0x0138, 0x200c, 0x2003,
+ 0x0001, 0x0016, 0x2001, 0x007a, 0x2034, 0x2001, 0x007b, 0x202c,
+ 0xa006, 0x2048, 0x2050, 0x2058, 0x080c, 0x2f8a, 0x080c, 0x2ef4,
+ 0xa03e, 0x2720, 0x00f6, 0x00e6, 0x00c6, 0x2d60, 0x2071, 0x8dff,
+ 0x2079, 0x0020, 0x2011, 0x0001, 0x080c, 0x2ea0, 0x080c, 0x2ea0,
+ 0x00ce, 0x00ee, 0x00fe, 0x080c, 0x2dfa, 0x080c, 0x2ec8, 0x080c,
+ 0x2e45, 0x080c, 0x2db9, 0x080c, 0x2dea, 0x00f6, 0x2079, 0x0100,
+ 0x7824, 0xd094, 0x0530, 0x7814, 0xa084, 0x0184, 0xa085, 0x0010,
+ 0x7816, 0x2079, 0x0140, 0x080c, 0x2d41, 0x1110, 0x00fe, 0x0430,
+ 0x7804, 0xd0dc, 0x0dc0, 0x2079, 0x0100, 0x7827, 0x0086, 0x7814,
+ 0xa084, 0x0184, 0xa085, 0x0032, 0x7816, 0x080c, 0x2d41, 0x1110,
+ 0x00fe, 0x00a0, 0x7824, 0xd0bc, 0x0dc0, 0x7827, 0x0080, 0xa026,
+ 0x7c16, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x2d4b, 0x00fe,
+ 0x0804, 0x2d0b, 0x00fe, 0x080c, 0x2d41, 0x1150, 0x8948, 0x2001,
+ 0x007a, 0x2602, 0x2001, 0x007b, 0x2502, 0x080c, 0x2d4b, 0x0088,
+ 0x87ff, 0x0140, 0x2001, 0x0201, 0x2004, 0xa005, 0x1904, 0x2c45,
+ 0x8739, 0x0038, 0x2001, 0x8dde, 0x2004, 0xa086, 0x0000, 0x1904,
+ 0x2c45, 0x2001, 0x0033, 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529,
+ 0x2500, 0xa605, 0x0904, 0x2d0b, 0x7824, 0xd0bc, 0x0128, 0x2900,
+ 0xaa05, 0xab05, 0x1904, 0x2d0b, 0x6033, 0x000d, 0x2001, 0x0030,
+ 0x2003, 0x0004, 0x7824, 0xd0ac, 0x1148, 0x2001, 0x8dde, 0x2003,
+ 0x0003, 0x2001, 0x0030, 0x2003, 0x0009, 0x0040, 0x6027, 0x0001,
+ 0x2001, 0x0075, 0x2004, 0xa005, 0x0108, 0x6026, 0x2c00, 0x601a,
+ 0x20e1, 0x9040, 0x2d00, 0x681a, 0x6833, 0x000d, 0x7824, 0xd0a4,
+ 0x1180, 0x6827, 0x0000, 0x00c6, 0x20a9, 0x0008, 0x2061, 0x0020,
+ 0x6003, 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x2ce0, 0x00ce,
+ 0x0040, 0x6827, 0x0001, 0x2001, 0x0074, 0x2004, 0xa005, 0x0108,
+ 0x6826, 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061, 0x0020, 0x7827,
+ 0x0002, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x601a, 0x0006,
+ 0x2001, 0x0073, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce,
+ 0x00fe, 0x0804, 0x2c32, 0x2061, 0x0100, 0x6027, 0x0002, 0x001e,
+ 0x61e2, 0x001e, 0x6106, 0x7824, 0xa084, 0x0003, 0xa086, 0x0002,
+ 0x0188, 0x20e1, 0x9028, 0x6050, 0xa084, 0xf7ef, 0x6052, 0x602f,
+ 0x0000, 0x602c, 0xc0ac, 0x602e, 0x604b, 0xf7f7, 0x6043, 0x0090,
+ 0x6043, 0x0010, 0x2908, 0x2a10, 0x2b18, 0x2b00, 0xaa05, 0xa905,
+ 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e,
+ 0x1118, 0x012e, 0x0804, 0x2823, 0x012e, 0x2021, 0x400c, 0x0804,
+ 0x2825, 0xa085, 0x0001, 0x1d04, 0x2d4a, 0x2091, 0x6000, 0x8420,
+ 0xa486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010, 0x2001,
+ 0x0030, 0x2003, 0x0004, 0x2001, 0x0020, 0x2003, 0x0004, 0x2001,
+ 0x8dde, 0x2003, 0x0000, 0x2001, 0x8dff, 0x2003, 0x0000, 0x20e1,
+ 0xf000, 0xa026, 0x0005, 0x00f6, 0x2079, 0x0100, 0x7850, 0xa084,
+ 0x0990, 0x7852, 0x782c, 0xa085, 0x0020, 0x782e, 0x20a9, 0x0008,
+ 0x1d04, 0x2d70, 0x2091, 0x6000, 0x1f04, 0x2d70, 0x7850, 0xa085,
+ 0x0400, 0x7852, 0x2001, 0x0009, 0x2004, 0xa084, 0x0003, 0xa086,
+ 0x0001, 0x1118, 0x782c, 0xc0ac, 0x782e, 0x784b, 0xf7f7, 0x7843,
+ 0x0090, 0x7843, 0x0010, 0x20a9, 0x000e, 0xe000, 0x1f04, 0x2d8d,
0x7850, 0xa085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854, 0xe000,
0xe000, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048, 0x7850,
0xa085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4, 0xe000,
- 0xe000, 0x8319, 0x1de0, 0x2001, 0x0140, 0x2003, 0x0100, 0x7843,
- 0x0000, 0x2003, 0x0000, 0x00fe, 0x0005, 0x7824, 0xd0ac, 0x11c8,
- 0x00f6, 0x00e6, 0x2071, 0x9519, 0x2079, 0x0030, 0x2001, 0x0201,
- 0x2004, 0xa005, 0x0160, 0x7000, 0xa086, 0x0000, 0x1140, 0x0051,
- 0xd0bc, 0x0108, 0x8738, 0x7003, 0x0003, 0x7803, 0x0019, 0x00ee,
- 0x00fe, 0x0005, 0x780c, 0xa08c, 0x0070, 0x0178, 0x2009, 0x007a,
- 0x260a, 0x2009, 0x007b, 0x250a, 0xd0b4, 0x0108, 0x8a50, 0xd0ac,
- 0x0108, 0x8948, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6, 0x2079,
- 0x0200, 0x781c, 0xd084, 0x0140, 0x20e1, 0x0007, 0x20e1, 0x2000,
- 0x2001, 0x020a, 0x2004, 0x0ca8, 0x00fe, 0x0005, 0x00e6, 0x2071,
- 0x0100, 0x2009, 0x9214, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166,
- 0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078,
- 0xa080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa,
- 0xa006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af,
- 0x95d5, 0x7027, 0x0080, 0x7017, 0x0032, 0x080c, 0x2f6d, 0x7024,
- 0xd0ac, 0x1120, 0xd0bc, 0x0dc8, 0x7027, 0x0080, 0x00f6, 0x00e6,
- 0x2071, 0x9519, 0x2079, 0x0030, 0x2011, 0x0011, 0x080c, 0x2f45,
- 0x2011, 0x0001, 0x080c, 0x2f45, 0x00ee, 0x00fe, 0x7017, 0x0000,
- 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x9519, 0x2079, 0x0030,
- 0x7904, 0xd1fc, 0x0904, 0x2f42, 0x7803, 0x0002, 0xa026, 0xd19c,
- 0x1904, 0x2f3e, 0x7000, 0x0002, 0x2f42, 0x2f00, 0x2f24, 0x2f3e,
- 0xd1bc, 0x1150, 0xd1dc, 0x1150, 0x8001, 0x7002, 0x2011, 0x0001,
- 0x04e1, 0x05c0, 0x04d1, 0x04b0, 0x780f, 0x0000, 0x7820, 0x7924,
- 0x7803, 0x0004, 0x7822, 0x7926, 0x2001, 0x0201, 0x200c, 0x81ff,
- 0x0de8, 0x080c, 0x2e82, 0x2009, 0x0001, 0x7808, 0xd0ec, 0x0110,
- 0x2009, 0x0011, 0x7902, 0x00f0, 0x8001, 0x7002, 0xa184, 0x0880,
- 0x1138, 0x7804, 0xd0fc, 0x1940, 0x2011, 0x0001, 0x00b1, 0x0090,
- 0x6030, 0xa092, 0x0004, 0xa086, 0x0009, 0x1120, 0x6000, 0x601a,
- 0x2011, 0x0025, 0x6232, 0xd1dc, 0x1988, 0x0870, 0x7803, 0x0004,
- 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x6024, 0xa005, 0x0520,
- 0x8001, 0x6026, 0x6018, 0x6130, 0xa140, 0x2804, 0x7832, 0x8840,
- 0x2804, 0x7836, 0x8840, 0x2804, 0x7822, 0x8840, 0x2804, 0x7826,
- 0x8840, 0x7a02, 0x7000, 0x8000, 0x7002, 0x6018, 0xa802, 0xa08a,
- 0x0029, 0x1138, 0x6018, 0xa080, 0x0001, 0x2004, 0x601a, 0x2001,
- 0x000d, 0x6032, 0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x00c6,
- 0x2071, 0x953b, 0x2079, 0x0020, 0x7904, 0xd1fc, 0x01f0, 0x7803,
- 0x0002, 0x2d60, 0xa026, 0x7000, 0x0002, 0x2f95, 0x2f80, 0x2f8c,
- 0x8001, 0x7002, 0xd19c, 0x1188, 0x2011, 0x0001, 0x080c, 0x2f45,
- 0x0160, 0x080c, 0x2f45, 0x0048, 0x8001, 0x7002, 0x7804, 0xd0fc,
- 0x1d30, 0x2011, 0x0001, 0x080c, 0x2f45, 0x00ce, 0x00ee, 0x00fe,
- 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x601b, 0x0004,
- 0x2061, 0x0100, 0x60cf, 0x0400, 0x6004, 0xc0ac, 0xa085, 0x0200,
- 0x6006, 0x2001, 0x0074, 0x2004, 0xa005, 0x01f8, 0x2038, 0x2001,
- 0x0076, 0x2024, 0x2001, 0x0077, 0x201c, 0x080c, 0x3089, 0x6833,
- 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220, 0x2138,
- 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080, 0x000d,
- 0x04a1, 0x1d90, 0x2d00, 0x681a, 0x0088, 0x080c, 0x3089, 0x6833,
- 0x000d, 0x2070, 0x6827, 0x0001, 0x2d00, 0x681a, 0x2001, 0x0076,
- 0x2004, 0x2072, 0x2001, 0x0077, 0x2004, 0x7006, 0x2061, 0x0020,
- 0x2079, 0x0100, 0x6013, 0x0400, 0x20e1, 0x9040, 0x2001, 0x0072,
- 0x2004, 0xa084, 0xfff8, 0x700a, 0x601a, 0x0006, 0x2001, 0x0073,
- 0x2004, 0x700e, 0x601e, 0x78c6, 0x000e, 0x78ca, 0xa006, 0x603a,
- 0x603e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0010,
- 0x20a0, 0x2099, 0x0014, 0x7003, 0x0026, 0x7432, 0x7336, 0xa006,
- 0x703a, 0x703e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7122, 0x7003,
- 0x0041, 0x7004, 0xd0fc, 0x0de8, 0x7003, 0x0002, 0x7003, 0x0040,
- 0x53a5, 0x7430, 0x7334, 0x87ff, 0x0180, 0x00c6, 0x00d6, 0x2d60,
- 0x00c6, 0x080c, 0x3641, 0x00ce, 0x6018, 0x2070, 0x2d00, 0x7006,
- 0x601a, 0x00de, 0x00ce, 0xa085, 0x0001, 0x00ee, 0x0005, 0x00e6,
- 0x2001, 0x0075, 0x2004, 0xa005, 0x0508, 0x2038, 0x2001, 0x0078,
- 0x2024, 0x2001, 0x0079, 0x201c, 0x080c, 0x3089, 0x2d60, 0x6833,
- 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220, 0x2138,
- 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080, 0x000d,
- 0x080c, 0x2ffd, 0x1d88, 0x2d00, 0x681a, 0x00d8, 0x0491, 0x2d60,
- 0x6033, 0x000d, 0x2070, 0x6027, 0x0001, 0x2c00, 0x601a, 0x2001,
- 0x0078, 0x2004, 0x2072, 0x2001, 0x0079, 0x2004, 0x7006, 0x2001,
- 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x2001, 0x0073, 0x2004,
- 0x700e, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824, 0xd0ac, 0x1178,
- 0x2001, 0x0101, 0x200c, 0xc1ed, 0x2102, 0x6027, 0x0000, 0x2001,
- 0x9519, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003, 0x0009, 0x00ee,
- 0x0005, 0x080c, 0x147c, 0x0178, 0xa006, 0x6802, 0x7010, 0xa005,
- 0x1120, 0x2d00, 0x7012, 0x7016, 0x0020, 0x7014, 0x6802, 0x2d00,
- 0x7016, 0xad80, 0x000d, 0x0005, 0x0804, 0x28ff, 0x7d38, 0x7c3c,
- 0x0804, 0x29a3, 0x080c, 0x3641, 0x0904, 0x2924, 0x080c, 0x4dc5,
- 0x0110, 0x080c, 0x41c5, 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c,
- 0x7d38, 0x080c, 0x3682, 0x701b, 0x30b6, 0x0005, 0xade8, 0x000d,
- 0x6800, 0xa005, 0x0904, 0x2927, 0x6804, 0xd0ac, 0x0118, 0xd0a4,
- 0x0904, 0x2927, 0xd094, 0x00c6, 0x2061, 0x0100, 0x6104, 0xa18d,
- 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061, 0x0100, 0x6104,
- 0x0118, 0xa18d, 0x0010, 0x0010, 0xa18c, 0xffef, 0x6106, 0x00ce,
- 0x2009, 0x0100, 0x210c, 0xa18a, 0x0002, 0x0268, 0xd084, 0x0158,
- 0x6a28, 0xa28a, 0x007f, 0x1a04, 0x2927, 0xa288, 0x2719, 0x210d,
- 0xa18c, 0x00ff, 0x6156, 0xd0dc, 0x0130, 0x6828, 0xa08a, 0x007f,
- 0x1a04, 0x2927, 0x604e, 0x6808, 0xa08a, 0x0100, 0x0a04, 0x2927,
- 0xa08a, 0x0841, 0x1a04, 0x2927, 0xa084, 0x0007, 0x1904, 0x2927,
- 0x680c, 0xa005, 0x0904, 0x2927, 0x6810, 0xa005, 0x0904, 0x2927,
- 0x6848, 0x6940, 0xa10a, 0x1a04, 0x2927, 0x8001, 0x0904, 0x2927,
- 0x684c, 0x6944, 0xa10a, 0x1a04, 0x2927, 0x8001, 0x0904, 0x2927,
- 0x6804, 0xd0fc, 0x01f8, 0x080c, 0x3641, 0x0904, 0x2924, 0x2009,
- 0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0xa290, 0x0038, 0xa399,
- 0x0000, 0x080c, 0x3682, 0x701b, 0x312e, 0x0005, 0xade8, 0x000d,
- 0x20a9, 0x0014, 0x2d98, 0x2069, 0x926d, 0x2da0, 0x53a3, 0x7010,
- 0xa0e8, 0x000d, 0x20a9, 0x001c, 0x2d98, 0x2069, 0x9251, 0x2da0,
- 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084, 0x00ff,
- 0x6042, 0x080c, 0x4e5d, 0x080c, 0x4780, 0x080c, 0x47d8, 0x6000,
- 0xa086, 0x0000, 0x1904, 0x31e5, 0x6808, 0x602a, 0x080c, 0x20ce,
- 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f,
- 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830,
- 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010,
- 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x080c, 0x57bc,
- 0x6904, 0xd1fc, 0x0520, 0x00c6, 0x2009, 0x0000, 0x20a9, 0x0001,
- 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0, 0x3508, 0x8109,
- 0x080c, 0x532a, 0x6878, 0x6016, 0x6874, 0x2008, 0xa084, 0xff00,
- 0x8007, 0x600a, 0xa184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003,
- 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, 0x3184, 0x00ce, 0x2069,
- 0x9251, 0x2001, 0x94d7, 0x6a80, 0xa294, 0x0030, 0xa28e, 0x0000,
- 0x0178, 0xa28e, 0x0010, 0x0118, 0xa28e, 0x0020, 0x0148, 0x2003,
- 0xaaaa, 0x2001, 0x0204, 0x2004, 0x2009, 0x94c8, 0x200a, 0x0008,
- 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000,
- 0x00ce, 0x080c, 0x4dc5, 0x0128, 0x080c, 0x3912, 0x0110, 0x080c,
- 0x2455, 0x60c0, 0xa005, 0x01a8, 0x6003, 0x0001, 0x2091, 0x301d,
- 0x080c, 0x4dc5, 0x1158, 0x2011, 0x4ce2, 0x080c, 0x5731, 0x2001,
- 0x94d8, 0x2003, 0x0000, 0x080c, 0x4d10, 0x0038, 0x080c, 0x4105,
- 0x0020, 0x6003, 0x0004, 0x2091, 0x301d, 0x0804, 0x28ff, 0x6000,
- 0xa086, 0x0000, 0x0904, 0x2924, 0x2069, 0x9251, 0x7830, 0x6842,
- 0x7834, 0x6846, 0x2d00, 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c,
- 0x7d38, 0x0804, 0x3685, 0x81ff, 0x1904, 0x2924, 0x080c, 0x4dc5,
- 0x1158, 0x2001, 0x94d8, 0x2003, 0x0001, 0x2001, 0x9200, 0x2003,
- 0x0001, 0x080c, 0x4d10, 0x0038, 0xa006, 0x080c, 0x2455, 0x080c,
- 0x41c5, 0x080c, 0x4105, 0x0804, 0x28ff, 0x81ff, 0x1904, 0x2924,
- 0x080c, 0x4dc5, 0x1110, 0x0804, 0x2924, 0x6184, 0x81ff, 0x0198,
- 0x703f, 0x0000, 0x2001, 0x98c0, 0x2009, 0x0040, 0x7a2c, 0x7b28,
- 0x7c3c, 0x7d38, 0x0126, 0x2091, 0x8000, 0x080c, 0x3685, 0x701b,
- 0x28fd, 0x012e, 0x0005, 0x703f, 0x0001, 0x00d6, 0x2069, 0x98c0,
- 0x20a9, 0x0040, 0x20a1, 0x98c0, 0x2019, 0xffff, 0x43a4, 0x654c,
- 0xa588, 0x2719, 0x210d, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011,
- 0x0002, 0x2100, 0xa506, 0x01a8, 0x080c, 0x4434, 0x1190, 0x6014,
- 0x821c, 0x0238, 0xa398, 0x98c0, 0xa085, 0xff00, 0x8007, 0x201a,
- 0x0038, 0xa398, 0x98c0, 0x2324, 0xa4a4, 0xff00, 0xa405, 0x201a,
- 0x8210, 0x8108, 0xa182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007,
- 0x2d0c, 0xa105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x98c0,
- 0x2099, 0x98c0, 0x080c, 0x4166, 0x0804, 0x3222, 0x080c, 0x3666,
- 0x0904, 0x2927, 0x00c6, 0x080c, 0x3641, 0x00ce, 0x0904, 0x2924,
- 0x080c, 0x4dc5, 0x0500, 0x2001, 0x9252, 0x2004, 0xd0b4, 0x01d8,
- 0x6000, 0xd08c, 0x11c0, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
- 0x1190, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x8476,
- 0x0904, 0x2924, 0x7007, 0x0003, 0x701b, 0x329f, 0x0005, 0x080c,
- 0x3666, 0x0904, 0x2927, 0x20a9, 0x002d, 0x2c98, 0xade8, 0x0002,
- 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006, 0x2098, 0xad80,
- 0x0006, 0x20a0, 0x080c, 0x4166, 0x20a9, 0x0004, 0xac80, 0x000a,
- 0x2098, 0xad80, 0x000a, 0x20a0, 0x080c, 0x4166, 0x2d00, 0x2009,
- 0x002f, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3685, 0x81ff,
- 0x1904, 0x2924, 0x080c, 0x3656, 0x0904, 0x2927, 0x080c, 0x45e9,
- 0x0804, 0x28ff, 0x81ff, 0x1904, 0x2924, 0x7828, 0xa08a, 0x1000,
- 0x1a04, 0x2927, 0x080c, 0x3666, 0x0904, 0x2927, 0x080c, 0x4644,
- 0x0904, 0x2924, 0x2019, 0x0004, 0x080c, 0x45fb, 0x7924, 0x810f,
- 0x7a28, 0x0011, 0x0804, 0x28ff, 0xa186, 0x00ff, 0x0110, 0x0071,
- 0x0060, 0x2029, 0x007e, 0x2061, 0x9200, 0x644c, 0x2400, 0xa506,
- 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x4434,
- 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c, 0x573d,
- 0x0005, 0x81ff, 0x1904, 0x2924, 0x080c, 0x3656, 0x0904, 0x2927,
- 0x080c, 0x44d4, 0x0904, 0x2924, 0x080c, 0x45f2, 0x0804, 0x28ff,
- 0x81ff, 0x1904, 0x2924, 0x080c, 0x3656, 0x0904, 0x2927, 0x080c,
- 0x44d4, 0x0904, 0x2924, 0x080c, 0x45e0, 0x0804, 0x28ff, 0x6100,
- 0x2001, 0x94d8, 0x2014, 0xa282, 0x0003, 0x1210, 0x0804, 0x28ff,
- 0x2011, 0x0000, 0x0804, 0x28ff, 0x0804, 0x28ff, 0x080c, 0x3666,
- 0x0904, 0x2927, 0x6004, 0xa086, 0x0707, 0x0904, 0x2927, 0x2001,
- 0x9200, 0x2004, 0xa086, 0x0003, 0x1904, 0x2924, 0x00d6, 0xace8,
- 0x000a, 0x7924, 0xd184, 0x0110, 0xace8, 0x0006, 0x680c, 0x8007,
- 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f, 0x6a00, 0x8217,
- 0x00de, 0x6100, 0xa18c, 0x0200, 0x0804, 0x28ff, 0x7824, 0xa09c,
- 0x00ff, 0xa39a, 0x0003, 0x1a04, 0x2924, 0x624c, 0xa294, 0x00ff,
- 0xa084, 0xff00, 0x8007, 0xa206, 0x1150, 0x2001, 0x9240, 0x2009,
- 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3685, 0x81ff,
- 0x1904, 0x2924, 0x080c, 0x3666, 0x0904, 0x2927, 0x6004, 0xa084,
- 0x00ff, 0xa086, 0x0006, 0x1904, 0x2924, 0x00c6, 0x080c, 0x3641,
- 0x00ce, 0x0904, 0x2924, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a,
- 0x080c, 0x8428, 0x0904, 0x2924, 0x7007, 0x0003, 0x701b, 0x3399,
- 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2924, 0xad80, 0x000e,
- 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3685,
- 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff, 0x0118, 0x81ff, 0x1904,
- 0x2924, 0x080c, 0x4dc5, 0x0128, 0xa006, 0x080c, 0x2455, 0x080c,
- 0x41c5, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2927, 0x7924, 0xa18c,
- 0xff00, 0x810f, 0xa186, 0x00ff, 0x0138, 0xa182, 0x007f, 0x1a04,
- 0x2927, 0x2100, 0x080c, 0x241f, 0x0026, 0x00c6, 0x0126, 0x2091,
- 0x8000, 0x2061, 0x94f8, 0x601b, 0x0000, 0x601f, 0x0000, 0x080c,
- 0x4dc5, 0x1158, 0x2001, 0x94d8, 0x2003, 0x0001, 0x2001, 0x9200,
- 0x2003, 0x0001, 0x080c, 0x4d10, 0x00a0, 0x2061, 0x0100, 0x2001,
- 0x9214, 0x2004, 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043,
- 0x0090, 0x6043, 0x0010, 0x2009, 0x001e, 0x2011, 0x412a, 0x080c,
- 0x57b3, 0x7924, 0xa18c, 0xff00, 0x810f, 0x080c, 0x4dc5, 0x1110,
- 0x2009, 0x00ff, 0x7a28, 0x080c, 0x32ec, 0x012e, 0x00ce, 0x002e,
- 0x0804, 0x28ff, 0x7924, 0xa18c, 0xff00, 0x810f, 0x00c6, 0x080c,
- 0x4400, 0x2c08, 0x00ce, 0x1904, 0x2927, 0x0804, 0x28ff, 0x81ff,
- 0x1904, 0x2924, 0x60c8, 0xd0ac, 0x1118, 0xd09c, 0x0904, 0x2924,
- 0x080c, 0x3641, 0x0904, 0x2924, 0x7924, 0x7a2c, 0x7b28, 0x7c3c,
- 0x7d38, 0x080c, 0x3682, 0x701b, 0x342e, 0x0005, 0x2009, 0x0080,
- 0x080c, 0x4434, 0x1130, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
- 0x0120, 0x2021, 0x400a, 0x0804, 0x2901, 0x00d6, 0xade8, 0x000d,
- 0x6900, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be,
- 0x0100, 0x0904, 0x34a1, 0xa0be, 0x0112, 0x0904, 0x34a1, 0xa0be,
- 0x0113, 0x0904, 0x34a1, 0xa0be, 0x0114, 0x0904, 0x34a1, 0xa0be,
- 0x0117, 0x0904, 0x34a1, 0xa0be, 0x011a, 0x0904, 0x34a1, 0xa0be,
- 0x0121, 0x05b0, 0xa0be, 0x0131, 0x0598, 0xa0be, 0x0171, 0x05c8,
- 0xa0be, 0x0173, 0x05b0, 0xa0be, 0x01a1, 0x1120, 0x6830, 0x8007,
- 0x6832, 0x04a0, 0xa0be, 0x0212, 0x0540, 0xa0be, 0x0213, 0x0528,
- 0xa0be, 0x0214, 0x01b0, 0xa0be, 0x0217, 0x0168, 0xa0be, 0x021a,
- 0x1120, 0x6838, 0x8007, 0x683a, 0x00e0, 0xa0be, 0x0300, 0x01c8,
- 0x00de, 0x0804, 0x2927, 0xad80, 0x0010, 0x20a9, 0x0007, 0x080c,
- 0x34dd, 0xad80, 0x000e, 0x20a9, 0x0001, 0x080c, 0x34dd, 0x0048,
- 0xad80, 0x000c, 0x080c, 0x34eb, 0x0048, 0xad80, 0x000e, 0x080c,
- 0x34eb, 0xad80, 0x000c, 0x20a9, 0x0001, 0x04b9, 0x00c6, 0x080c,
- 0x3641, 0x0540, 0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, 0x6853,
- 0x0000, 0x684f, 0x0020, 0x685b, 0x0001, 0x810b, 0x697e, 0x6883,
- 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996, 0x689b, 0x0000,
- 0x00ce, 0x00de, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823,
- 0x0000, 0x080c, 0x8442, 0x0904, 0x2924, 0x7007, 0x0003, 0x701b,
- 0x34d6, 0x0005, 0x00ce, 0x00de, 0x0804, 0x2924, 0x6820, 0xa086,
- 0x8001, 0x0904, 0x2924, 0x0804, 0x28ff, 0x0016, 0x2008, 0x2044,
- 0x8000, 0x204c, 0x8000, 0x290a, 0x8108, 0x280a, 0x8108, 0x1f04,
- 0x34df, 0x001e, 0x0005, 0x0016, 0x00a6, 0x00b6, 0x2008, 0x2044,
- 0x8000, 0x204c, 0x8000, 0x2054, 0x8000, 0x205c, 0x2b0a, 0x8108,
- 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a, 0x00be, 0x00ae, 0x001e,
- 0x0005, 0x81ff, 0x1904, 0x2924, 0x7924, 0x2140, 0xa18c, 0xff00,
- 0x810f, 0x60c8, 0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x2927,
- 0xa182, 0x00ff, 0x1a04, 0x2927, 0x7a2c, 0x7b28, 0x606c, 0xa306,
- 0x1140, 0x6070, 0xa24e, 0x0904, 0x2927, 0xa9cc, 0xff00, 0x0904,
- 0x2927, 0x00c6, 0x080c, 0x359b, 0x2c68, 0x00ce, 0x01c0, 0xa0c6,
- 0x4000, 0x1108, 0x0088, 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060,
- 0xa0c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009,
- 0x1108, 0x0010, 0x2001, 0x4006, 0x2020, 0x0804, 0x2901, 0x2d00,
- 0x7022, 0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0x749c,
- 0x05b8, 0x2d00, 0x601a, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c,
- 0x3641, 0x00ce, 0x2b70, 0x1140, 0x080c, 0x74f2, 0x00ee, 0x00ce,
- 0x00be, 0x001e, 0x0804, 0x2924, 0x6837, 0x0000, 0x683b, 0x0000,
- 0x2d00, 0x6012, 0x6833, 0x0000, 0x6838, 0xc0fd, 0xd88c, 0x0108,
- 0xc0f5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x266c, 0x012e,
- 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x43d1, 0x2001, 0x0002,
- 0x080c, 0x43e3, 0x2009, 0x0002, 0x080c, 0x7518, 0xa085, 0x0001,
- 0x00ee, 0x00ce, 0x00be, 0x001e, 0x0904, 0x2924, 0x7007, 0x0003,
- 0x701b, 0x358b, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2924,
- 0x7020, 0x2060, 0x2009, 0x0000, 0x080c, 0x46a5, 0x1110, 0x2009,
- 0x0001, 0x0804, 0x28ff, 0x00e6, 0x00d6, 0x2029, 0x0000, 0x2001,
- 0x9232, 0x2004, 0xd0ac, 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff,
- 0x2071, 0x936e, 0x0030, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071,
- 0x93ee, 0x2e04, 0xa005, 0x1130, 0x2100, 0xa406, 0x1548, 0x2428,
+ 0xe000, 0x8319, 0x1de0, 0x2001, 0x0140, 0x2003, 0x0100, 0x7827,
+ 0x0020, 0x7843, 0x0000, 0x2003, 0x0000, 0x7827, 0x0048, 0x00fe,
+ 0x0005, 0x7824, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071, 0x8dde,
+ 0x2079, 0x0030, 0x2001, 0x0201, 0x2004, 0xa005, 0x0160, 0x7000,
+ 0xa086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738, 0x7003,
+ 0x0003, 0x7803, 0x0019, 0x00ee, 0x00fe, 0x0005, 0x780c, 0xa08c,
+ 0x0070, 0x0178, 0x2009, 0x007a, 0x260a, 0x2009, 0x007b, 0x250a,
+ 0xd0b4, 0x0108, 0x8a50, 0xd0ac, 0x0108, 0x8948, 0xd0a4, 0x0108,
+ 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0140,
+ 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x0ca8,
+ 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2009, 0x8b14, 0x210c,
+ 0x716e, 0x7063, 0x0100, 0x7166, 0x719e, 0x706b, 0x0000, 0x7073,
+ 0x0809, 0x7077, 0x0008, 0x7078, 0xa080, 0x0100, 0x707a, 0x7080,
+ 0x8000, 0x7082, 0x7087, 0xaaaa, 0xa006, 0x708a, 0x708e, 0x707e,
+ 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5, 0x7027, 0x0080, 0x7014,
+ 0xa084, 0x0184, 0xa085, 0x0032, 0x7016, 0x080c, 0x2ec8, 0x080c,
+ 0x2d41, 0x1110, 0x8421, 0x0028, 0x7024, 0xd0bc, 0x0db0, 0x7027,
+ 0x0080, 0x00f6, 0x00e6, 0x2071, 0x8dde, 0x2079, 0x0030, 0x2011,
+ 0x0011, 0x080c, 0x2ea0, 0x2011, 0x0001, 0x080c, 0x2ea0, 0x00ee,
+ 0x00fe, 0x7017, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071,
+ 0x8dde, 0x2079, 0x0030, 0x7904, 0xd1fc, 0x0904, 0x2e9d, 0x7803,
+ 0x0002, 0xa026, 0xd19c, 0x1904, 0x2e99, 0x7000, 0x0002, 0x2e9d,
+ 0x2e5b, 0x2e7f, 0x2e99, 0xd1bc, 0x1150, 0xd1dc, 0x1150, 0x8001,
+ 0x7002, 0x2011, 0x0001, 0x04e1, 0x05c0, 0x04d1, 0x04b0, 0x780f,
+ 0x0000, 0x7820, 0x7924, 0x7803, 0x0004, 0x7822, 0x7926, 0x2001,
+ 0x0201, 0x200c, 0x81ff, 0x0de8, 0x080c, 0x2dd6, 0x2009, 0x0001,
+ 0x7808, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x7902, 0x00f0, 0x8001,
+ 0x7002, 0xa184, 0x0880, 0x1138, 0x7804, 0xd0fc, 0x1940, 0x2011,
+ 0x0001, 0x00b1, 0x0090, 0x6030, 0xa092, 0x0004, 0xa086, 0x0009,
+ 0x1120, 0x6000, 0x601a, 0x2011, 0x0025, 0x6232, 0xd1dc, 0x1988,
+ 0x0870, 0x7803, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005,
+ 0x6024, 0xa005, 0x0520, 0x8001, 0x6026, 0x6018, 0x6130, 0xa140,
+ 0x2804, 0x7832, 0x8840, 0x2804, 0x7836, 0x8840, 0x2804, 0x7822,
+ 0x8840, 0x2804, 0x7826, 0x8840, 0x7a02, 0x7000, 0x8000, 0x7002,
+ 0x6018, 0xa802, 0xa08a, 0x0029, 0x1138, 0x6018, 0xa080, 0x0001,
+ 0x2004, 0x601a, 0x2001, 0x000d, 0x6032, 0xa085, 0x0001, 0x0005,
+ 0x00f6, 0x00e6, 0x00c6, 0x2071, 0x8dff, 0x2079, 0x0020, 0x7904,
+ 0xd1fc, 0x01f0, 0x7803, 0x0002, 0x2d60, 0xa026, 0x7000, 0x0002,
+ 0x2ef0, 0x2edb, 0x2ee7, 0x8001, 0x7002, 0xd19c, 0x1188, 0x2011,
+ 0x0001, 0x080c, 0x2ea0, 0x0160, 0x080c, 0x2ea0, 0x0048, 0x8001,
+ 0x7002, 0x7804, 0xd0fc, 0x1d30, 0x2011, 0x0001, 0x080c, 0x2ea0,
+ 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061,
+ 0x0200, 0x601b, 0x0004, 0x2061, 0x0100, 0x60cf, 0x0400, 0x6004,
+ 0xc0ac, 0xa085, 0x0200, 0x6006, 0x2001, 0x0074, 0x2004, 0xa005,
+ 0x01f8, 0x2038, 0x2001, 0x0076, 0x2024, 0x2001, 0x0077, 0x201c,
+ 0x080c, 0x2fe4, 0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a,
+ 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e,
+ 0x6818, 0xa080, 0x000d, 0x04a1, 0x1d90, 0x2d00, 0x681a, 0x0088,
+ 0x080c, 0x2fe4, 0x6833, 0x000d, 0x2070, 0x6827, 0x0001, 0x2d00,
+ 0x681a, 0x2001, 0x0076, 0x2004, 0x2072, 0x2001, 0x0077, 0x2004,
+ 0x7006, 0x2061, 0x0020, 0x2079, 0x0100, 0x6013, 0x0400, 0x20e1,
+ 0x9040, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x601a,
+ 0x0006, 0x2001, 0x0073, 0x2004, 0x700e, 0x601e, 0x78c6, 0x000e,
+ 0x78ca, 0xa006, 0x603a, 0x603e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+ 0x00e6, 0x2071, 0x0010, 0x20a0, 0x2099, 0x0014, 0x7003, 0x0026,
+ 0x7432, 0x7336, 0xa006, 0x703a, 0x703e, 0x810b, 0x810b, 0x21a8,
+ 0x810b, 0x7122, 0x7003, 0x0041, 0x7004, 0xd0fc, 0x0de8, 0x7003,
+ 0x0002, 0x7003, 0x0040, 0x53a5, 0x7430, 0x7334, 0x87ff, 0x0180,
+ 0x00c6, 0x00d6, 0x2d60, 0x00c6, 0x080c, 0x35c0, 0x00ce, 0x6018,
+ 0x2070, 0x2d00, 0x7006, 0x601a, 0x00de, 0x00ce, 0xa085, 0x0001,
+ 0x00ee, 0x0005, 0x00e6, 0x2001, 0x0075, 0x2004, 0xa005, 0x0508,
+ 0x2038, 0x2001, 0x0078, 0x2024, 0x2001, 0x0079, 0x201c, 0x080c,
+ 0x2fe4, 0x2d60, 0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a,
+ 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e,
+ 0x6818, 0xa080, 0x000d, 0x080c, 0x2f58, 0x1d88, 0x2d00, 0x681a,
+ 0x00d8, 0x0491, 0x2d60, 0x6033, 0x000d, 0x2070, 0x6027, 0x0001,
+ 0x2c00, 0x601a, 0x2001, 0x0078, 0x2004, 0x2072, 0x2001, 0x0079,
+ 0x2004, 0x7006, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a,
+ 0x2001, 0x0073, 0x2004, 0x700e, 0x2001, 0x0030, 0x2003, 0x0004,
+ 0x7824, 0xd0ac, 0x1178, 0x2001, 0x0101, 0x200c, 0xc1ed, 0x2102,
+ 0x6027, 0x0000, 0x2001, 0x8dde, 0x2003, 0x0003, 0x2001, 0x0030,
+ 0x2003, 0x0009, 0x00ee, 0x0005, 0x080c, 0x1488, 0x0178, 0xa006,
+ 0x6802, 0x7010, 0xa005, 0x1120, 0x2d00, 0x7012, 0x7016, 0x0020,
+ 0x7014, 0x6802, 0x2d00, 0x7016, 0xad80, 0x000d, 0x0005, 0x0804,
+ 0x2823, 0x7d38, 0x7c3c, 0x0804, 0x28c7, 0x080c, 0x35c0, 0x0904,
+ 0x2848, 0x080c, 0x4c42, 0x0110, 0x080c, 0x40fd, 0x2009, 0x001c,
+ 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3601, 0x701b, 0x3011,
+ 0x0005, 0xade8, 0x000d, 0x6800, 0xa005, 0x0904, 0x284b, 0x6804,
+ 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x284b, 0xd094, 0x00c6, 0x2061,
+ 0x0100, 0x6104, 0x0138, 0x6200, 0xa292, 0x0005, 0x0218, 0xa18c,
+ 0xffdf, 0x0010, 0xa18d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6,
+ 0x2061, 0x0100, 0x6104, 0x0118, 0xa18d, 0x0010, 0x0010, 0xa18c,
+ 0xffef, 0x6106, 0x00ce, 0x2009, 0x0100, 0x210c, 0xa18a, 0x0002,
+ 0x0268, 0xd084, 0x0158, 0x6a28, 0xa28a, 0x007f, 0x1a04, 0x284b,
+ 0xa288, 0x263d, 0x210d, 0xa18c, 0x00ff, 0x6156, 0xd0dc, 0x0130,
+ 0x6828, 0xa08a, 0x007f, 0x1a04, 0x284b, 0x604e, 0x6808, 0xa08a,
+ 0x0100, 0x0a04, 0x284b, 0xa08a, 0x0841, 0x1a04, 0x284b, 0xa084,
+ 0x0007, 0x1904, 0x284b, 0x680c, 0xa005, 0x0904, 0x284b, 0x6810,
+ 0xa005, 0x0904, 0x284b, 0x6848, 0x6940, 0xa10a, 0x1a04, 0x284b,
+ 0x8001, 0x0904, 0x284b, 0x684c, 0x6944, 0xa10a, 0x1a04, 0x284b,
+ 0x8001, 0x0904, 0x284b, 0x6804, 0xd0fc, 0x01f8, 0x080c, 0x35c0,
+ 0x0904, 0x2848, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+ 0xa290, 0x0038, 0xa399, 0x0000, 0x080c, 0x3601, 0x701b, 0x3091,
+ 0x0005, 0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069, 0x8b6d,
+ 0x2da0, 0x53a3, 0x7010, 0xa0e8, 0x000d, 0x20a9, 0x001c, 0x2d98,
+ 0x2069, 0x8b51, 0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e,
+ 0x8007, 0xa084, 0x00ff, 0x6042, 0x080c, 0x4d79, 0x080c, 0x4618,
+ 0x080c, 0x4670, 0x6000, 0xa086, 0x0000, 0x1904, 0x3148, 0x6808,
+ 0x602a, 0x080c, 0x1fbd, 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007,
+ 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04,
+ 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f,
+ 0x8217, 0x831f, 0x0010, 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e,
+ 0x6312, 0x080c, 0x5695, 0x6904, 0xd1fc, 0x0520, 0x00c6, 0x2009,
+ 0x0000, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d,
+ 0x12b0, 0x3508, 0x8109, 0x080c, 0x520d, 0x6878, 0x6016, 0x6874,
+ 0x2008, 0xa084, 0xff00, 0x8007, 0x600a, 0xa184, 0x00ff, 0x6006,
+ 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04,
+ 0x30e7, 0x00ce, 0x2069, 0x8b51, 0x2001, 0x8d9c, 0x6a80, 0xa294,
+ 0x0030, 0xa28e, 0x0000, 0x0178, 0xa28e, 0x0010, 0x0118, 0xa28e,
+ 0x0020, 0x0148, 0x2003, 0xaaaa, 0x2001, 0x0204, 0x2004, 0x2009,
+ 0x8d8d, 0x200a, 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f,
+ 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x4c42, 0x0128, 0x080c,
+ 0x37e7, 0x0110, 0x080c, 0x2333, 0x60c0, 0xa005, 0x01a8, 0x6003,
+ 0x0001, 0x2091, 0x301d, 0x080c, 0x4c42, 0x1158, 0x2011, 0x4b5d,
+ 0x080c, 0x560d, 0x2001, 0x8d9d, 0x2003, 0x0000, 0x080c, 0x4b8b,
+ 0x0038, 0x080c, 0x403d, 0x0020, 0x6003, 0x0004, 0x2091, 0x301d,
+ 0x0804, 0x2823, 0x6000, 0xa086, 0x0000, 0x0904, 0x2848, 0x2069,
+ 0x8b51, 0x7830, 0x6842, 0x7834, 0x6846, 0x2d00, 0x2009, 0x001c,
+ 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3604, 0x81ff, 0x1904,
+ 0x2848, 0x080c, 0x4c42, 0x1158, 0x2001, 0x8d9d, 0x2003, 0x0001,
+ 0x2001, 0x8b00, 0x2003, 0x0001, 0x080c, 0x4b8b, 0x0038, 0xa006,
+ 0x080c, 0x2333, 0x080c, 0x40fd, 0x080c, 0x403d, 0x0804, 0x2823,
+ 0x81ff, 0x1904, 0x2848, 0x080c, 0x4c42, 0x1110, 0x0804, 0x2848,
+ 0x6184, 0x81ff, 0x0198, 0x703f, 0x0000, 0x2001, 0x91c0, 0x2009,
+ 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x3604, 0x701b, 0x2821, 0x012e, 0x0005, 0x703f, 0x0001,
+ 0x00d6, 0x2069, 0x91c0, 0x20a9, 0x0040, 0x20a1, 0x91c0, 0x2019,
+ 0xffff, 0x43a4, 0x654c, 0xa588, 0x263d, 0x210d, 0xa18c, 0x00ff,
+ 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100, 0xa506, 0x01a8, 0x080c,
+ 0x430a, 0x1190, 0x6014, 0x821c, 0x0238, 0xa398, 0x91c0, 0xa085,
+ 0xff00, 0x8007, 0x201a, 0x0038, 0xa398, 0x91c0, 0x2324, 0xa4a4,
+ 0xff00, 0xa405, 0x201a, 0x8210, 0x8108, 0xa182, 0x0080, 0x1208,
+ 0x0c18, 0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a, 0x00de, 0x20a9,
+ 0x0040, 0x20a1, 0x91c0, 0x2099, 0x91c0, 0x080c, 0x409e, 0x0804,
+ 0x3185, 0x080c, 0x35e5, 0x0904, 0x284b, 0x00c6, 0x080c, 0x35c0,
+ 0x00ce, 0x0904, 0x2848, 0x080c, 0x4c42, 0x0500, 0x2001, 0x8b52,
+ 0x2004, 0xd0b4, 0x01d8, 0x6000, 0xd08c, 0x11c0, 0x6004, 0xa084,
+ 0x00ff, 0xa086, 0x0006, 0x1190, 0x6837, 0x0000, 0x6838, 0xc0fd,
+ 0x683a, 0x080c, 0x7d17, 0x0904, 0x2848, 0x7007, 0x0003, 0x701b,
+ 0x3202, 0x0005, 0x080c, 0x35e5, 0x0904, 0x284b, 0x20a9, 0x002b,
+ 0x2c98, 0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80,
+ 0x0006, 0x2098, 0xad80, 0x0006, 0x20a0, 0x080c, 0x409e, 0x20a9,
+ 0x0004, 0xac80, 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x080c,
+ 0x409e, 0x2d00, 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+ 0x0804, 0x3604, 0x81ff, 0x1904, 0x2848, 0x080c, 0x35d5, 0x0904,
+ 0x284b, 0x080c, 0x44c2, 0x0804, 0x2823, 0x81ff, 0x1904, 0x2848,
+ 0x7828, 0xa08a, 0x1000, 0x1a04, 0x284b, 0x080c, 0x35e5, 0x0904,
+ 0x284b, 0x080c, 0x451d, 0x0904, 0x2848, 0x2019, 0x0004, 0x080c,
+ 0x44d4, 0x7924, 0x810f, 0x7a28, 0x0011, 0x0804, 0x2823, 0xa186,
+ 0x00ff, 0x0110, 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0x8b00,
+ 0x644c, 0x2400, 0xa506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8,
+ 0x0005, 0x080c, 0x430a, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b,
+ 0xa108, 0x080c, 0x5619, 0x0005, 0x81ff, 0x1904, 0x2848, 0x080c,
+ 0x35d5, 0x0904, 0x284b, 0x080c, 0x43ad, 0x0904, 0x2848, 0x080c,
+ 0x44cb, 0x0804, 0x2823, 0x81ff, 0x1904, 0x2848, 0x080c, 0x35d5,
+ 0x0904, 0x284b, 0x080c, 0x43ad, 0x0904, 0x2848, 0x080c, 0x44b9,
+ 0x0804, 0x2823, 0x6100, 0x2001, 0x8d9d, 0x2014, 0xa282, 0x0003,
+ 0x1210, 0x0804, 0x2823, 0x2011, 0x0000, 0x0804, 0x2823, 0x0804,
+ 0x2823, 0x080c, 0x35e5, 0x0904, 0x284b, 0x6004, 0xa086, 0x0707,
+ 0x0904, 0x284b, 0x2001, 0x8b00, 0x2004, 0xa086, 0x0003, 0x1904,
+ 0x2848, 0x00d6, 0xace8, 0x000a, 0x7924, 0xd184, 0x0110, 0xace8,
+ 0x0006, 0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04,
+ 0x831f, 0x6a00, 0x8217, 0x00de, 0x6100, 0xa18c, 0x0200, 0x0804,
+ 0x2823, 0x7824, 0xa09c, 0x00ff, 0xa39a, 0x0003, 0x1a04, 0x2848,
+ 0x624c, 0xa294, 0x00ff, 0xa084, 0xff00, 0x8007, 0xa206, 0x1150,
+ 0x2001, 0x8b40, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+ 0x0804, 0x3604, 0x81ff, 0x1904, 0x2848, 0x080c, 0x35e5, 0x0904,
+ 0x284b, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1904, 0x2848,
+ 0x00c6, 0x080c, 0x35c0, 0x00ce, 0x0904, 0x2848, 0x6837, 0x0000,
+ 0x6838, 0xc0fd, 0x683a, 0x080c, 0x7cc9, 0x0904, 0x2848, 0x7007,
+ 0x0003, 0x701b, 0x32fc, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904,
+ 0x2848, 0xad80, 0x000e, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c,
+ 0x7d38, 0x0804, 0x3604, 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff,
+ 0x0118, 0x81ff, 0x1904, 0x2848, 0x080c, 0x4c42, 0x0128, 0xa006,
+ 0x080c, 0x2333, 0x080c, 0x40fd, 0x7828, 0xa08a, 0x1000, 0x1a04,
+ 0x284b, 0x7924, 0xa18c, 0xff00, 0x810f, 0xa186, 0x00ff, 0x0138,
+ 0xa182, 0x007f, 0x1a04, 0x284b, 0x2100, 0x080c, 0x22fd, 0x0026,
+ 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0x8dbd, 0x601b, 0x0000,
+ 0x601f, 0x0000, 0x080c, 0x4c42, 0x1158, 0x2001, 0x8d9d, 0x2003,
+ 0x0001, 0x2001, 0x8b00, 0x2003, 0x0001, 0x080c, 0x4b8b, 0x00a0,
+ 0x2061, 0x0100, 0x2001, 0x8b14, 0x2004, 0xa084, 0x00ff, 0x810f,
+ 0xa105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x001e,
+ 0x2011, 0x4062, 0x080c, 0x568c, 0x7924, 0xa18c, 0xff00, 0x810f,
+ 0x080c, 0x4c42, 0x1110, 0x2009, 0x00ff, 0x7a28, 0x080c, 0x324f,
+ 0x012e, 0x00ce, 0x002e, 0x0804, 0x2823, 0x7924, 0xa18c, 0xff00,
+ 0x810f, 0x00c6, 0x080c, 0x42d6, 0x2c08, 0x00ce, 0x1904, 0x284b,
+ 0x0804, 0x2823, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x2848,
+ 0x60c8, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804,
+ 0x2848, 0x080c, 0x35c0, 0x1120, 0x2009, 0x0002, 0x0804, 0x2848,
+ 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3601, 0x701b,
+ 0x339a, 0x0005, 0x2009, 0x0080, 0x080c, 0x430a, 0x1130, 0x6004,
+ 0xa084, 0x00ff, 0xa086, 0x0006, 0x0120, 0x2021, 0x400a, 0x0804,
+ 0x2825, 0x00d6, 0xade8, 0x000d, 0x6900, 0x6a08, 0x6b0c, 0x6c10,
+ 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0904, 0x340d, 0xa0be,
+ 0x0112, 0x0904, 0x340d, 0xa0be, 0x0113, 0x0904, 0x340d, 0xa0be,
+ 0x0114, 0x0904, 0x340d, 0xa0be, 0x0117, 0x0904, 0x340d, 0xa0be,
+ 0x011a, 0x0904, 0x340d, 0xa0be, 0x0121, 0x05b0, 0xa0be, 0x0131,
+ 0x0598, 0xa0be, 0x0171, 0x05c8, 0xa0be, 0x0173, 0x05b0, 0xa0be,
+ 0x01a1, 0x1120, 0x6830, 0x8007, 0x6832, 0x04a0, 0xa0be, 0x0212,
+ 0x0540, 0xa0be, 0x0213, 0x0528, 0xa0be, 0x0214, 0x01b0, 0xa0be,
+ 0x0217, 0x0168, 0xa0be, 0x021a, 0x1120, 0x6838, 0x8007, 0x683a,
+ 0x00e0, 0xa0be, 0x0300, 0x01c8, 0x00de, 0x0804, 0x284b, 0xad80,
+ 0x0010, 0x20a9, 0x0007, 0x080c, 0x3450, 0xad80, 0x000e, 0x20a9,
+ 0x0001, 0x080c, 0x3450, 0x0048, 0xad80, 0x000c, 0x080c, 0x345e,
+ 0x0048, 0xad80, 0x000e, 0x080c, 0x345e, 0xad80, 0x000c, 0x20a9,
+ 0x0001, 0x04f1, 0x00c6, 0x080c, 0x35c0, 0x0558, 0x6838, 0xc0fd,
+ 0x683a, 0x6837, 0x0119, 0x6853, 0x0000, 0x684f, 0x0020, 0x685b,
+ 0x0001, 0x810b, 0x697e, 0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e,
+ 0x6d92, 0x6996, 0x689b, 0x0000, 0x00ce, 0x00de, 0x6837, 0x0000,
+ 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x080c, 0x7ce3, 0x1120,
+ 0x2009, 0x0003, 0x0804, 0x2848, 0x7007, 0x0003, 0x701b, 0x3447,
+ 0x0005, 0x00ce, 0x00de, 0x2009, 0x0002, 0x0804, 0x2848, 0x6820,
+ 0xa086, 0x8001, 0x1904, 0x2823, 0x2009, 0x0004, 0x0804, 0x2848,
+ 0x0016, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108,
+ 0x280a, 0x8108, 0x1f04, 0x3452, 0x001e, 0x0005, 0x0016, 0x00a6,
+ 0x00b6, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x2054, 0x8000,
+ 0x205c, 0x2b0a, 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a,
+ 0x00be, 0x00ae, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001,
+ 0x0804, 0x2848, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0x60c8,
+ 0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x284b, 0xa182, 0x00ff,
+ 0x1a04, 0x284b, 0x7a2c, 0x7b28, 0x606c, 0xa306, 0x1140, 0x6070,
+ 0xa24e, 0x0904, 0x284b, 0xa9cc, 0xff00, 0x0904, 0x284b, 0x00c6,
+ 0x080c, 0x3513, 0x2c68, 0x00ce, 0x01c0, 0xa0c6, 0x4000, 0x1108,
+ 0x0088, 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008,
+ 0x1118, 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010,
+ 0x2001, 0x4006, 0x2020, 0x0804, 0x2825, 0x2d00, 0x7022, 0x0016,
+ 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0x6cc2, 0x05a0, 0x2d00,
+ 0x601a, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x35c0, 0x00ce,
+ 0x2b70, 0x1150, 0x080c, 0x6d18, 0x00ee, 0x00ce, 0x00be, 0x001e,
+ 0x2009, 0x0002, 0x0804, 0x2848, 0x6837, 0x0000, 0x2d00, 0x6012,
+ 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x2563, 0x012e, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c,
+ 0x42a7, 0x2001, 0x0002, 0x080c, 0x42b9, 0x2009, 0x0002, 0x080c,
+ 0x6d3f, 0xa085, 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x1120,
+ 0x2009, 0x0003, 0x0804, 0x2848, 0x7007, 0x0003, 0x701b, 0x3501,
+ 0x0005, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0904, 0x2848,
+ 0x7020, 0x2060, 0x2009, 0x0000, 0x080c, 0x457e, 0x1110, 0x2009,
+ 0x0001, 0x0804, 0x2823, 0x00e6, 0x00d6, 0x2029, 0x0000, 0x2001,
+ 0x8b32, 0x2004, 0xd0ac, 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff,
+ 0x2071, 0x8c34, 0x0030, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071,
+ 0x8cb4, 0x2e04, 0xa005, 0x1130, 0x2100, 0xa406, 0x1548, 0x2428,
0xc5fd, 0x0430, 0x2068, 0x6f10, 0x2700, 0xa306, 0x11b0, 0x6e14,
0x2600, 0xa206, 0x1190, 0x2400, 0xa106, 0x1160, 0x2d60, 0xd884,
0x0540, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1510, 0x2001,
0x4000, 0x0400, 0x2001, 0x4007, 0x00e8, 0x2400, 0xa106, 0x1140,
0x6e14, 0x87ff, 0x1110, 0x86ff, 0x09d0, 0x2001, 0x4008, 0x0090,
- 0x8420, 0x8e70, 0x1f04, 0x35b1, 0x85ff, 0x1130, 0x2001, 0x4009,
- 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, 0x4400, 0x1dd0, 0x6312,
+ 0x8420, 0x8e70, 0x1f04, 0x3529, 0x85ff, 0x1130, 0x2001, 0x4009,
+ 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, 0x42d6, 0x1dd0, 0x6312,
0x6216, 0xa006, 0xa005, 0x00de, 0x00ee, 0x0005, 0x81ff, 0x1904,
- 0x2924, 0x080c, 0x3641, 0x0904, 0x2924, 0x6837, 0x0000, 0x6838,
- 0xc0fd, 0x683a, 0x7824, 0xa005, 0x0904, 0x2927, 0xa096, 0x00ff,
- 0x0120, 0xa092, 0x0004, 0x1a04, 0x2927, 0x2010, 0x2d18, 0x080c,
- 0x2631, 0x0904, 0x2924, 0x7007, 0x0003, 0x701b, 0x3618, 0x0005,
- 0x6830, 0xa086, 0x0100, 0x0904, 0x2924, 0x0804, 0x28ff, 0x7924,
+ 0x2848, 0x080c, 0x35c0, 0x0904, 0x2848, 0x6837, 0x0000, 0x6838,
+ 0xc0fd, 0x683a, 0x7824, 0xa005, 0x0904, 0x284b, 0xa096, 0x00ff,
+ 0x0120, 0xa092, 0x0004, 0x1a04, 0x284b, 0x2010, 0x2d18, 0x080c,
+ 0x2528, 0x0904, 0x2848, 0x7007, 0x0003, 0x701b, 0x3590, 0x0005,
+ 0x6830, 0xa086, 0x0100, 0x0904, 0x2848, 0x0804, 0x2823, 0x7924,
0xa18c, 0xff00, 0x810f, 0x60c8, 0xd0ac, 0x1120, 0xa182, 0x0080,
- 0x0a04, 0x2927, 0xa182, 0x00ff, 0x1a04, 0x2927, 0x0126, 0x2091,
- 0x8000, 0x080c, 0x831a, 0x1150, 0xa190, 0x936e, 0x2204, 0xa065,
- 0x0128, 0x080c, 0x41e0, 0x012e, 0x0804, 0x28ff, 0x012e, 0x0804,
- 0x2924, 0x080c, 0x147c, 0x0188, 0xa006, 0x6802, 0x7010, 0xa005,
- 0x1120, 0x2d00, 0x7012, 0x7016, 0x0030, 0x7014, 0x6802, 0x2060,
- 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d, 0x0005, 0x7924, 0x810f,
- 0xa18c, 0x00ff, 0x080c, 0x4434, 0x1130, 0x7e28, 0xa684, 0x3fff,
- 0xa082, 0x4000, 0x0208, 0xa066, 0x8cff, 0x0005, 0x7e24, 0x860f,
- 0xa18c, 0x00ff, 0x080c, 0x4434, 0x1128, 0xa6b4, 0x00ff, 0xa682,
- 0x4000, 0x0208, 0xa066, 0x8cff, 0x0005, 0x0016, 0x7110, 0x81ff,
- 0x0128, 0x2168, 0x6904, 0x080c, 0x1493, 0x0cc8, 0x7112, 0x7116,
- 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061,
- 0x92e6, 0x6606, 0x6112, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532,
- 0x2c10, 0x080c, 0x14c7, 0x7007, 0x0002, 0x701b, 0x28ff, 0x0005,
- 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x92a4,
- 0x2004, 0xa005, 0x1168, 0x0e04, 0x36b0, 0x7818, 0xd084, 0x1140,
- 0x7a22, 0x7b26, 0x7c2a, 0x781b, 0x0001, 0x2091, 0x4080, 0x0408,
- 0x0016, 0x00c6, 0x00e6, 0x2071, 0x9296, 0x7138, 0xa182, 0x0010,
- 0x0218, 0x7030, 0x2060, 0x0078, 0x7030, 0xa0e0, 0x0004, 0xac82,
- 0x92e6, 0x0210, 0x2061, 0x92a6, 0x2c00, 0x7032, 0x81ff, 0x1108,
- 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce,
- 0x001e, 0x012e, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x9296, 0x7038,
- 0xa005, 0x0570, 0x0126, 0x2091, 0x8000, 0x0e04, 0x3707, 0x00f6,
- 0x2079, 0x0000, 0x7818, 0xd084, 0x1508, 0x00c6, 0x7034, 0x2060,
- 0x2c04, 0x7822, 0x6004, 0x7826, 0x6008, 0x782a, 0x781b, 0x0001,
- 0x2091, 0x4080, 0x7038, 0x8001, 0x703a, 0xa005, 0x1130, 0x7033,
- 0x92a6, 0x7037, 0x92a6, 0x00ce, 0x0048, 0xac80, 0x0004, 0xa0fa,
- 0x92e6, 0x0210, 0x2001, 0x92a6, 0x7036, 0x00ce, 0x00fe, 0x012e,
- 0x00ee, 0x0005, 0x0026, 0x2001, 0x9252, 0x2004, 0xd0c4, 0x0120,
- 0x2011, 0x8014, 0x080c, 0x3698, 0x002e, 0x0005, 0x81ff, 0x1904,
- 0x2924, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, 0x6032, 0x080c,
- 0x4dc5, 0x1158, 0x2001, 0x94d8, 0x2003, 0x0001, 0x2001, 0x9200,
- 0x2003, 0x0001, 0x080c, 0x4d10, 0x0010, 0x080c, 0x4105, 0x012e,
- 0x0804, 0x28ff, 0x7824, 0x2008, 0xa18c, 0xfffd, 0x1128, 0x61d4,
- 0xa10d, 0x61d6, 0x0804, 0x28ff, 0x0804, 0x2927, 0x81ff, 0x1904,
- 0x2924, 0x6000, 0xa086, 0x0003, 0x1904, 0x2924, 0x2001, 0x9252,
- 0x2004, 0xd0a4, 0x1904, 0x2924, 0x080c, 0x3666, 0x0904, 0x2927,
- 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1120, 0x7828, 0xa005,
- 0x0904, 0x28ff, 0x00c6, 0x080c, 0x3641, 0x00ce, 0x0904, 0x2924,
- 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c,
- 0x84d7, 0x0904, 0x2924, 0x7007, 0x0003, 0x701b, 0x3770, 0x0005,
- 0x6830, 0xa086, 0x0100, 0x0904, 0x2924, 0x0804, 0x28ff, 0x2001,
- 0x9200, 0x2004, 0xa086, 0x0003, 0x1904, 0x2924, 0x7f24, 0x7a2c,
- 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3641, 0x0904, 0x2924, 0x2009,
- 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80,
- 0x0005, 0x7026, 0x20a0, 0x080c, 0x4434, 0x15e0, 0x6004, 0xa0c4,
- 0x00ff, 0xa8c6, 0x0006, 0x0150, 0xa0c4, 0xff00, 0xa8c6, 0x0600,
- 0x0128, 0xa084, 0x00ff, 0xa082, 0x0006, 0x1660, 0xd784, 0x0150,
- 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x080c,
- 0x34eb, 0x0048, 0xac80, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004,
- 0x53a3, 0x080c, 0x34eb, 0xa186, 0x007e, 0x0178, 0xa186, 0x0080,
- 0x0160, 0x6004, 0xa084, 0x00ff, 0xa0c2, 0x0006, 0x1210, 0xc1fd,
- 0x0020, 0x080c, 0x46a5, 0x1108, 0xc1fd, 0x21a2, 0xc1fc, 0x94a0,
- 0xa6b0, 0x0005, 0x8108, 0x2001, 0x9232, 0x2004, 0xd0ac, 0x0118,
- 0xa186, 0x0100, 0x0040, 0xd78c, 0x0120, 0xa186, 0x0100, 0x0148,
- 0x0018, 0xa186, 0x007e, 0x0128, 0xa686, 0x0028, 0x0150, 0x0804,
- 0x3793, 0x86ff, 0x1120, 0x7120, 0x810b, 0x0804, 0x28ff, 0x702f,
- 0x0001, 0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0x92e6,
- 0x6007, 0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e,
- 0x6532, 0x2c10, 0x080c, 0x14c7, 0x7007, 0x0002, 0x701b, 0x3809,
- 0x0005, 0x702c, 0xa005, 0x1170, 0x711c, 0x7024, 0x20a0, 0x7728,
- 0x2031, 0x0000, 0x2061, 0x92e6, 0x6224, 0x6328, 0x642c, 0x6530,
- 0x0804, 0x3793, 0x7120, 0x810b, 0x0804, 0x28ff, 0x2029, 0x007e,
- 0x7924, 0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007, 0xa0e2,
- 0x0020, 0x0a04, 0x2927, 0xa502, 0x0a04, 0x2927, 0xa184, 0x00ff,
- 0xa0e2, 0x0020, 0x0a04, 0x2927, 0xa502, 0x0a04, 0x2927, 0xa284,
- 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2927, 0xa502, 0x0a04,
- 0x2927, 0xa284, 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x2927, 0xa502,
- 0x0a04, 0x2927, 0xa384, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04,
- 0x2927, 0xa502, 0x0a04, 0x2927, 0xa384, 0x00ff, 0xa0e2, 0x0020,
- 0x0a04, 0x2927, 0xa502, 0x0a04, 0x2927, 0xa484, 0xff00, 0x8007,
- 0xa0e2, 0x0020, 0x0a04, 0x2927, 0xa502, 0x0a04, 0x2927, 0xa484,
- 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x2927, 0xa502, 0x0a04, 0x2927,
- 0x2061, 0x94df, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x28ff,
- 0x080c, 0x3641, 0x0904, 0x2924, 0x2009, 0x0015, 0x7a2c, 0x7b28,
- 0x7c3c, 0x7d38, 0x080c, 0x3682, 0x701b, 0x3887, 0x0005, 0xade8,
- 0x000d, 0x6800, 0xa005, 0x0904, 0x2927, 0x6804, 0x2008, 0xa18c,
- 0xfff8, 0x1904, 0x2927, 0x680c, 0xa005, 0x0904, 0x2927, 0xa082,
- 0xff01, 0x1a04, 0x2927, 0x6810, 0xa082, 0x005c, 0x0a04, 0x2927,
- 0x6824, 0x2008, 0xa082, 0x0008, 0x0a04, 0x2927, 0xa182, 0x0400,
- 0x1a04, 0x2927, 0x080c, 0x5a84, 0x6944, 0x6820, 0xa102, 0x0a04,
- 0x2927, 0x6828, 0x6944, 0x810c, 0xa102, 0x0a04, 0x2927, 0x6840,
- 0xa082, 0x000f, 0x1a04, 0x2927, 0x00d6, 0x080c, 0x145f, 0x0904,
- 0x2924, 0x2d00, 0x00de, 0x684e, 0x00d6, 0x6848, 0xa005, 0x0148,
- 0x2008, 0x2069, 0x9200, 0x68dc, 0xa108, 0x68a8, 0xa102, 0x1208,
- 0x69de, 0x00de, 0x20a9, 0x0015, 0x2d98, 0x2069, 0x9281, 0x2da0,
- 0x53a3, 0x080c, 0x5957, 0x0904, 0x2924, 0x080c, 0x5885, 0x1904,
- 0x2924, 0x00c6, 0x2061, 0x0100, 0x6104, 0xa18d, 0x8000, 0x6106,
- 0x610c, 0xa18d, 0x0100, 0x610e, 0x2061, 0x0140, 0x610c, 0xa18d,
- 0x0100, 0x6902, 0x6b10, 0x2061, 0x9519, 0x6316, 0x080c, 0x4716,
- 0x2001, 0x9295, 0x2003, 0x0000, 0x00ce, 0x0804, 0x28ff, 0xe000,
- 0xe000, 0xe000, 0xe000, 0xe000, 0xe000, 0xe000, 0x0804, 0x28ff,
- 0x7824, 0x0804, 0x28ff, 0x7824, 0x00e6, 0x2071, 0x9281, 0x00ee,
- 0x0804, 0x28ff, 0x0006, 0x2001, 0x9252, 0x2004, 0xd0cc, 0x000e,
- 0x0005, 0x0006, 0x2001, 0x9271, 0x2004, 0xd0bc, 0x000e, 0x0005,
- 0x6164, 0x7a24, 0x6300, 0x82ff, 0x1118, 0x7926, 0x0804, 0x28ff,
- 0x83ff, 0x1904, 0x2927, 0x2001, 0xfff0, 0xa200, 0x1a04, 0x2927,
- 0x2019, 0xffff, 0x6068, 0xa302, 0xa200, 0x0a04, 0x2927, 0x7926,
- 0x6266, 0x0804, 0x28ff, 0x2001, 0x9200, 0x2004, 0xa086, 0x0003,
- 0x1904, 0x2924, 0x7c28, 0x7d24, 0x7e38, 0x7f2c, 0x080c, 0x3641,
- 0x0904, 0x2924, 0x2009, 0x0000, 0x2019, 0x0000, 0x7023, 0x0000,
- 0x702f, 0x0000, 0xad80, 0x0003, 0x7026, 0x20a0, 0xa1e0, 0x936e,
- 0x2c64, 0x8cff, 0x01b8, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
- 0x0130, 0x6004, 0xa084, 0xff00, 0xa086, 0x0600, 0x1158, 0x6014,
- 0x20a2, 0x94a0, 0x6010, 0x8007, 0xa105, 0x8007, 0x20a2, 0x94a0,
- 0xa398, 0x0002, 0x8108, 0xa182, 0x00ff, 0x0120, 0xa386, 0x002a,
- 0x0148, 0x08e0, 0x83ff, 0x1120, 0x7120, 0x810c, 0x0804, 0x28ff,
- 0x702f, 0x0001, 0x711e, 0x7020, 0xa300, 0x7022, 0x2061, 0x92e6,
- 0x6007, 0x0000, 0x6312, 0x7024, 0x600e, 0x6426, 0x652a, 0x662e,
- 0x6732, 0x2c10, 0x080c, 0x14c7, 0x7007, 0x0002, 0x701b, 0x3999,
- 0x0005, 0x702c, 0xa005, 0x1158, 0x711c, 0x7024, 0x20a0, 0x2019,
- 0x0000, 0x6424, 0x6528, 0x662c, 0x6730, 0x0804, 0x3956, 0x7120,
- 0x810c, 0x0804, 0x28ff, 0x81ff, 0x1904, 0x2924, 0x60c8, 0xd0ac,
- 0x1118, 0xd09c, 0x0904, 0x2924, 0x080c, 0x3641, 0x0904, 0x2924,
- 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3682, 0x701b,
- 0x39c2, 0x0005, 0x00d6, 0xade8, 0x000d, 0x6828, 0xa0be, 0x7000,
- 0x0148, 0xa0be, 0x7100, 0x0130, 0xa0be, 0x7200, 0x0118, 0x00de,
- 0x0804, 0x2927, 0x6820, 0x6924, 0x080c, 0x240b, 0x1500, 0x080c,
- 0x4400, 0x11e8, 0x7122, 0x6612, 0x6516, 0x6e18, 0x00c6, 0x080c,
- 0x3641, 0x01a8, 0x080c, 0x3641, 0x0190, 0x00ce, 0x00de, 0x6837,
- 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x080c, 0x845c,
- 0x0904, 0x2924, 0x7007, 0x0003, 0x701b, 0x39fa, 0x0005, 0x00de,
- 0x0804, 0x2924, 0x7120, 0x080c, 0x441f, 0x6820, 0xa086, 0x8001,
- 0x0904, 0x2924, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002, 0x0006,
- 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x4166, 0x000e, 0xade8,
- 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0x92e6, 0x6007,
- 0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x1108, 0x0018, 0xa7c6,
- 0x7100, 0x1140, 0xa6c2, 0x0004, 0x0a04, 0x2927, 0x2009, 0x0004,
- 0x0804, 0x3685, 0xa7c6, 0x7200, 0x1904, 0x2927, 0xa6c2, 0x0054,
- 0x0a04, 0x2927, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a, 0x642e,
- 0x6532, 0x2c10, 0x080c, 0x14c7, 0x7007, 0x0002, 0x701b, 0x3a41,
- 0x0005, 0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004, 0xa080,
- 0x0002, 0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x4166,
- 0x000e, 0x2009, 0x002a, 0x2061, 0x92e6, 0x6224, 0x6328, 0x642c,
- 0x6530, 0x0804, 0x3685, 0x81ff, 0x1904, 0x2924, 0x080c, 0x3656,
- 0x0904, 0x2927, 0x080c, 0x44d4, 0x0904, 0x2924, 0x080c, 0x4604,
- 0x0804, 0x28ff, 0x0126, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071,
- 0x9200, 0x6044, 0xd0a4, 0x11b0, 0xd084, 0x0118, 0x080c, 0x3bd7,
- 0x0068, 0xd08c, 0x0118, 0x080c, 0x3af8, 0x0040, 0xd094, 0x0118,
- 0x080c, 0x3ad0, 0x0018, 0xd09c, 0x0108, 0x0061, 0x00ee, 0x00ce,
- 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a,
- 0x001e, 0x0ca0, 0x624c, 0xa286, 0xf0f0, 0x1150, 0x6048, 0xa086,
- 0xf0f0, 0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0478,
- 0xa294, 0xff00, 0xa296, 0xf700, 0x0160, 0x6240, 0xa295, 0x0100,
- 0x6242, 0xa294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x4186,
- 0x00f0, 0x6040, 0xa084, 0x0010, 0xa085, 0x0040, 0x6042, 0x6043,
- 0x0000, 0x7077, 0x0000, 0x7093, 0x0001, 0x70b3, 0x0000, 0x70cb,
- 0x0000, 0x2009, 0x98c0, 0x200b, 0x0000, 0x7087, 0x0000, 0x707b,
- 0x000f, 0x2009, 0x000f, 0x2011, 0x40a8, 0x080c, 0x57b3, 0x0005,
- 0x0156, 0x7078, 0xa005, 0x1510, 0x2011, 0x40a8, 0x080c, 0x5731,
- 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9, 0x00c8,
- 0x6044, 0xd08c, 0x1168, 0x1f04, 0x3ae0, 0x6242, 0x708b, 0x0000,
- 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, 0x6042, 0x6242, 0x0030,
- 0x6242, 0x708b, 0x0000, 0x707f, 0x0000, 0x0000, 0x015e, 0x0005,
- 0x707c, 0xa08a, 0x0003, 0x1210, 0x0023, 0x0010, 0x080c, 0x13fe,
- 0x0005, 0x3b04, 0x3b54, 0x3bd6, 0x00f6, 0x707f, 0x0001, 0x20e1,
- 0xa000, 0xe000, 0x20e1, 0x8700, 0x080c, 0x20ce, 0x20e1, 0x9080,
- 0x20e1, 0x4000, 0x2079, 0x9700, 0x207b, 0x2200, 0x7807, 0x00ef,
- 0x780b, 0x0000, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000,
- 0x781b, 0x0000, 0x781f, 0x0000, 0x7823, 0xffff, 0x7827, 0xffff,
- 0x782b, 0x0000, 0x782f, 0x0000, 0x2079, 0x970c, 0x207b, 0x1101,
- 0x7807, 0x0000, 0x2099, 0x9205, 0x20a1, 0x970e, 0x20a9, 0x0004,
- 0x53a3, 0x2079, 0x9712, 0x207b, 0x0000, 0x7807, 0x0000, 0x2099,
- 0x9700, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c,
- 0x600f, 0x0000, 0x080c, 0x40ec, 0x00fe, 0x7083, 0x0000, 0x6043,
- 0x0008, 0x6043, 0x0000, 0x0005, 0x00d6, 0x7080, 0x7083, 0x0000,
- 0xa025, 0x0904, 0x3bbe, 0x6020, 0xd0b4, 0x1904, 0x3bbc, 0x7190,
- 0x81ff, 0x0904, 0x3ba6, 0xa486, 0x000c, 0x1904, 0x3bb1, 0xa480,
- 0x0018, 0x8004, 0x20a8, 0x2011, 0x9780, 0x2019, 0x9700, 0x220c,
- 0x2304, 0xa106, 0x1188, 0x8210, 0x8318, 0x1f04, 0x3b6f, 0x6043,
- 0x0004, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x707f,
- 0x0002, 0x708b, 0x0002, 0x04c0, 0x2069, 0x9780, 0x6930, 0xa18e,
- 0x1101, 0x1538, 0x6834, 0xa005, 0x1520, 0x6900, 0xa18c, 0x00ff,
- 0x1118, 0x6804, 0xa005, 0x0190, 0x2011, 0x978e, 0x2019, 0x9205,
- 0x20a9, 0x0004, 0x220c, 0x2304, 0xa102, 0x0230, 0x1190, 0x8210,
- 0x8318, 0x1f04, 0x3b9a, 0x0068, 0x7093, 0x0000, 0x20e1, 0x9080,
- 0x20e1, 0x4000, 0x2099, 0x9780, 0x20a1, 0x020b, 0x20a9, 0x0014,
- 0x53a6, 0x6043, 0x0008, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x1120,
- 0x60c3, 0x000c, 0x080c, 0x40ec, 0x00de, 0x0005, 0x6040, 0xa085,
- 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x60c3, 0x000c, 0x2011,
- 0x94ef, 0x2013, 0x0000, 0x7083, 0x0000, 0x20e1, 0x9080, 0x60a3,
- 0x0056, 0x60a7, 0x9575, 0x080c, 0x6f15, 0x0c30, 0x0005, 0x7088,
- 0xa08a, 0x001d, 0x1210, 0x0023, 0x0010, 0x080c, 0x13fe, 0x0005,
- 0x3c0a, 0x3c19, 0x3c43, 0x3c58, 0x3c7e, 0x3ca6, 0x3ccc, 0x3cfd,
- 0x3d23, 0x3d4b, 0x3d86, 0x3dae, 0x3dca, 0x3de0, 0x3e00, 0x3e13,
- 0x3e1b, 0x3e45, 0x3e6b, 0x3e93, 0x3eb9, 0x3eea, 0x3f25, 0x3f54,
- 0x3f70, 0x3faf, 0x3fcf, 0x3fe8, 0x3fe9, 0x00c6, 0x2061, 0x9200,
- 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9, 0x6006,
- 0x00ce, 0x0005, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0002,
- 0x708b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x40af, 0x080c, 0x5725,
- 0x0005, 0x00f6, 0x7080, 0xa086, 0x0014, 0x1518, 0x6043, 0x0000,
- 0x6020, 0xd0b4, 0x11f0, 0x2079, 0x9780, 0x7a30, 0xa296, 0x1102,
- 0x11b0, 0x7834, 0xa005, 0x1198, 0x7a38, 0xd2fc, 0x0138, 0x70b0,
- 0xa005, 0x1120, 0x080c, 0x419d, 0x70b3, 0x0001, 0x2011, 0x40af,
- 0x080c, 0x5731, 0x708b, 0x0010, 0x080c, 0x3e1b, 0x0010, 0x7083,
- 0x0000, 0x00fe, 0x0005, 0x708b, 0x0003, 0x6043, 0x0004, 0x080c,
- 0x416e, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9, 0x000a, 0x20a3,
- 0x0000, 0x1f04, 0x3c4f, 0x60c3, 0x0014, 0x080c, 0x40ec, 0x0005,
- 0x00f6, 0x7080, 0xa005, 0x0500, 0x2011, 0x40af, 0x080c, 0x5731,
- 0xa086, 0x0014, 0x11b8, 0x2079, 0x9780, 0x7a30, 0xa296, 0x1102,
- 0x1188, 0x7834, 0xa005, 0x1170, 0x7a38, 0xd2fc, 0x0138, 0x70b0,
- 0xa005, 0x1120, 0x080c, 0x419d, 0x70b3, 0x0001, 0x708b, 0x0004,
- 0x0029, 0x0010, 0x080c, 0x41b6, 0x00fe, 0x0005, 0x708b, 0x0005,
- 0x080c, 0x416e, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011,
- 0x978e, 0x080c, 0x41bd, 0x1160, 0x7074, 0xa005, 0x1148, 0x714c,
- 0xa186, 0xffff, 0x0128, 0x080c, 0x4074, 0x0110, 0x080c, 0x419d,
- 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3,
- 0x0000, 0x60c3, 0x0014, 0x080c, 0x40ec, 0x0005, 0x00f6, 0x7080,
- 0xa005, 0x0500, 0x2011, 0x40af, 0x080c, 0x5731, 0xa086, 0x0014,
- 0x11b8, 0x2079, 0x9780, 0x7a30, 0xa296, 0x1103, 0x1188, 0x7834,
- 0xa005, 0x1170, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120,
- 0x080c, 0x419d, 0x70b3, 0x0001, 0x708b, 0x0006, 0x0029, 0x0010,
- 0x080c, 0x41b6, 0x00fe, 0x0005, 0x708b, 0x0007, 0x080c, 0x416e,
- 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0x978e, 0x080c,
- 0x41bd, 0x11a8, 0x7074, 0xa005, 0x1190, 0x7154, 0xa186, 0xffff,
- 0x0170, 0xa180, 0x2719, 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c,
- 0x4074, 0x0128, 0x080c, 0x3919, 0x0110, 0x080c, 0x2455, 0x20a9,
- 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
- 0x60c3, 0x0014, 0x080c, 0x40ec, 0x0005, 0x00f6, 0x7080, 0xa005,
- 0x0500, 0x2011, 0x40af, 0x080c, 0x5731, 0xa086, 0x0014, 0x11b8,
- 0x2079, 0x9780, 0x7a30, 0xa296, 0x1104, 0x1188, 0x7834, 0xa005,
- 0x1170, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c,
- 0x419d, 0x70b3, 0x0001, 0x708b, 0x0008, 0x0029, 0x0010, 0x080c,
- 0x41b6, 0x00fe, 0x0005, 0x708b, 0x0009, 0x080c, 0x416e, 0x20a3,
- 0x1105, 0x20a3, 0x0100, 0x3430, 0x080c, 0x41bd, 0x1150, 0x7074,
- 0xa005, 0x1138, 0x080c, 0x3fea, 0x1170, 0xa085, 0x0001, 0x080c,
- 0x2455, 0x20a9, 0x0008, 0x2099, 0x978e, 0x26a0, 0x53a6, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x40ec, 0x0010,
- 0x080c, 0x3bfd, 0x0005, 0x00f6, 0x7080, 0xa005, 0x05a8, 0x2011,
- 0x40af, 0x080c, 0x5731, 0xa086, 0x0014, 0x1560, 0x2079, 0x9780,
- 0x7a30, 0xa296, 0x1105, 0x1530, 0x7834, 0x2011, 0x0100, 0xa21e,
+ 0x0a04, 0x284b, 0xa182, 0x00ff, 0x1a04, 0x284b, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x7bbb, 0x1188, 0xa190, 0x8c34, 0x2204, 0xa065,
+ 0x0160, 0x080c, 0x4118, 0x2001, 0x8b32, 0x2004, 0xd0ac, 0x0110,
+ 0x6017, 0x0000, 0x012e, 0x0804, 0x2823, 0x012e, 0x0804, 0x2848,
+ 0x080c, 0x1488, 0x0188, 0xa006, 0x6802, 0x7010, 0xa005, 0x1120,
+ 0x2d00, 0x7012, 0x7016, 0x0030, 0x7014, 0x6802, 0x2060, 0x2d00,
+ 0x6006, 0x7016, 0xad80, 0x000d, 0x0005, 0x7924, 0x810f, 0xa18c,
+ 0x00ff, 0x080c, 0x430a, 0x1130, 0x7e28, 0xa684, 0x3fff, 0xa082,
+ 0x4000, 0x0208, 0xa066, 0x8cff, 0x0005, 0x7e24, 0x860f, 0xa18c,
+ 0x00ff, 0x080c, 0x430a, 0x1128, 0xa6b4, 0x00ff, 0xa682, 0x4000,
+ 0x0208, 0xa066, 0x8cff, 0x0005, 0x0016, 0x7110, 0x81ff, 0x0128,
+ 0x2168, 0x6904, 0x080c, 0x149f, 0x0cc8, 0x7112, 0x7116, 0x001e,
+ 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x8bd1,
+ 0x6606, 0x6112, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10,
+ 0x080c, 0x14d3, 0x7007, 0x0002, 0x701b, 0x2823, 0x0005, 0x00f6,
+ 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x8b8f, 0x2004,
+ 0xa005, 0x1168, 0x0e04, 0x362f, 0x7818, 0xd084, 0x1140, 0x7a22,
+ 0x7b26, 0x7c2a, 0x781b, 0x0001, 0x2091, 0x4080, 0x0408, 0x0016,
+ 0x00c6, 0x00e6, 0x2071, 0x8b81, 0x7138, 0xa182, 0x0010, 0x0218,
+ 0x7030, 0x2060, 0x0078, 0x7030, 0xa0e0, 0x0004, 0xac82, 0x8bd1,
+ 0x0210, 0x2061, 0x8b91, 0x2c00, 0x7032, 0x81ff, 0x1108, 0x7036,
+ 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, 0x001e,
+ 0x012e, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x8b81, 0x7038, 0xa005,
+ 0x0570, 0x0126, 0x2091, 0x8000, 0x0e04, 0x3686, 0x00f6, 0x2079,
+ 0x0000, 0x7818, 0xd084, 0x1508, 0x00c6, 0x7034, 0x2060, 0x2c04,
+ 0x7822, 0x6004, 0x7826, 0x6008, 0x782a, 0x781b, 0x0001, 0x2091,
+ 0x4080, 0x7038, 0x8001, 0x703a, 0xa005, 0x1130, 0x7033, 0x8b91,
+ 0x7037, 0x8b91, 0x00ce, 0x0048, 0xac80, 0x0004, 0xa0fa, 0x8bd1,
+ 0x0210, 0x2001, 0x8b91, 0x7036, 0x00ce, 0x00fe, 0x012e, 0x00ee,
+ 0x0005, 0x0026, 0x2001, 0x8b52, 0x2004, 0xd0c4, 0x0120, 0x2011,
+ 0x8014, 0x080c, 0x3617, 0x002e, 0x0005, 0x81ff, 0x1904, 0x2848,
+ 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, 0x6032, 0x080c, 0x4c42,
+ 0x1158, 0x2001, 0x8d9d, 0x2003, 0x0001, 0x2001, 0x8b00, 0x2003,
+ 0x0001, 0x080c, 0x4b8b, 0x0010, 0x080c, 0x403d, 0x012e, 0x0804,
+ 0x2823, 0x7824, 0x2008, 0xa18c, 0xfffd, 0x1128, 0x61d4, 0xa10d,
+ 0x61d6, 0x0804, 0x2823, 0x0804, 0x284b, 0x81ff, 0x1904, 0x2848,
+ 0x6000, 0xa086, 0x0003, 0x1904, 0x2848, 0x2001, 0x8b52, 0x2004,
+ 0xd0a4, 0x1904, 0x2848, 0x080c, 0x35e5, 0x0904, 0x284b, 0x6004,
+ 0xa084, 0x00ff, 0xa086, 0x0006, 0x1120, 0x7828, 0xa005, 0x0904,
+ 0x2823, 0x00c6, 0x080c, 0x35c0, 0x00ce, 0x0904, 0x2848, 0x6837,
+ 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x7d78,
+ 0x0904, 0x2848, 0x7007, 0x0003, 0x701b, 0x36ef, 0x0005, 0x6830,
+ 0xa086, 0x0100, 0x0904, 0x2848, 0x0804, 0x2823, 0x2001, 0x8b00,
+ 0x2004, 0xa086, 0x0003, 0x1904, 0x2848, 0x7f24, 0x7a2c, 0x7b28,
+ 0x7c3c, 0x7d38, 0x080c, 0x35c0, 0x0904, 0x2848, 0x2009, 0x0000,
+ 0x2031, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80, 0x0005,
+ 0x7026, 0x20a0, 0x080c, 0x430a, 0x1560, 0x6004, 0xa0c4, 0x00ff,
+ 0xa8c6, 0x0006, 0x0128, 0xa0c4, 0xff00, 0xa8c6, 0x0600, 0x1508,
+ 0x2001, 0x8b52, 0x2004, 0xd0ac, 0x1118, 0x080c, 0x457e, 0x01c8,
+ 0xd784, 0x0150, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9, 0x0004,
+ 0x53a3, 0x080c, 0x345e, 0x0048, 0xac80, 0x000a, 0x2098, 0x3400,
+ 0x20a9, 0x0004, 0x53a3, 0x080c, 0x345e, 0x21a2, 0x94a0, 0xa6b0,
+ 0x0005, 0x8108, 0x2001, 0x8b32, 0x2004, 0xd0ac, 0x0118, 0xa186,
+ 0x0100, 0x0040, 0xd78c, 0x0120, 0xa186, 0x0100, 0x0148, 0x0018,
+ 0xa186, 0x007e, 0x0128, 0xa686, 0x0028, 0x0150, 0x0804, 0x3712,
+ 0x86ff, 0x1120, 0x7120, 0x810b, 0x0804, 0x2823, 0x702f, 0x0001,
+ 0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0x8bd1, 0x6007,
+ 0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532,
+ 0x2c10, 0x080c, 0x14d3, 0x7007, 0x0002, 0x701b, 0x3778, 0x0005,
+ 0x702c, 0xa005, 0x1170, 0x711c, 0x7024, 0x20a0, 0x7728, 0x2031,
+ 0x0000, 0x2061, 0x8bd1, 0x6224, 0x6328, 0x642c, 0x6530, 0x0804,
+ 0x3712, 0x7120, 0x810b, 0x0804, 0x2823, 0x2029, 0x007e, 0x7924,
+ 0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020,
+ 0x0a04, 0x284b, 0xa502, 0x0a04, 0x284b, 0xa184, 0x00ff, 0xa0e2,
+ 0x0020, 0x0a04, 0x284b, 0xa502, 0x0a04, 0x284b, 0xa284, 0xff00,
+ 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x284b, 0xa502, 0x0a04, 0x284b,
+ 0xa284, 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x284b, 0xa502, 0x0a04,
+ 0x284b, 0xa384, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x284b,
+ 0xa502, 0x0a04, 0x284b, 0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0a04,
+ 0x284b, 0xa502, 0x0a04, 0x284b, 0xa484, 0xff00, 0x8007, 0xa0e2,
+ 0x0020, 0x0a04, 0x284b, 0xa502, 0x0a04, 0x284b, 0xa484, 0x00ff,
+ 0xa0e2, 0x0020, 0x0a04, 0x284b, 0xa502, 0x0a04, 0x284b, 0x2061,
+ 0x8da4, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x2823, 0x0006,
+ 0x2001, 0x8b52, 0x2004, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x2001,
+ 0x8b71, 0x2004, 0xd0bc, 0x000e, 0x0005, 0x6164, 0x7a24, 0x6300,
+ 0x82ff, 0x1118, 0x7926, 0x0804, 0x2823, 0x83ff, 0x1904, 0x284b,
+ 0x2001, 0xfff0, 0xa200, 0x1a04, 0x284b, 0x2019, 0xffff, 0x6068,
+ 0xa302, 0xa200, 0x0a04, 0x284b, 0x7926, 0x6266, 0x0804, 0x2823,
+ 0x2001, 0x8b00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2848, 0x7c28,
+ 0x7d24, 0x7e38, 0x7f2c, 0x080c, 0x35c0, 0x0904, 0x2848, 0x2009,
+ 0x0000, 0x2019, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80,
+ 0x0003, 0x7026, 0x20a0, 0xa1e0, 0x8c34, 0x2c64, 0x8cff, 0x01b8,
+ 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0130, 0x6004, 0xa084,
+ 0xff00, 0xa086, 0x0600, 0x1158, 0x6014, 0x20a2, 0x94a0, 0x6010,
+ 0x8007, 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108,
+ 0xa182, 0x00ff, 0x0120, 0xa386, 0x002a, 0x0148, 0x08e0, 0x83ff,
+ 0x1120, 0x7120, 0x810c, 0x0804, 0x2823, 0x702f, 0x0001, 0x711e,
+ 0x7020, 0xa300, 0x7022, 0x2061, 0x8bd1, 0x6007, 0x0000, 0x6312,
+ 0x7024, 0x600e, 0x6426, 0x652a, 0x662e, 0x6732, 0x2c10, 0x080c,
+ 0x14d3, 0x7007, 0x0002, 0x701b, 0x386e, 0x0005, 0x702c, 0xa005,
+ 0x1158, 0x711c, 0x7024, 0x20a0, 0x2019, 0x0000, 0x6424, 0x6528,
+ 0x662c, 0x6730, 0x0804, 0x382b, 0x7120, 0x810c, 0x0804, 0x2823,
+ 0x81ff, 0x1904, 0x2848, 0x60c8, 0xd0ac, 0x1118, 0xd09c, 0x0904,
+ 0x2848, 0x080c, 0x35c0, 0x0904, 0x2848, 0x7924, 0x7a2c, 0x7b28,
+ 0x7c3c, 0x7d38, 0x080c, 0x3601, 0x701b, 0x3897, 0x0005, 0x00d6,
+ 0xade8, 0x000d, 0x6828, 0xa0be, 0x7000, 0x0148, 0xa0be, 0x7100,
+ 0x0130, 0xa0be, 0x7200, 0x0118, 0x00de, 0x0804, 0x284b, 0x6820,
+ 0x6924, 0x080c, 0x22e9, 0x1500, 0x080c, 0x42d6, 0x11e8, 0x7122,
+ 0x6612, 0x6516, 0x6e18, 0x00c6, 0x080c, 0x35c0, 0x01a8, 0x080c,
+ 0x35c0, 0x0190, 0x00ce, 0x00de, 0x6837, 0x0000, 0x6838, 0xc0fd,
+ 0x683a, 0x6823, 0x0000, 0x080c, 0x7cfd, 0x0904, 0x2848, 0x7007,
+ 0x0003, 0x701b, 0x38cf, 0x0005, 0x00de, 0x0804, 0x2848, 0x7120,
+ 0x080c, 0x42f5, 0x6820, 0xa086, 0x8001, 0x0904, 0x2848, 0x2d00,
+ 0x701e, 0x6804, 0xa080, 0x0002, 0x0006, 0x20a9, 0x002a, 0x2098,
+ 0x20a0, 0x080c, 0x409e, 0x000e, 0xade8, 0x000d, 0x6a08, 0x6b0c,
+ 0x6c10, 0x6d14, 0x2061, 0x8bd1, 0x6007, 0x0000, 0x6e00, 0x6f28,
+ 0xa7c6, 0x7000, 0x1108, 0x0018, 0xa7c6, 0x7100, 0x1140, 0xa6c2,
+ 0x0004, 0x0a04, 0x284b, 0x2009, 0x0004, 0x0804, 0x3604, 0xa7c6,
+ 0x7200, 0x1904, 0x284b, 0xa6c2, 0x0054, 0x0a04, 0x284b, 0x600e,
+ 0x6013, 0x002a, 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x080c,
+ 0x14d3, 0x7007, 0x0002, 0x701b, 0x3916, 0x0005, 0x701c, 0x2068,
+ 0x6804, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x0006, 0x20a9,
+ 0x002a, 0x2098, 0x20a0, 0x080c, 0x409e, 0x000e, 0x2009, 0x002a,
+ 0x2061, 0x8bd1, 0x6224, 0x6328, 0x642c, 0x6530, 0x0804, 0x3604,
+ 0x81ff, 0x1904, 0x2848, 0x080c, 0x35d5, 0x0904, 0x284b, 0x080c,
+ 0x43ad, 0x0904, 0x2848, 0x080c, 0x44dd, 0x0804, 0x2823, 0x7824,
+ 0xd084, 0x0904, 0x31d9, 0x080c, 0x35e5, 0x0904, 0x284b, 0x00c6,
+ 0x080c, 0x35c0, 0x00ce, 0x0904, 0x2848, 0x6004, 0xa084, 0x00ff,
+ 0xa086, 0x0006, 0x11f0, 0x2001, 0x8b52, 0x2004, 0xd0b4, 0x0904,
+ 0x3206, 0x6000, 0xd08c, 0x1904, 0x3206, 0x6837, 0x0000, 0x6838,
+ 0xc0fd, 0x683a, 0x080c, 0x7d17, 0x0904, 0x2848, 0x7007, 0x0003,
+ 0x701b, 0x396b, 0x0005, 0x080c, 0x35e5, 0x0904, 0x284b, 0x0804,
+ 0x3206, 0x2009, 0x8b2f, 0x210c, 0x81ff, 0x1904, 0x2848, 0x2001,
+ 0x8b00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2848, 0x2001, 0x8b52,
+ 0x2004, 0xd0ac, 0x1904, 0x2848, 0x6837, 0x0000, 0x6833, 0x0000,
+ 0x6838, 0xc0fd, 0x683a, 0x080c, 0x7d78, 0x0904, 0x2848, 0x7007,
+ 0x0003, 0x701b, 0x3994, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904,
+ 0x2848, 0x080c, 0x35e5, 0x0904, 0x284b, 0x0804, 0x3953, 0x0126,
+ 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x8b00, 0x6044, 0xd0a4,
+ 0x11b0, 0xd084, 0x0118, 0x080c, 0x3b0c, 0x0068, 0xd08c, 0x0118,
+ 0x080c, 0x3a2d, 0x0040, 0xd094, 0x0118, 0x080c, 0x3a05, 0x0018,
+ 0xd09c, 0x0108, 0x0061, 0x00ee, 0x00ce, 0x012e, 0x0005, 0x0016,
+ 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0ca0, 0x624c,
+ 0xa286, 0xf0f0, 0x1150, 0x6048, 0xa086, 0xf0f0, 0x0130, 0x624a,
+ 0x6043, 0x0090, 0x6043, 0x0010, 0x0478, 0xa294, 0xff00, 0xa296,
+ 0xf700, 0x0160, 0x6240, 0xa295, 0x0100, 0x6242, 0xa294, 0x0010,
+ 0x0128, 0x2009, 0x00f7, 0x080c, 0x40be, 0x00f0, 0x6040, 0xa084,
+ 0x0010, 0xa085, 0x0040, 0x6042, 0x6043, 0x0000, 0x7077, 0x0000,
+ 0x7093, 0x0001, 0x70b3, 0x0000, 0x70cb, 0x0000, 0x2009, 0x91c0,
+ 0x200b, 0x0000, 0x7087, 0x0000, 0x707b, 0x000f, 0x2009, 0x000f,
+ 0x2011, 0x3fe0, 0x080c, 0x568c, 0x0005, 0x0156, 0x7078, 0xa005,
+ 0x1510, 0x2011, 0x3fe0, 0x080c, 0x560d, 0x6040, 0xa094, 0x0010,
+ 0xa285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168,
+ 0x1f04, 0x3a15, 0x6242, 0x708b, 0x0000, 0x6040, 0xa094, 0x0010,
+ 0xa285, 0x0080, 0x6042, 0x6242, 0x0030, 0x6242, 0x708b, 0x0000,
+ 0x707f, 0x0000, 0x0000, 0x015e, 0x0005, 0x707c, 0xa08a, 0x0003,
+ 0x1210, 0x0023, 0x0010, 0x080c, 0x1410, 0x0005, 0x3a39, 0x3a89,
+ 0x3b0b, 0x00f6, 0x707f, 0x0001, 0x20e1, 0xa000, 0xe000, 0x20e1,
+ 0x8700, 0x080c, 0x1fbd, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2079,
+ 0x9000, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000, 0x780f,
+ 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, 0x0000, 0x781f,
+ 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, 0x0000, 0x782f,
+ 0x0000, 0x2079, 0x900c, 0x207b, 0x1101, 0x7807, 0x0000, 0x2099,
+ 0x8b05, 0x20a1, 0x900e, 0x20a9, 0x0004, 0x53a3, 0x2079, 0x9012,
+ 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0x9000, 0x20a1, 0x020b,
+ 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000, 0x080c,
+ 0x4024, 0x00fe, 0x7083, 0x0000, 0x6043, 0x0008, 0x6043, 0x0000,
+ 0x0005, 0x00d6, 0x7080, 0x7083, 0x0000, 0xa025, 0x0904, 0x3af3,
+ 0x6020, 0xd0b4, 0x1904, 0x3af1, 0x7190, 0x81ff, 0x0904, 0x3adb,
+ 0xa486, 0x000c, 0x1904, 0x3ae6, 0xa480, 0x0018, 0x8004, 0x20a8,
+ 0x2011, 0x9080, 0x2019, 0x9000, 0x220c, 0x2304, 0xa106, 0x1188,
+ 0x8210, 0x8318, 0x1f04, 0x3aa4, 0x6043, 0x0004, 0x608b, 0xbc94,
+ 0x608f, 0xf0f0, 0x6043, 0x0006, 0x707f, 0x0002, 0x708b, 0x0002,
+ 0x04c0, 0x2069, 0x9080, 0x6930, 0xa18e, 0x1101, 0x1538, 0x6834,
+ 0xa005, 0x1520, 0x6900, 0xa18c, 0x00ff, 0x1118, 0x6804, 0xa005,
+ 0x0190, 0x2011, 0x908e, 0x2019, 0x8b05, 0x20a9, 0x0004, 0x220c,
+ 0x2304, 0xa102, 0x0230, 0x1190, 0x8210, 0x8318, 0x1f04, 0x3acf,
+ 0x0068, 0x7093, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
+ 0x9080, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, 0x0008,
+ 0x6043, 0x0000, 0x6020, 0xd0b4, 0x1120, 0x60c3, 0x000c, 0x080c,
+ 0x4024, 0x00de, 0x0005, 0x6040, 0xa085, 0x0100, 0x6042, 0x6020,
+ 0xd0b4, 0x1db8, 0x60c3, 0x000c, 0x2011, 0x8db4, 0x2013, 0x0000,
+ 0x7083, 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575,
+ 0x080c, 0x66ee, 0x0c30, 0x0005, 0x7088, 0xa08a, 0x001d, 0x1210,
+ 0x0023, 0x0010, 0x080c, 0x1410, 0x0005, 0x3b3f, 0x3b4e, 0x3b78,
+ 0x3b8d, 0x3bb3, 0x3bdb, 0x3c01, 0x3c32, 0x3c58, 0x3c80, 0x3cbb,
+ 0x3ce3, 0x3cff, 0x3d15, 0x3d35, 0x3d48, 0x3d50, 0x3d7a, 0x3da0,
+ 0x3dc8, 0x3dee, 0x3e1f, 0x3e5b, 0x3e8a, 0x3ea6, 0x3ee5, 0x3f05,
+ 0x3f1e, 0x3f1f, 0x00c6, 0x2061, 0x8b00, 0x6003, 0x0007, 0x2061,
+ 0x0100, 0x6004, 0xa084, 0xfff9, 0x6006, 0x00ce, 0x0005, 0x608b,
+ 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0002, 0x708b, 0x0001, 0x2009,
+ 0x07d0, 0x2011, 0x3fe7, 0x080c, 0x5601, 0x0005, 0x00f6, 0x7080,
+ 0xa086, 0x0014, 0x1518, 0x6043, 0x0000, 0x6020, 0xd0b4, 0x11f0,
+ 0x2079, 0x9080, 0x7a30, 0xa296, 0x1102, 0x11b0, 0x7834, 0xa005,
+ 0x1198, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c,
+ 0x40d5, 0x70b3, 0x0001, 0x2011, 0x3fe7, 0x080c, 0x560d, 0x708b,
+ 0x0010, 0x080c, 0x3d50, 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005,
+ 0x708b, 0x0003, 0x6043, 0x0004, 0x080c, 0x40a6, 0x20a3, 0x1102,
+ 0x20a3, 0x0000, 0x20a9, 0x000a, 0x20a3, 0x0000, 0x1f04, 0x3b84,
+ 0x60c3, 0x0014, 0x080c, 0x4024, 0x0005, 0x00f6, 0x7080, 0xa005,
+ 0x0500, 0x2011, 0x3fe7, 0x080c, 0x560d, 0xa086, 0x0014, 0x11b8,
+ 0x2079, 0x9080, 0x7a30, 0xa296, 0x1102, 0x1188, 0x7834, 0xa005,
0x1170, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c,
- 0x419d, 0x70b3, 0x0001, 0x708b, 0x000a, 0x00c1, 0x00a8, 0xa005,
- 0x1188, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c,
- 0x419d, 0x70b3, 0x0001, 0x7087, 0x0000, 0x708b, 0x000e, 0x080c,
- 0x3e00, 0x0010, 0x080c, 0x41b6, 0x00fe, 0x0005, 0x708b, 0x000b,
- 0x2011, 0x970e, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4,
- 0x20a9, 0x0002, 0x2009, 0x0000, 0x41a4, 0x080c, 0x416e, 0x20a3,
- 0x1106, 0x20a3, 0x0000, 0x080c, 0x41bd, 0x0118, 0x2013, 0x0000,
- 0x0020, 0x7050, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042,
- 0x53a6, 0x60c3, 0x0084, 0x080c, 0x40ec, 0x0005, 0x00f6, 0x7080,
- 0xa005, 0x01b0, 0x2011, 0x40af, 0x080c, 0x5731, 0xa086, 0x0084,
- 0x1168, 0x2079, 0x9780, 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834,
- 0xa005, 0x1120, 0x708b, 0x000c, 0x0029, 0x0010, 0x080c, 0x41b6,
- 0x00fe, 0x0005, 0x708b, 0x000d, 0x080c, 0x416e, 0x20a3, 0x1107,
- 0x20a3, 0x0000, 0x2099, 0x978e, 0x20a9, 0x0040, 0x53a6, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x40ec, 0x0005,
- 0x00f6, 0x7080, 0xa005, 0x01d0, 0x2011, 0x40af, 0x080c, 0x5731,
- 0xa086, 0x0084, 0x1188, 0x2079, 0x9780, 0x7a30, 0xa296, 0x1107,
- 0x1158, 0x7834, 0xa005, 0x1140, 0x7087, 0x0001, 0x080c, 0x4160,
- 0x708b, 0x000e, 0x0029, 0x0010, 0x080c, 0x41b6, 0x00fe, 0x0005,
- 0x708b, 0x000f, 0x7083, 0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5,
- 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x40af,
- 0x080c, 0x5725, 0x0005, 0x7080, 0xa005, 0x0120, 0x2011, 0x40af,
- 0x080c, 0x5731, 0x0005, 0x708b, 0x0011, 0x716c, 0x81ff, 0x0170,
- 0x2009, 0x0000, 0x7070, 0xa084, 0x00ff, 0x080c, 0x240b, 0xa186,
- 0x0080, 0x0120, 0x2011, 0x978e, 0x080c, 0x4074, 0x20e1, 0x9080,
- 0x20e1, 0x4000, 0x2099, 0x9780, 0x20a1, 0x020b, 0x7480, 0xa480,
- 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6,
- 0x60c3, 0x0014, 0x080c, 0x40ec, 0x0005, 0x00f6, 0x7080, 0xa005,
- 0x0500, 0x2011, 0x40af, 0x080c, 0x5731, 0xa086, 0x0014, 0x11b8,
- 0x2079, 0x9780, 0x7a30, 0xa296, 0x1103, 0x1188, 0x7834, 0xa005,
- 0x1170, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c,
- 0x419d, 0x70b3, 0x0001, 0x708b, 0x0012, 0x0029, 0x0010, 0x7083,
- 0x0000, 0x00fe, 0x0005, 0x708b, 0x0013, 0x080c, 0x417a, 0x20a3,
- 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0x978e, 0x080c, 0x41bd,
+ 0x40d5, 0x70b3, 0x0001, 0x708b, 0x0004, 0x0029, 0x0010, 0x080c,
+ 0x40ee, 0x00fe, 0x0005, 0x708b, 0x0005, 0x080c, 0x40a6, 0x20a3,
+ 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0x908e, 0x080c, 0x40f5,
0x1160, 0x7074, 0xa005, 0x1148, 0x714c, 0xa186, 0xffff, 0x0128,
- 0x080c, 0x4074, 0x0110, 0x080c, 0x419d, 0x20a9, 0x0008, 0x2298,
+ 0x080c, 0x3fab, 0x0110, 0x080c, 0x40d5, 0x20a9, 0x0008, 0x2298,
0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
- 0x080c, 0x40ec, 0x0005, 0x00f6, 0x7080, 0xa005, 0x0500, 0x2011,
- 0x40af, 0x080c, 0x5731, 0xa086, 0x0014, 0x11b8, 0x2079, 0x9780,
- 0x7a30, 0xa296, 0x1104, 0x1188, 0x7834, 0xa005, 0x1170, 0x7a38,
- 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, 0x419d, 0x70b3,
- 0x0001, 0x708b, 0x0014, 0x0029, 0x0010, 0x7083, 0x0000, 0x00fe,
- 0x0005, 0x708b, 0x0015, 0x080c, 0x417a, 0x20a3, 0x1104, 0x20a3,
- 0x0000, 0x3430, 0x2011, 0x978e, 0x080c, 0x41bd, 0x11a8, 0x7074,
- 0xa005, 0x1190, 0x7154, 0xa186, 0xffff, 0x0170, 0xa180, 0x2719,
- 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x4074, 0x0128, 0x080c,
- 0x3919, 0x0110, 0x080c, 0x2455, 0x20a9, 0x0008, 0x2298, 0x26a0,
+ 0x080c, 0x4024, 0x0005, 0x00f6, 0x7080, 0xa005, 0x0500, 0x2011,
+ 0x3fe7, 0x080c, 0x560d, 0xa086, 0x0014, 0x11b8, 0x2079, 0x9080,
+ 0x7a30, 0xa296, 0x1103, 0x1188, 0x7834, 0xa005, 0x1170, 0x7a38,
+ 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, 0x40d5, 0x70b3,
+ 0x0001, 0x708b, 0x0006, 0x0029, 0x0010, 0x080c, 0x40ee, 0x00fe,
+ 0x0005, 0x708b, 0x0007, 0x080c, 0x40a6, 0x20a3, 0x1104, 0x20a3,
+ 0x0000, 0x3430, 0x2011, 0x908e, 0x080c, 0x40f5, 0x11a8, 0x7074,
+ 0xa005, 0x1190, 0x7154, 0xa186, 0xffff, 0x0170, 0xa180, 0x263d,
+ 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x3fab, 0x0128, 0x080c,
+ 0x37ee, 0x0110, 0x080c, 0x2333, 0x20a9, 0x0008, 0x2298, 0x26a0,
0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c,
- 0x40ec, 0x0005, 0x00f6, 0x7080, 0xa005, 0x05a8, 0x2011, 0x40af,
- 0x080c, 0x5731, 0xa086, 0x0014, 0x1560, 0x2079, 0x9780, 0x7a30,
- 0xa296, 0x1105, 0x1530, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1178,
- 0x7a38, 0xd2f4, 0x0110, 0x70cb, 0x0008, 0xd2fc, 0x0138, 0x70b0,
- 0xa005, 0x1120, 0x080c, 0x419d, 0x70b3, 0x0001, 0x0070, 0xa005,
- 0x1180, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c,
- 0x419d, 0x70b3, 0x0001, 0x7087, 0x0000, 0x708b, 0x0016, 0x0029,
- 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005, 0x20e1, 0x9080, 0x20e1,
- 0x4000, 0x2099, 0x9780, 0x20a1, 0x020b, 0x20a9, 0x000e, 0x53a6,
- 0x3430, 0x2011, 0x978e, 0x708b, 0x0017, 0x080c, 0x41bd, 0x1150,
- 0x7074, 0xa005, 0x1138, 0x080c, 0x3fea, 0x1170, 0xa085, 0x0001,
- 0x080c, 0x2455, 0x20a9, 0x0008, 0x2099, 0x978e, 0x26a0, 0x53a6,
- 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x40ec,
- 0x0010, 0x080c, 0x3bfd, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01b0,
- 0x2011, 0x40af, 0x080c, 0x5731, 0xa086, 0x0084, 0x1168, 0x2079,
- 0x9780, 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834, 0xa005, 0x1120,
- 0x708b, 0x0018, 0x0029, 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005,
- 0x708b, 0x0019, 0x080c, 0x417a, 0x20a3, 0x1106, 0x20a3, 0x0000,
- 0x3430, 0x2099, 0x978e, 0x2039, 0x970e, 0x27a0, 0x20a9, 0x0040,
- 0x53a3, 0x080c, 0x41bd, 0x11e8, 0x2728, 0x2514, 0x8207, 0xa084,
- 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007, 0xa205, 0x202a,
- 0x7050, 0x2310, 0x8214, 0xa2a0, 0x970e, 0x2414, 0xa38c, 0x0001,
- 0x0118, 0xa294, 0xff00, 0x0018, 0xa294, 0x00ff, 0x8007, 0xa215,
- 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000,
- 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x40ec, 0x0005, 0x00f6,
- 0x7080, 0xa005, 0x01d0, 0x2011, 0x40af, 0x080c, 0x5731, 0xa086,
- 0x0084, 0x1188, 0x2079, 0x9780, 0x7a30, 0xa296, 0x1107, 0x1158,
- 0x7834, 0xa005, 0x1140, 0x7087, 0x0001, 0x080c, 0x4160, 0x708b,
- 0x001a, 0x0029, 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005, 0x708b,
- 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x9780, 0x20a1,
- 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8,
- 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x080c, 0x40ec, 0x0005,
- 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0x9252, 0x252c, 0x20a9,
- 0x0008, 0x2041, 0x970e, 0x28a0, 0x2099, 0x978e, 0x53a3, 0x20a9,
- 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0110, 0x2011, 0x0000, 0x2800,
- 0xa200, 0x200c, 0xa1a6, 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210,
- 0x0008, 0x8211, 0x1f04, 0x3fff, 0x0804, 0x406c, 0x82ff, 0x1160,
- 0xd5d4, 0x0120, 0xa1a6, 0x3fff, 0x0d90, 0x0020, 0xa1a6, 0x3fff,
- 0x0904, 0x406c, 0xa18d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001,
- 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423,
- 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318,
- 0x1f04, 0x4025, 0x04c8, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425,
- 0x1f04, 0x4037, 0x2328, 0x8529, 0xa2be, 0x0007, 0x0158, 0x0006,
- 0x2039, 0x0007, 0x2200, 0xa73a, 0x000e, 0x27a8, 0xa5a8, 0x0010,
- 0x1f04, 0x4046, 0x754e, 0xa5c8, 0x2719, 0x292d, 0xa5ac, 0x00ff,
- 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x2435, 0x001e, 0x60e7,
- 0x0000, 0x65ea, 0x2018, 0x2304, 0xa405, 0x201a, 0x7077, 0x0001,
- 0x26a0, 0x2898, 0x20a9, 0x0008, 0x53a6, 0x20a3, 0x0000, 0x20a3,
- 0x0000, 0xa085, 0x0001, 0x0028, 0xa006, 0x0018, 0xa006, 0x080c,
- 0x13fe, 0x009e, 0x008e, 0x0005, 0x2118, 0x2021, 0x0000, 0x2001,
- 0x0007, 0xa39a, 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118,
- 0x84ff, 0x0120, 0xa39a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001,
- 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8, 0xa238, 0x2704, 0xa42c,
- 0x11b0, 0xa405, 0x203a, 0x714e, 0xa1a0, 0x2719, 0x242d, 0xa5ac,
- 0x00ff, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x2435, 0x001e,
+ 0x4024, 0x0005, 0x00f6, 0x7080, 0xa005, 0x0500, 0x2011, 0x3fe7,
+ 0x080c, 0x560d, 0xa086, 0x0014, 0x11b8, 0x2079, 0x9080, 0x7a30,
+ 0xa296, 0x1104, 0x1188, 0x7834, 0xa005, 0x1170, 0x7a38, 0xd2fc,
+ 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, 0x40d5, 0x70b3, 0x0001,
+ 0x708b, 0x0008, 0x0029, 0x0010, 0x080c, 0x40ee, 0x00fe, 0x0005,
+ 0x708b, 0x0009, 0x080c, 0x40a6, 0x20a3, 0x1105, 0x20a3, 0x0100,
+ 0x3430, 0x080c, 0x40f5, 0x1150, 0x7074, 0xa005, 0x1138, 0x080c,
+ 0x3f20, 0x1170, 0xa085, 0x0001, 0x080c, 0x2333, 0x20a9, 0x0008,
+ 0x2099, 0x908e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x60c3, 0x0014, 0x080c, 0x4024, 0x0010, 0x080c, 0x3b32, 0x0005,
+ 0x00f6, 0x7080, 0xa005, 0x05a8, 0x2011, 0x3fe7, 0x080c, 0x560d,
+ 0xa086, 0x0014, 0x1560, 0x2079, 0x9080, 0x7a30, 0xa296, 0x1105,
+ 0x1530, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1170, 0x7a38, 0xd2fc,
+ 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, 0x40d5, 0x70b3, 0x0001,
+ 0x708b, 0x000a, 0x00c1, 0x00a8, 0xa005, 0x1188, 0x7a38, 0xd2fc,
+ 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, 0x40d5, 0x70b3, 0x0001,
+ 0x7087, 0x0000, 0x708b, 0x000e, 0x080c, 0x3d35, 0x0010, 0x080c,
+ 0x40ee, 0x00fe, 0x0005, 0x708b, 0x000b, 0x2011, 0x900e, 0x22a0,
+ 0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009,
+ 0x0000, 0x41a4, 0x080c, 0x40a6, 0x20a3, 0x1106, 0x20a3, 0x0000,
+ 0x080c, 0x40f5, 0x0118, 0x2013, 0x0000, 0x0020, 0x7050, 0xa085,
+ 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6, 0x60c3, 0x0084,
+ 0x080c, 0x4024, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01b0, 0x2011,
+ 0x3fe7, 0x080c, 0x560d, 0xa086, 0x0084, 0x1168, 0x2079, 0x9080,
+ 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834, 0xa005, 0x1120, 0x708b,
+ 0x000c, 0x0029, 0x0010, 0x080c, 0x40ee, 0x00fe, 0x0005, 0x708b,
+ 0x000d, 0x080c, 0x40a6, 0x20a3, 0x1107, 0x20a3, 0x0000, 0x2099,
+ 0x908e, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x60c3, 0x0084, 0x080c, 0x4024, 0x0005, 0x00f6, 0x7080, 0xa005,
+ 0x01d0, 0x2011, 0x3fe7, 0x080c, 0x560d, 0xa086, 0x0084, 0x1188,
+ 0x2079, 0x9080, 0x7a30, 0xa296, 0x1107, 0x1158, 0x7834, 0xa005,
+ 0x1140, 0x7087, 0x0001, 0x080c, 0x4098, 0x708b, 0x000e, 0x0029,
+ 0x0010, 0x080c, 0x40ee, 0x00fe, 0x0005, 0x708b, 0x000f, 0x7083,
+ 0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5, 0x6043, 0x0005, 0x6043,
+ 0x0004, 0x2009, 0x07d0, 0x2011, 0x3fe7, 0x080c, 0x5601, 0x0005,
+ 0x7080, 0xa005, 0x0120, 0x2011, 0x3fe7, 0x080c, 0x560d, 0x0005,
+ 0x708b, 0x0011, 0x716c, 0x81ff, 0x0170, 0x2009, 0x0000, 0x7070,
+ 0xa084, 0x00ff, 0x080c, 0x22e9, 0xa186, 0x0080, 0x0120, 0x2011,
+ 0x908e, 0x080c, 0x3fab, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
+ 0x9080, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007,
+ 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, 0x080c,
+ 0x4024, 0x0005, 0x00f6, 0x7080, 0xa005, 0x0500, 0x2011, 0x3fe7,
+ 0x080c, 0x560d, 0xa086, 0x0014, 0x11b8, 0x2079, 0x9080, 0x7a30,
+ 0xa296, 0x1103, 0x1188, 0x7834, 0xa005, 0x1170, 0x7a38, 0xd2fc,
+ 0x0138, 0x70b0, 0xa005, 0x1120, 0x080c, 0x40d5, 0x70b3, 0x0001,
+ 0x708b, 0x0012, 0x0029, 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005,
+ 0x708b, 0x0013, 0x080c, 0x40b2, 0x20a3, 0x1103, 0x20a3, 0x0000,
+ 0x3430, 0x2011, 0x908e, 0x080c, 0x40f5, 0x1160, 0x7074, 0xa005,
+ 0x1148, 0x714c, 0xa186, 0xffff, 0x0128, 0x080c, 0x3fab, 0x0110,
+ 0x080c, 0x40d5, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4024, 0x0005,
+ 0x00f6, 0x7080, 0xa005, 0x0500, 0x2011, 0x3fe7, 0x080c, 0x560d,
+ 0xa086, 0x0014, 0x11b8, 0x2079, 0x9080, 0x7a30, 0xa296, 0x1104,
+ 0x1188, 0x7834, 0xa005, 0x1170, 0x7a38, 0xd2fc, 0x0138, 0x70b0,
+ 0xa005, 0x1120, 0x080c, 0x40d5, 0x70b3, 0x0001, 0x708b, 0x0014,
+ 0x0029, 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005, 0x708b, 0x0015,
+ 0x080c, 0x40b2, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011,
+ 0x908e, 0x080c, 0x40f5, 0x11a8, 0x7074, 0xa005, 0x1190, 0x7154,
+ 0xa186, 0xffff, 0x0170, 0xa180, 0x263d, 0x200d, 0xa18c, 0xff00,
+ 0x810f, 0x080c, 0x3fab, 0x0128, 0x080c, 0x37ee, 0x0110, 0x080c,
+ 0x2333, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4024, 0x0005, 0x00f6,
+ 0x7080, 0xa005, 0x05b0, 0x2011, 0x3fe7, 0x080c, 0x560d, 0xa086,
+ 0x0014, 0x1568, 0x2079, 0x9080, 0x7a30, 0xa296, 0x1105, 0x1538,
+ 0x7834, 0x2011, 0x0100, 0xa21e, 0x1158, 0x7a38, 0xd2fc, 0x0138,
+ 0x70b0, 0xa005, 0x1120, 0x080c, 0x40d5, 0x70b3, 0x0001, 0x0070,
+ 0xa005, 0x11a8, 0x7a38, 0xd2fc, 0x0138, 0x70b0, 0xa005, 0x1120,
+ 0x080c, 0x40d5, 0x70b3, 0x0001, 0x7087, 0x0000, 0x7a38, 0xd2f4,
+ 0x0110, 0x70cb, 0x0008, 0x708b, 0x0016, 0x0029, 0x0010, 0x7083,
+ 0x0000, 0x00fe, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
+ 0x9080, 0x20a1, 0x020b, 0x20a9, 0x000e, 0x53a6, 0x3430, 0x2011,
+ 0x908e, 0x708b, 0x0017, 0x080c, 0x40f5, 0x1150, 0x7074, 0xa005,
+ 0x1138, 0x080c, 0x3f20, 0x1170, 0xa085, 0x0001, 0x080c, 0x2333,
+ 0x20a9, 0x0008, 0x2099, 0x908e, 0x26a0, 0x53a6, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4024, 0x0010, 0x080c,
+ 0x3b32, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01b0, 0x2011, 0x3fe7,
+ 0x080c, 0x560d, 0xa086, 0x0084, 0x1168, 0x2079, 0x9080, 0x7a30,
+ 0xa296, 0x1106, 0x1138, 0x7834, 0xa005, 0x1120, 0x708b, 0x0018,
+ 0x0029, 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005, 0x708b, 0x0019,
+ 0x080c, 0x40b2, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x3430, 0x2099,
+ 0x908e, 0x2039, 0x900e, 0x27a0, 0x20a9, 0x0040, 0x53a3, 0x080c,
+ 0x40f5, 0x11e8, 0x2728, 0x2514, 0x8207, 0xa084, 0x00ff, 0x8000,
+ 0x2018, 0xa294, 0x00ff, 0x8007, 0xa205, 0x202a, 0x7050, 0x2310,
+ 0x8214, 0xa2a0, 0x900e, 0x2414, 0xa38c, 0x0001, 0x0118, 0xa294,
+ 0xff00, 0x0018, 0xa294, 0x00ff, 0x8007, 0xa215, 0x2222, 0x2798,
+ 0x26a0, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x60c3, 0x0084, 0x080c, 0x4024, 0x0005, 0x00f6, 0x7080, 0xa005,
+ 0x01d0, 0x2011, 0x3fe7, 0x080c, 0x560d, 0xa086, 0x0084, 0x1188,
+ 0x2079, 0x9080, 0x7a30, 0xa296, 0x1107, 0x1158, 0x7834, 0xa005,
+ 0x1140, 0x7087, 0x0001, 0x080c, 0x4098, 0x708b, 0x001a, 0x0029,
+ 0x0010, 0x7083, 0x0000, 0x00fe, 0x0005, 0x708b, 0x001b, 0x20e1,
+ 0x9080, 0x20e1, 0x4000, 0x2099, 0x9080, 0x20a1, 0x020b, 0x7480,
+ 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8,
+ 0x53a6, 0x60c3, 0x0084, 0x080c, 0x4024, 0x0005, 0x0005, 0x0005,
+ 0x0086, 0x0096, 0x2029, 0x8b52, 0x252c, 0x20a9, 0x0008, 0x2041,
+ 0x900e, 0x28a0, 0x2099, 0x908e, 0x53a3, 0x20a9, 0x0008, 0x2011,
+ 0x0007, 0xd5d4, 0x0110, 0x2011, 0x0000, 0x2800, 0xa200, 0x200c,
+ 0xa1a6, 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211,
+ 0x1f04, 0x3f35, 0x0804, 0x3fa3, 0x82ff, 0x1160, 0xd5d4, 0x0120,
+ 0xa1a6, 0x3fff, 0x0d90, 0x0020, 0xa1a6, 0x3fff, 0x0904, 0x3fa3,
+ 0xa18d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110,
+ 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424,
+ 0x1240, 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x3f5b,
+ 0x04d0, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x3f6d,
+ 0x2328, 0x8529, 0xa2be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007,
+ 0x2200, 0xa73a, 0x000e, 0x27a8, 0xa5a8, 0x0010, 0x1f04, 0x3f7c,
+ 0x754e, 0xa5c8, 0x263d, 0x292d, 0xa5ac, 0x00ff, 0x7572, 0x6532,
+ 0x6536, 0x0016, 0x2508, 0x080c, 0x2313, 0x001e, 0x60e7, 0x0000,
+ 0x65ea, 0x2018, 0x2304, 0xa405, 0x201a, 0x7077, 0x0001, 0x26a0,
+ 0x2898, 0x20a9, 0x0008, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0xa085, 0x0001, 0x0028, 0xa006, 0x0018, 0xa006, 0x080c, 0x1410,
+ 0x009e, 0x008e, 0x0005, 0x2118, 0x2021, 0x0000, 0x2001, 0x0007,
+ 0xa39a, 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff,
+ 0x0120, 0xa39a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff,
+ 0x0118, 0x8423, 0x8319, 0x1de8, 0xa238, 0x2704, 0xa42c, 0x11b8,
+ 0xa405, 0x203a, 0x714e, 0xa1a0, 0x263d, 0x242d, 0xa5ac, 0x00ff,
+ 0x7572, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x2313, 0x001e,
0x60e7, 0x0000, 0x65ea, 0x7077, 0x0001, 0xa084, 0x0000, 0x0005,
- 0x00e6, 0x2071, 0x9200, 0x707b, 0x0000, 0x00ee, 0x0005, 0x00e6,
- 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x6f1e, 0x7004,
+ 0x00e6, 0x2071, 0x8b00, 0x707b, 0x0000, 0x00ee, 0x0005, 0x00e6,
+ 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x66f7, 0x7004,
0xa084, 0x4000, 0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x080c,
- 0x4dcd, 0x01b0, 0x080c, 0x4deb, 0x1198, 0x2001, 0x94d7, 0x2003,
- 0xaaaa, 0x2001, 0x0204, 0x2004, 0x0016, 0x2009, 0x94c8, 0x200a,
- 0x001e, 0x2001, 0x94d8, 0x2003, 0x0000, 0x080c, 0x4d10, 0x0080,
- 0x0126, 0x2091, 0x8000, 0x2071, 0x9222, 0x2073, 0x0000, 0x7840,
+ 0x4c4a, 0x01b0, 0x080c, 0x4c68, 0x1198, 0x2001, 0x8d9c, 0x2003,
+ 0xaaaa, 0x2001, 0x0204, 0x2004, 0x0016, 0x2009, 0x8d8d, 0x200a,
+ 0x001e, 0x2001, 0x8d9d, 0x2003, 0x0000, 0x080c, 0x4b8b, 0x0080,
+ 0x0126, 0x2091, 0x8000, 0x2071, 0x8b22, 0x2073, 0x0000, 0x7840,
0x0026, 0xa094, 0x0010, 0xa285, 0x0080, 0x7842, 0x7a42, 0x002e,
0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x2011,
- 0x94ef, 0x2013, 0x0000, 0x7083, 0x0000, 0x012e, 0x20e1, 0x9080,
- 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x6f15, 0x2009, 0x07d0,
- 0x2011, 0x40af, 0x080c, 0x57b3, 0x0005, 0x0016, 0x0026, 0x00c6,
- 0x0126, 0x2091, 0x8000, 0x2009, 0x00f7, 0x080c, 0x4186, 0x2061,
- 0x94f8, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0x9200, 0x6003,
+ 0x8db4, 0x2013, 0x0000, 0x7083, 0x0000, 0x012e, 0x20e1, 0x9080,
+ 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x66ee, 0x2009, 0x07d0,
+ 0x2011, 0x3fe7, 0x080c, 0x568c, 0x0005, 0x0016, 0x0026, 0x00c6,
+ 0x0126, 0x2091, 0x8000, 0x2009, 0x00f7, 0x080c, 0x40be, 0x2061,
+ 0x8dbd, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0x8b00, 0x6003,
0x0001, 0x2061, 0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009,
- 0x001e, 0x2011, 0x412a, 0x080c, 0x5725, 0x012e, 0x00ce, 0x002e,
+ 0x001e, 0x2011, 0x4062, 0x080c, 0x5601, 0x012e, 0x00ce, 0x002e,
0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071,
- 0x0100, 0x080c, 0x6f1e, 0x2071, 0x0140, 0x7004, 0xa084, 0x4000,
- 0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x080c, 0x4dcd, 0x01b0,
- 0x080c, 0x4deb, 0x1198, 0x2001, 0x94d7, 0x2003, 0xaaaa, 0x2001,
- 0x0204, 0x2004, 0x0016, 0x2009, 0x94c8, 0x200a, 0x001e, 0x2001,
- 0x94d8, 0x2003, 0x0000, 0x080c, 0x4d10, 0x0030, 0x2001, 0x0001,
- 0x080c, 0x23ba, 0x080c, 0x4105, 0x012e, 0x000e, 0x00ee, 0x0005,
- 0x20a9, 0x0040, 0x20a1, 0x98c0, 0x2099, 0x978e, 0x3304, 0x8007,
- 0x20a2, 0x9398, 0x94a0, 0x1f04, 0x4166, 0x0005, 0x20e1, 0x9080,
- 0x20e1, 0x4000, 0x2099, 0x9700, 0x20a1, 0x020b, 0x20a9, 0x000c,
- 0x53a6, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x9780,
+ 0x0100, 0x080c, 0x66f7, 0x2071, 0x0140, 0x7004, 0xa084, 0x4000,
+ 0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x080c, 0x4c4a, 0x01b0,
+ 0x080c, 0x4c68, 0x1198, 0x2001, 0x8d9c, 0x2003, 0xaaaa, 0x2001,
+ 0x0204, 0x2004, 0x0016, 0x2009, 0x8d8d, 0x200a, 0x001e, 0x2001,
+ 0x8d9d, 0x2003, 0x0000, 0x080c, 0x4b8b, 0x0030, 0x2001, 0x0001,
+ 0x080c, 0x2298, 0x080c, 0x403d, 0x012e, 0x000e, 0x00ee, 0x0005,
+ 0x20a9, 0x0040, 0x20a1, 0x91c0, 0x2099, 0x908e, 0x3304, 0x8007,
+ 0x20a2, 0x9398, 0x94a0, 0x1f04, 0x409e, 0x0005, 0x20e1, 0x9080,
+ 0x20e1, 0x4000, 0x2099, 0x9000, 0x20a1, 0x020b, 0x20a9, 0x000c,
+ 0x53a6, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0x9080,
0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x0005, 0x00c6, 0x0006,
- 0x2061, 0x0100, 0x810f, 0x2001, 0x922f, 0x2004, 0xa005, 0x1138,
- 0x2001, 0x9214, 0x2004, 0xa084, 0x00ff, 0xa105, 0x0010, 0xa185,
+ 0x2061, 0x0100, 0x810f, 0x2001, 0x8b2f, 0x2004, 0xa005, 0x1138,
+ 0x2001, 0x8b14, 0x2004, 0xa084, 0x00ff, 0xa105, 0x0010, 0xa185,
0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x2001,
- 0x9252, 0x2004, 0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a,
- 0x080c, 0x90d7, 0x2001, 0x920c, 0x200c, 0xc195, 0x2102, 0x2019,
- 0x002a, 0x080c, 0x264b, 0x004e, 0x001e, 0x0005, 0x080c, 0x4105,
- 0x708b, 0x0000, 0x7083, 0x0000, 0x0005, 0x0006, 0x2001, 0x920c,
+ 0x8b52, 0x2004, 0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a,
+ 0x080c, 0x8982, 0x2001, 0x8b0c, 0x200c, 0xc195, 0x2102, 0x2019,
+ 0x002a, 0x080c, 0x2542, 0x004e, 0x001e, 0x0005, 0x080c, 0x403d,
+ 0x708b, 0x0000, 0x7083, 0x0000, 0x0005, 0x0006, 0x2001, 0x8b0c,
0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126,
0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0xa18d, 0x0006, 0x2102,
0x012e, 0x001e, 0x000e, 0x0005, 0x0156, 0x20a9, 0x00ff, 0x2009,
- 0x936e, 0xa006, 0x200a, 0x8108, 0x1f04, 0x41da, 0x015e, 0x0005,
- 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x9251, 0xa006,
- 0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012, 0xa198, 0x2719,
+ 0x8c34, 0xa006, 0x200a, 0x8108, 0x1f04, 0x4112, 0x015e, 0x0005,
+ 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x8b51, 0xa006,
+ 0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012, 0xa198, 0x263d,
0x231d, 0xa39c, 0x00ff, 0x6316, 0x20a9, 0x0004, 0xac98, 0x0006,
0x23a0, 0x40a4, 0x20a9, 0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4,
0x603e, 0x6042, 0x604e, 0x6052, 0x6056, 0x605a, 0x605e, 0x6062,
0x6066, 0x606a, 0x606e, 0x6072, 0x6076, 0x607a, 0x607e, 0x6082,
0x6086, 0x608a, 0x608e, 0x6092, 0x6096, 0x609a, 0x609e, 0x61a2,
- 0x00d6, 0x60a4, 0xa06d, 0x0110, 0x080c, 0x1493, 0x60a7, 0x0000,
- 0x60a8, 0xa06d, 0x0110, 0x080c, 0x1493, 0x60ab, 0x0000, 0x00de,
- 0xa006, 0x604a, 0x6810, 0x603a, 0x680c, 0x6046, 0xa006, 0x60b2,
- 0x60ae, 0x60b6, 0x60bb, 0x0520, 0x6814, 0xa084, 0x00ff, 0x6042,
- 0x014e, 0x013e, 0x015e, 0x003e, 0x00de, 0x0005, 0x0126, 0x2091,
- 0x8000, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082, 0x4000, 0x1a04,
- 0x42cf, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, 0x1a04, 0x42d4,
- 0x2001, 0x920c, 0x2004, 0xa084, 0x0003, 0x1904, 0x42bd, 0xa188,
- 0x936e, 0x2104, 0xa065, 0x0904, 0x42a9, 0x6004, 0xa084, 0x00ff,
- 0xa08e, 0x0006, 0x1904, 0x42ae, 0x60a4, 0xa00d, 0x0118, 0x080c,
- 0x4630, 0x05d0, 0x60a8, 0xa00d, 0x0188, 0x080c, 0x467a, 0x1170,
- 0x694c, 0xd1fc, 0x1118, 0x080c, 0x43c4, 0x0448, 0x080c, 0x4386,
- 0x694c, 0xd1ec, 0x1520, 0x080c, 0x452b, 0x0408, 0x694c, 0xa184,
- 0xa000, 0x0178, 0xd1ec, 0x0140, 0xd1fc, 0x0118, 0x080c, 0x453a,
- 0x0028, 0x080c, 0x453a, 0x0028, 0xd1fc, 0x0118, 0x080c, 0x4386,
- 0x0070, 0x6050, 0xa00d, 0x0130, 0x2d00, 0x200a, 0x6803, 0x0000,
- 0x6052, 0x0028, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x080c,
- 0x6015, 0xa006, 0x012e, 0x0005, 0x2001, 0x0005, 0x2009, 0x0000,
- 0x0478, 0x2001, 0x0028, 0x2009, 0x0000, 0x0450, 0xa082, 0x0006,
- 0x1260, 0x2001, 0x9232, 0x2004, 0xd0ac, 0x1120, 0x60a0, 0xd0bc,
- 0x0904, 0x4264, 0x2001, 0x0028, 0x0078, 0x2009, 0x920c, 0x210c,
- 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001,
- 0x0004, 0x0010, 0x2001, 0x0029, 0x2009, 0x0000, 0x0048, 0x2001,
- 0x0029, 0x2009, 0x0000, 0x0020, 0x2001, 0x0029, 0x2009, 0x0000,
- 0xa005, 0x012e, 0x0005, 0x00e6, 0x0126, 0x2091, 0x8000, 0x6844,
- 0x0006, 0x000e, 0x0006, 0x000e, 0xa084, 0xff00, 0xa08e, 0xff00,
- 0x1120, 0x2001, 0x94c6, 0x2064, 0x0098, 0x6844, 0x8007, 0xa084,
- 0x00ff, 0x2008, 0xa182, 0x00ff, 0x16c8, 0xa188, 0x936e, 0x2104,
- 0xa065, 0x01f0, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x11d8,
- 0x2c70, 0x080c, 0x749c, 0x0580, 0x2e00, 0x601a, 0x2d00, 0x6012,
- 0x601f, 0x0009, 0x600b, 0x0000, 0x6844, 0xa08e, 0xff00, 0x1110,
- 0x600b, 0x8000, 0x2009, 0x0100, 0x080c, 0x7518, 0xa006, 0x00c8,
- 0x2001, 0x0028, 0x00a8, 0xa082, 0x0006, 0x0e10, 0x2009, 0x920c,
- 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118,
- 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029,
- 0xa005, 0x012e, 0x00ee, 0x0005, 0x2001, 0x002c, 0x0cc8, 0x6944,
- 0x6e48, 0xa684, 0x3fff, 0xa082, 0x4000, 0x1678, 0xa18c, 0xff00,
- 0x810f, 0xa182, 0x00ff, 0x12e0, 0xa188, 0x936e, 0x2104, 0xa065,
- 0x01b8, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x11b0, 0x684c,
- 0xd0ec, 0x0120, 0x080c, 0x453a, 0x0489, 0x0030, 0x0479, 0x684c,
- 0xd0fc, 0x0110, 0x080c, 0x452b, 0x080c, 0x4578, 0xa006, 0x0088,
- 0x2001, 0x0028, 0x2009, 0x0000, 0x0060, 0xa082, 0x0006, 0x0e38,
- 0x2001, 0x0029, 0x2009, 0x0000, 0x0020, 0x2001, 0x0029, 0x2009,
- 0x0000, 0xa005, 0x0005, 0x0126, 0x2091, 0x8000, 0x6050, 0xa00d,
- 0x0138, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x012e, 0x0005,
- 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0cc0, 0x0126, 0x2091,
- 0x8000, 0x604c, 0xa005, 0x0170, 0x00e6, 0x2071, 0x94e5, 0x7004,
- 0xa086, 0x0002, 0x0168, 0x00ee, 0x604c, 0x6802, 0x2d00, 0x604e,
- 0x012e, 0x0005, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0cc0,
- 0x701c, 0xac06, 0x1d80, 0x604c, 0x2070, 0x7000, 0x6802, 0x2d00,
- 0x7002, 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x604c,
- 0xa06d, 0x0130, 0x6800, 0xa005, 0x1108, 0x6052, 0x604e, 0xad05,
- 0x012e, 0x0005, 0x604c, 0xa06d, 0x0130, 0x6800, 0xa005, 0x1108,
- 0x6052, 0x604e, 0xad05, 0x0005, 0x6803, 0x0000, 0x6084, 0xa00d,
- 0x0120, 0x2d00, 0x200a, 0x6086, 0x0005, 0x2d00, 0x6086, 0x6082,
- 0x0cd8, 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6218, 0x2260,
- 0x6200, 0xa005, 0x0110, 0xc285, 0x0008, 0xc284, 0x6202, 0x002e,
- 0x00ce, 0x012e, 0x0005, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6218,
- 0x2260, 0x6204, 0xa294, 0xff00, 0xa215, 0x6206, 0x00ce, 0x012e,
+ 0x00d6, 0x60a4, 0xa06d, 0x0110, 0x080c, 0x149f, 0x60a7, 0x0000,
+ 0x60a8, 0xa06d, 0x0110, 0x080c, 0x149f, 0x60ab, 0x0000, 0x00de,
+ 0xa006, 0x604a, 0x6810, 0x603a, 0x680c, 0x6046, 0x6814, 0xa084,
+ 0x00ff, 0x6042, 0x014e, 0x013e, 0x015e, 0x003e, 0x00de, 0x0005,
+ 0x0126, 0x2091, 0x8000, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082,
+ 0x4000, 0x1a04, 0x4201, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+ 0x1a04, 0x4206, 0x2001, 0x8b0c, 0x2004, 0xa084, 0x0003, 0x1904,
+ 0x41ef, 0xa188, 0x8c34, 0x2104, 0xa065, 0x0904, 0x41db, 0x6004,
+ 0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904, 0x41e0, 0x60a4, 0xa00d,
+ 0x0118, 0x080c, 0x4509, 0x05d0, 0x60a8, 0xa00d, 0x0188, 0x080c,
+ 0x4553, 0x1170, 0x694c, 0xd1fc, 0x1118, 0x080c, 0x429a, 0x0448,
+ 0x080c, 0x425c, 0x694c, 0xd1ec, 0x1520, 0x080c, 0x4404, 0x0408,
+ 0x694c, 0xa184, 0xa000, 0x0178, 0xd1ec, 0x0140, 0xd1fc, 0x0118,
+ 0x080c, 0x4413, 0x0028, 0x080c, 0x4413, 0x0028, 0xd1fc, 0x0118,
+ 0x080c, 0x425c, 0x0070, 0x6050, 0xa00d, 0x0130, 0x2d00, 0x200a,
+ 0x6803, 0x0000, 0x6052, 0x0028, 0x2d00, 0x6052, 0x604e, 0x6803,
+ 0x0000, 0x080c, 0x58b9, 0xa006, 0x012e, 0x0005, 0x2001, 0x0005,
+ 0x2009, 0x0000, 0x0478, 0x2001, 0x0028, 0x2009, 0x0000, 0x0450,
+ 0xa082, 0x0006, 0x1260, 0x2001, 0x8b32, 0x2004, 0xd0ac, 0x1120,
+ 0x60a0, 0xd0bc, 0x0904, 0x4196, 0x2001, 0x0028, 0x0078, 0x2009,
+ 0x8b0c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184,
+ 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x2009, 0x0000,
+ 0x0048, 0x2001, 0x0029, 0x2009, 0x0000, 0x0020, 0x2001, 0x0029,
+ 0x2009, 0x0000, 0xa005, 0x012e, 0x0005, 0x6944, 0x6e48, 0xa684,
+ 0x3fff, 0xa082, 0x4000, 0x1678, 0xa18c, 0xff00, 0x810f, 0xa182,
+ 0x00ff, 0x12e0, 0xa188, 0x8c34, 0x2104, 0xa065, 0x01b8, 0x6004,
+ 0xa084, 0x00ff, 0xa08e, 0x0006, 0x11b0, 0x684c, 0xd0ec, 0x0120,
+ 0x080c, 0x4413, 0x0489, 0x0030, 0x0479, 0x684c, 0xd0fc, 0x0110,
+ 0x080c, 0x4404, 0x080c, 0x4451, 0xa006, 0x0088, 0x2001, 0x0028,
+ 0x2009, 0x0000, 0x0060, 0xa082, 0x0006, 0x0e38, 0x2001, 0x0029,
+ 0x2009, 0x0000, 0x0020, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005,
+ 0x0005, 0x0126, 0x2091, 0x8000, 0x6050, 0xa00d, 0x0138, 0x2d00,
+ 0x200a, 0x6803, 0x0000, 0x6052, 0x012e, 0x0005, 0x2d00, 0x6052,
+ 0x604e, 0x6803, 0x0000, 0x0cc0, 0x0126, 0x2091, 0x8000, 0x604c,
+ 0xa005, 0x0170, 0x00e6, 0x2071, 0x8daa, 0x7004, 0xa086, 0x0002,
+ 0x0168, 0x00ee, 0x604c, 0x6802, 0x2d00, 0x604e, 0x012e, 0x0005,
+ 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0cc0, 0x701c, 0xac06,
+ 0x1d80, 0x604c, 0x2070, 0x7000, 0x6802, 0x2d00, 0x7002, 0x00ee,
+ 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x604c, 0xa06d, 0x0130,
+ 0x6800, 0xa005, 0x1108, 0x6052, 0x604e, 0xad05, 0x012e, 0x0005,
+ 0x604c, 0xa06d, 0x0130, 0x6800, 0xa005, 0x1108, 0x6052, 0x604e,
+ 0xad05, 0x0005, 0x6803, 0x0000, 0x6084, 0xa00d, 0x0120, 0x2d00,
+ 0x200a, 0x6086, 0x0005, 0x2d00, 0x6086, 0x6082, 0x0cd8, 0x0126,
+ 0x00c6, 0x0026, 0x2091, 0x8000, 0x6218, 0x2260, 0x6200, 0xa005,
+ 0x0110, 0xc285, 0x0008, 0xc284, 0x6202, 0x002e, 0x00ce, 0x012e,
0x0005, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204,
- 0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x00ce, 0x012e, 0x0005,
- 0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x00b0, 0xa190,
- 0x936e, 0x2204, 0xa065, 0x1180, 0x0016, 0x00d6, 0x080c, 0x145f,
- 0x2d60, 0x00de, 0x001e, 0x0d80, 0x2c00, 0x2012, 0x60a7, 0x0000,
- 0x60ab, 0x0000, 0x080c, 0x41e0, 0xa006, 0x002e, 0x0005, 0x0026,
- 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x0060, 0x00d6, 0xa190,
- 0x936e, 0x2204, 0xa06d, 0x0120, 0x2013, 0x0000, 0x080c, 0x1493,
- 0x00de, 0xa006, 0x002e, 0x0005, 0x0016, 0xa182, 0x00ff, 0x0218,
- 0xa085, 0x0001, 0x0030, 0xa188, 0x936e, 0x2104, 0xa065, 0x0dc0,
- 0xa006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x600b,
- 0x0000, 0x600f, 0x0000, 0x6000, 0xc08c, 0x6002, 0x080c, 0x4dc5,
- 0x1520, 0x60a0, 0xa086, 0x007e, 0x2069, 0x9790, 0x0130, 0x2001,
- 0x9232, 0x2004, 0xd0ac, 0x11c8, 0x0098, 0x2d04, 0xd0e4, 0x01a8,
- 0x00d6, 0x2069, 0x978e, 0x00c6, 0x2061, 0x94d9, 0x6810, 0x2062,
- 0x6814, 0x6006, 0x6818, 0x600a, 0x681c, 0x600e, 0x00ce, 0x00de,
- 0x8d69, 0x2d04, 0x2069, 0x0140, 0x6886, 0x2069, 0x978e, 0x6808,
- 0x605e, 0x6810, 0x6062, 0x6138, 0xa10a, 0x0208, 0x603a, 0x6814,
- 0x6066, 0x2099, 0x9796, 0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004,
- 0x53a3, 0x2099, 0x979a, 0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004,
- 0x53a3, 0x2069, 0x97ae, 0x6808, 0x606a, 0x690c, 0x616e, 0x6810,
- 0x6072, 0x6818, 0x6076, 0xa182, 0x0211, 0x1218, 0x2009, 0x0008,
- 0x0400, 0xa182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0xa182,
- 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349, 0x1218,
- 0x2009, 0x0005, 0x0070, 0xa182, 0x0421, 0x1218, 0x2009, 0x0004,
- 0x0040, 0xa182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009,
- 0x0002, 0x6192, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x00e6,
- 0x2071, 0x978d, 0x2e04, 0x6896, 0x2071, 0x978e, 0x7004, 0x689a,
- 0x701c, 0x689e, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000,
- 0x60a4, 0xa06d, 0x01c0, 0x6900, 0x81ff, 0x1540, 0x6a04, 0xa282,
- 0x0010, 0x1648, 0xad88, 0x0004, 0x20a9, 0x0010, 0x2104, 0xa086,
- 0xffff, 0x0128, 0x8108, 0x1f04, 0x44e6, 0x080c, 0x13fe, 0x260a,
- 0x8210, 0x6a06, 0x0098, 0x080c, 0x145f, 0x01a8, 0x2d00, 0x60a6,
- 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff,
- 0x8108, 0x1f04, 0x44fe, 0x6807, 0x0001, 0x6e12, 0xa085, 0x0001,
- 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x0126, 0x2091, 0x8000,
- 0x00d6, 0x60a4, 0xa00d, 0x01a0, 0x2168, 0x6800, 0xa005, 0x1160,
- 0x080c, 0x4630, 0x1168, 0x200b, 0xffff, 0x6804, 0xa08a, 0x0002,
- 0x0218, 0x8001, 0x6806, 0x0020, 0x080c, 0x1493, 0x60a7, 0x0000,
- 0x00de, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x468d,
- 0x0010, 0x080c, 0x4373, 0x080c, 0x45af, 0x1dd8, 0x080c, 0x4578,
- 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a8, 0xa06d,
- 0x01c0, 0x6950, 0x81ff, 0x1540, 0x6a54, 0xa282, 0x0010, 0x1670,
- 0xad88, 0x0018, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0128,
- 0x8108, 0x1f04, 0x454c, 0x080c, 0x13fe, 0x260a, 0x8210, 0x6a56,
- 0x0098, 0x080c, 0x145f, 0x01d0, 0x2d00, 0x60aa, 0x6853, 0x0000,
- 0xad88, 0x0018, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x1f04,
- 0x4564, 0x6857, 0x0001, 0x6e62, 0x0010, 0x080c, 0x43c4, 0x0089,
- 0x1de0, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8,
- 0x0126, 0x2091, 0x8000, 0x080c, 0x6015, 0x012e, 0x0005, 0xa01e,
- 0x0010, 0x2019, 0x0001, 0xa00e, 0x0126, 0x2091, 0x8000, 0x604c,
- 0x2068, 0x6000, 0xd0dc, 0x1170, 0x8dff, 0x01e8, 0x83ff, 0x0120,
- 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406, 0x1118, 0x6840,
- 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70, 0x6a00, 0x604c,
- 0xad06, 0x1110, 0x624e, 0x0018, 0xa180, 0x0000, 0x2202, 0x82ff,
- 0x1110, 0x6152, 0x8dff, 0x012e, 0x0005, 0xa01e, 0x0010, 0x2019,
- 0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x01e8, 0x83ff, 0x0120,
- 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406, 0x1118, 0x6840,
- 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70, 0x6a00, 0x6080,
- 0xad06, 0x1110, 0x6282, 0x0018, 0xa180, 0x0000, 0x2202, 0x82ff,
- 0x1110, 0x6186, 0x8dff, 0x0005, 0xa016, 0x080c, 0x462a, 0x1110,
- 0x2011, 0x0001, 0x080c, 0x4674, 0x1110, 0xa295, 0x0002, 0x0005,
- 0x080c, 0x46a5, 0x0118, 0x080c, 0x83ab, 0x0010, 0xa085, 0x0001,
- 0x0005, 0x080c, 0x46a5, 0x0118, 0x080c, 0x8338, 0x0010, 0xa085,
- 0x0001, 0x0005, 0x080c, 0x46a5, 0x0118, 0x080c, 0x837e, 0x0010,
- 0xa085, 0x0001, 0x0005, 0x080c, 0x46a5, 0x0118, 0x080c, 0x8352,
- 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x46a5, 0x0118, 0x080c,
- 0x83d8, 0x0010, 0xa085, 0x0001, 0x0005, 0x0126, 0x0006, 0x00d6,
- 0x2091, 0x8000, 0x6080, 0xa06d, 0x0168, 0x6800, 0x0006, 0x6837,
- 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x8527, 0x080c, 0x4809,
- 0x000e, 0x0c88, 0x6083, 0x0000, 0x6087, 0x0000, 0x00de, 0x000e,
- 0x012e, 0x0005, 0x60a4, 0xa00d, 0x1118, 0xa085, 0x0001, 0x0005,
- 0x00e6, 0x2170, 0x7000, 0xa005, 0x1160, 0x20a9, 0x0010, 0xae88,
- 0x0004, 0x2104, 0xa606, 0x0128, 0x8108, 0x1f04, 0x4639, 0xa085,
- 0x0001, 0xa006, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000,
- 0x60a4, 0xa06d, 0x1128, 0x080c, 0x145f, 0x01a0, 0x2d00, 0x60a6,
- 0x6803, 0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010,
- 0x200b, 0xffff, 0x8108, 0x1f04, 0x4658, 0xa085, 0x0001, 0x012e,
- 0x00de, 0x0005, 0xa006, 0x0cd8, 0x00d6, 0x0126, 0x2091, 0x8000,
- 0x60a4, 0xa06d, 0x0130, 0x60a7, 0x0000, 0x080c, 0x1493, 0xa085,
- 0x0001, 0x012e, 0x00de, 0x0005, 0x60a8, 0xa00d, 0x1118, 0xa085,
- 0x0001, 0x0005, 0x00e6, 0x2170, 0x7050, 0xa005, 0x1160, 0x20a9,
- 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0128, 0x8108, 0x1f04,
- 0x4683, 0xa085, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
- 0x0c19, 0x1188, 0x200b, 0xffff, 0x00d6, 0x60a8, 0x2068, 0x6854,
- 0xa08a, 0x0002, 0x0218, 0x8001, 0x6856, 0x0020, 0x080c, 0x1493,
- 0x60ab, 0x0000, 0x00de, 0x012e, 0x0005, 0x609c, 0xd0a4, 0x0005,
- 0x00f6, 0x2079, 0x9251, 0x7804, 0xd0a4, 0x0518, 0x0156, 0x00c6,
- 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4434, 0x1168,
- 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004, 0x0118, 0xa086,
- 0x0006, 0x1118, 0x6000, 0xc0ed, 0x6002, 0x001e, 0x8108, 0x1f04,
- 0x46b4, 0x00ce, 0x015e, 0x2009, 0x07d0, 0x2011, 0x46d3, 0x080c,
- 0x57b3, 0x00fe, 0x0005, 0x2011, 0x46d3, 0x080c, 0x5731, 0x0156,
- 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4434,
- 0x1530, 0x6000, 0xd0ec, 0x0518, 0x0046, 0x62a0, 0xa294, 0x00ff,
- 0x8227, 0xa006, 0x2009, 0x0029, 0x080c, 0x90d7, 0x6000, 0xc0e5,
- 0xc0ec, 0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700, 0x6006,
- 0x2019, 0x0029, 0x080c, 0x6127, 0x0086, 0x2041, 0x0000, 0x080c,
- 0x606d, 0x2009, 0x0000, 0x080c, 0x8ee4, 0x008e, 0x004e, 0x001e,
- 0x8108, 0x1f04, 0x46dd, 0x00ce, 0x015e, 0x0005, 0x00c6, 0x6018,
- 0x2060, 0x6000, 0xc0ec, 0x6002, 0x00ce, 0x0005, 0x00c6, 0x00d6,
- 0x080c, 0x145f, 0x2d60, 0x090c, 0x13fe, 0x2009, 0x00ff, 0x080c,
- 0x41e0, 0x6007, 0x0006, 0x6013, 0x00ff, 0x6017, 0xffff, 0x606f,
- 0x0200, 0x606c, 0x6093, 0x0002, 0x60bb, 0x0520, 0x60a3, 0x00ff,
- 0x60b7, 0x0000, 0x60af, 0x0000, 0x2c08, 0x2001, 0x94c6, 0x2102,
- 0x00de, 0x00ce, 0x0005, 0x0156, 0x00e6, 0x00d6, 0x00c6, 0x20a9,
- 0x00ff, 0x2009, 0x0000, 0x0016, 0x080c, 0x4434, 0x1138, 0x2c70,
- 0x70ac, 0xa005, 0x0118, 0x2060, 0x080c, 0x5cf4, 0x001e, 0x8108,
- 0x1f04, 0x4743, 0x00ce, 0x00de, 0x00ee, 0x015e, 0x0005, 0x2071,
- 0x9328, 0x7003, 0x0001, 0x7007, 0x0000, 0x7013, 0x0000, 0x7017,
+ 0xa294, 0xff00, 0xa215, 0x6206, 0x00ce, 0x012e, 0x0005, 0x0126,
+ 0x00c6, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204, 0xa294, 0x00ff,
+ 0x8007, 0xa215, 0x6206, 0x00ce, 0x012e, 0x0005, 0x0026, 0xa182,
+ 0x00ff, 0x0218, 0xa085, 0x0001, 0x00b0, 0xa190, 0x8c34, 0x2204,
+ 0xa065, 0x1180, 0x0016, 0x00d6, 0x080c, 0x146f, 0x2d60, 0x00de,
+ 0x001e, 0x0d80, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab, 0x0000,
+ 0x080c, 0x4118, 0xa006, 0x002e, 0x0005, 0x0026, 0xa182, 0x00ff,
+ 0x0218, 0xa085, 0x0001, 0x0060, 0x00d6, 0xa190, 0x8c34, 0x2204,
+ 0xa06d, 0x0120, 0x2013, 0x0000, 0x080c, 0x149f, 0x00de, 0xa006,
+ 0x002e, 0x0005, 0x0016, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001,
+ 0x0030, 0xa188, 0x8c34, 0x2104, 0xa065, 0x0dc0, 0xa006, 0x001e,
+ 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x600b, 0x0000, 0x600f,
+ 0x0000, 0x6000, 0xc08c, 0x6002, 0x080c, 0x4c42, 0x1538, 0x60a0,
+ 0xa086, 0x007e, 0x2069, 0x9090, 0x0130, 0x2001, 0x8b32, 0x2004,
+ 0xd0ac, 0x11e0, 0x0098, 0x2d04, 0xd0e4, 0x01c0, 0x00d6, 0x2069,
+ 0x908e, 0x00c6, 0x2061, 0x8d9e, 0x6810, 0x2062, 0x6814, 0x6006,
+ 0x6818, 0x600a, 0x681c, 0x600e, 0x00ce, 0x00de, 0x8d69, 0x2d04,
+ 0x2069, 0x0140, 0x6886, 0x2069, 0x8b00, 0x689e, 0x2069, 0x908e,
+ 0x6808, 0x605e, 0x6810, 0x6062, 0x6138, 0xa10a, 0x0208, 0x603a,
+ 0x6814, 0x6066, 0x2099, 0x9096, 0xac88, 0x000a, 0x21a0, 0x20a9,
+ 0x0004, 0x53a3, 0x2099, 0x909a, 0xac88, 0x0006, 0x21a0, 0x20a9,
+ 0x0004, 0x53a3, 0x2069, 0x90ae, 0x6808, 0x606a, 0x690c, 0x616e,
+ 0x6810, 0x6072, 0x6818, 0x6076, 0xa182, 0x0211, 0x1218, 0x2009,
+ 0x0008, 0x0400, 0xa182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0,
+ 0xa182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349,
+ 0x1218, 0x2009, 0x0005, 0x0070, 0xa182, 0x0421, 0x1218, 0x2009,
+ 0x0004, 0x0040, 0xa182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010,
+ 0x2009, 0x0002, 0x6192, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005,
+ 0x00e6, 0x2071, 0x908d, 0x2e04, 0x6896, 0x2071, 0x908e, 0x7004,
+ 0x689a, 0x701c, 0x689e, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091,
+ 0x8000, 0x60a4, 0xa06d, 0x01c0, 0x6900, 0x81ff, 0x1540, 0x6a04,
+ 0xa282, 0x0010, 0x1648, 0xad88, 0x0004, 0x20a9, 0x0010, 0x2104,
+ 0xa086, 0xffff, 0x0128, 0x8108, 0x1f04, 0x43bf, 0x080c, 0x1410,
+ 0x260a, 0x8210, 0x6a06, 0x0098, 0x080c, 0x1488, 0x01a8, 0x2d00,
+ 0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b,
+ 0xffff, 0x8108, 0x1f04, 0x43d7, 0x6807, 0x0001, 0x6e12, 0xa085,
+ 0x0001, 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x0126, 0x2091,
+ 0x8000, 0x00d6, 0x60a4, 0xa00d, 0x01a0, 0x2168, 0x6800, 0xa005,
+ 0x1160, 0x080c, 0x4509, 0x1168, 0x200b, 0xffff, 0x6804, 0xa08a,
+ 0x0002, 0x0218, 0x8001, 0x6806, 0x0020, 0x080c, 0x149f, 0x60a7,
+ 0x0000, 0x00de, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x4566, 0x0010, 0x080c, 0x4249, 0x080c, 0x4488, 0x1dd8, 0x080c,
+ 0x4451, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a8,
+ 0xa06d, 0x01c0, 0x6950, 0x81ff, 0x1540, 0x6a54, 0xa282, 0x0010,
+ 0x1670, 0xad88, 0x0018, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff,
+ 0x0128, 0x8108, 0x1f04, 0x4425, 0x080c, 0x1410, 0x260a, 0x8210,
+ 0x6a56, 0x0098, 0x080c, 0x1488, 0x01d0, 0x2d00, 0x60aa, 0x6853,
+ 0x0000, 0xad88, 0x0018, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108,
+ 0x1f04, 0x443d, 0x6857, 0x0001, 0x6e62, 0x0010, 0x080c, 0x429a,
+ 0x0089, 0x1de0, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0xa006,
+ 0x0cd8, 0x0126, 0x2091, 0x8000, 0x080c, 0x58b9, 0x012e, 0x0005,
+ 0xa01e, 0x0010, 0x2019, 0x0001, 0xa00e, 0x0126, 0x2091, 0x8000,
+ 0x604c, 0x2068, 0x6000, 0xd0dc, 0x1170, 0x8dff, 0x01e8, 0x83ff,
+ 0x0120, 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406, 0x1118,
+ 0x6840, 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70, 0x6a00,
+ 0x604c, 0xad06, 0x1110, 0x624e, 0x0018, 0xa180, 0x0000, 0x2202,
+ 0x82ff, 0x1110, 0x6152, 0x8dff, 0x012e, 0x0005, 0xa01e, 0x0010,
+ 0x2019, 0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x01e8, 0x83ff,
+ 0x0120, 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406, 0x1118,
+ 0x6840, 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70, 0x6a00,
+ 0x6080, 0xad06, 0x1110, 0x6282, 0x0018, 0xa180, 0x0000, 0x2202,
+ 0x82ff, 0x1110, 0x6186, 0x8dff, 0x0005, 0xa016, 0x080c, 0x4503,
+ 0x1110, 0x2011, 0x0001, 0x080c, 0x454d, 0x1110, 0xa295, 0x0002,
+ 0x0005, 0x080c, 0x457e, 0x0118, 0x080c, 0x7c4c, 0x0010, 0xa085,
+ 0x0001, 0x0005, 0x080c, 0x457e, 0x0118, 0x080c, 0x7bd9, 0x0010,
+ 0xa085, 0x0001, 0x0005, 0x080c, 0x457e, 0x0118, 0x080c, 0x7c1f,
+ 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x457e, 0x0118, 0x080c,
+ 0x7bf3, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x457e, 0x0118,
+ 0x080c, 0x7c79, 0x0010, 0xa085, 0x0001, 0x0005, 0x0126, 0x0006,
+ 0x00d6, 0x2091, 0x8000, 0x6080, 0xa06d, 0x0168, 0x6800, 0x0006,
+ 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x7dc8, 0x080c,
+ 0x46a1, 0x000e, 0x0c88, 0x6083, 0x0000, 0x6087, 0x0000, 0x00de,
+ 0x000e, 0x012e, 0x0005, 0x60a4, 0xa00d, 0x1118, 0xa085, 0x0001,
+ 0x0005, 0x00e6, 0x2170, 0x7000, 0xa005, 0x1160, 0x20a9, 0x0010,
+ 0xae88, 0x0004, 0x2104, 0xa606, 0x0128, 0x8108, 0x1f04, 0x4512,
+ 0xa085, 0x0001, 0xa006, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091,
+ 0x8000, 0x60a4, 0xa06d, 0x1128, 0x080c, 0x1488, 0x01a0, 0x2d00,
+ 0x60a6, 0x6803, 0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9,
+ 0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, 0x4531, 0xa085, 0x0001,
+ 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x00d6, 0x0126, 0x2091,
+ 0x8000, 0x60a4, 0xa06d, 0x0130, 0x60a7, 0x0000, 0x080c, 0x149f,
+ 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0x60a8, 0xa00d, 0x1118,
+ 0xa085, 0x0001, 0x0005, 0x00e6, 0x2170, 0x7050, 0xa005, 0x1160,
+ 0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0128, 0x8108,
+ 0x1f04, 0x455c, 0xa085, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091,
+ 0x8000, 0x0c19, 0x1188, 0x200b, 0xffff, 0x00d6, 0x60a8, 0x2068,
+ 0x6854, 0xa08a, 0x0002, 0x0218, 0x8001, 0x6856, 0x0020, 0x080c,
+ 0x149f, 0x60ab, 0x0000, 0x00de, 0x012e, 0x0005, 0x609c, 0xd0a4,
+ 0x0005, 0x00f6, 0x2079, 0x8b51, 0x7804, 0xd0a4, 0x0518, 0x0156,
+ 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x430a,
+ 0x1168, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004, 0x0118,
+ 0xa086, 0x0006, 0x1118, 0x6000, 0xc0ed, 0x6002, 0x001e, 0x8108,
+ 0x1f04, 0x458d, 0x00ce, 0x015e, 0x2009, 0x07d0, 0x2011, 0x45ac,
+ 0x080c, 0x568c, 0x00fe, 0x0005, 0x2011, 0x45ac, 0x080c, 0x560d,
+ 0x0156, 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c,
+ 0x430a, 0x1530, 0x6000, 0xd0ec, 0x0518, 0x0046, 0x62a0, 0xa294,
+ 0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x080c, 0x8982, 0x6000,
+ 0xc0e5, 0xc0ec, 0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700,
+ 0x6006, 0x2019, 0x0029, 0x080c, 0x59d5, 0x0086, 0x2041, 0x0000,
+ 0x080c, 0x5911, 0x2009, 0x0000, 0x080c, 0x878f, 0x008e, 0x004e,
+ 0x001e, 0x8108, 0x1f04, 0x45b6, 0x00ce, 0x015e, 0x0005, 0x00c6,
+ 0x6018, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x00ce, 0x0005, 0x2071,
+ 0x8c13, 0x7003, 0x0001, 0x7007, 0x0000, 0x7013, 0x0000, 0x7017,
0x0000, 0x701b, 0x0000, 0x701f, 0x0000, 0x704b, 0x0001, 0x704f,
0x0000, 0x705b, 0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x2071,
- 0x94b6, 0x7003, 0x9328, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f,
- 0x9496, 0x7013, 0x0020, 0x7017, 0x0040, 0x7037, 0x0000, 0x0005,
- 0x0016, 0x00e6, 0x2071, 0x946e, 0xa00e, 0x7186, 0x718a, 0x7097,
- 0x0001, 0x2001, 0x9252, 0x2004, 0xd0fc, 0x1148, 0x2001, 0x9252,
+ 0x8d7c, 0x7003, 0x8c13, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f,
+ 0x8d5c, 0x7013, 0x0020, 0x7017, 0x0040, 0x7037, 0x0000, 0x0005,
+ 0x0016, 0x00e6, 0x2071, 0x8d34, 0xa00e, 0x7186, 0x718a, 0x7097,
+ 0x0001, 0x2001, 0x8b52, 0x2004, 0xd0fc, 0x1148, 0x2001, 0x8b52,
0x2004, 0xa00e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x04f0, 0x2001,
- 0x9271, 0x200c, 0xa184, 0x000f, 0x2009, 0x9272, 0x210c, 0x0002,
- 0x478e, 0x47b0, 0x47b7, 0x47c1, 0x47c6, 0x478e, 0x478e, 0x478e,
- 0x478e, 0x478e, 0x478e, 0x478e, 0x478e, 0x478e, 0x478e, 0x478e,
+ 0x8b71, 0x200c, 0xa184, 0x000f, 0x2009, 0x8b72, 0x210c, 0x0002,
+ 0x4626, 0x4648, 0x464f, 0x4659, 0x465e, 0x4626, 0x4626, 0x4626,
+ 0x4626, 0x4626, 0x4626, 0x4626, 0x4626, 0x4626, 0x4626, 0x4626,
0x708f, 0x0005, 0x7007, 0x0122, 0x2001, 0x0002, 0x0030, 0x708f,
0x0002, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002, 0x7097, 0x0001,
0x0088, 0x7007, 0x0122, 0x2001, 0x0002, 0x0020, 0x7007, 0x0121,
0x2001, 0x0003, 0x7002, 0xa006, 0x7096, 0x708e, 0xa184, 0xff00,
0x8007, 0x709a, 0xa184, 0x00ff, 0x7092, 0x00ee, 0x001e, 0x0005,
- 0x00e6, 0x2071, 0x9328, 0x684c, 0xa005, 0x1130, 0x7028, 0xc085,
+ 0x00e6, 0x2071, 0x8c13, 0x684c, 0xa005, 0x1130, 0x7028, 0xc085,
0x702a, 0xa085, 0x0001, 0x0418, 0x6a60, 0x7236, 0x6b64, 0x733a,
0x6868, 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, 0x702e,
0x6844, 0x7032, 0x2009, 0x000d, 0x200a, 0x8007, 0x8006, 0x8006,
0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, 0x726e,
0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0xa006, 0x00ee,
- 0x0005, 0x0156, 0x00e6, 0x0026, 0x6838, 0xd0fc, 0x1904, 0x4861,
- 0x6804, 0xa00d, 0x0188, 0x00d6, 0x2071, 0x9200, 0xa016, 0x702c,
+ 0x0005, 0x0156, 0x00e6, 0x0026, 0x6838, 0xd0fc, 0x1904, 0x46f9,
+ 0x6804, 0xa00d, 0x0188, 0x00d6, 0x2071, 0x8b00, 0xa016, 0x702c,
0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x1dc8, 0x702e,
- 0x70ac, 0xa200, 0x70ae, 0x00de, 0x2071, 0x9328, 0x701c, 0xa005,
- 0x1904, 0x4871, 0x20a9, 0x0032, 0x0f04, 0x486f, 0x0e04, 0x482c,
- 0x2071, 0x946e, 0x7200, 0x82ff, 0x05d0, 0x6934, 0xa186, 0x0103,
- 0x1904, 0x487f, 0x6948, 0x6844, 0xa105, 0x1538, 0x2009, 0x8020,
- 0x2200, 0x0002, 0x486f, 0x4846, 0x48e6, 0x48f3, 0x2071, 0x0000,
- 0x20a9, 0x0032, 0x0f04, 0x486f, 0x7018, 0xd084, 0x1dd8, 0x7122,
+ 0x70ac, 0xa200, 0x70ae, 0x00de, 0x2071, 0x8c13, 0x701c, 0xa005,
+ 0x1904, 0x4709, 0x20a9, 0x0032, 0x0f04, 0x4707, 0x0e04, 0x46c4,
+ 0x2071, 0x8d34, 0x7200, 0x82ff, 0x05d0, 0x6934, 0xa186, 0x0103,
+ 0x1904, 0x4717, 0x6948, 0x6844, 0xa105, 0x1538, 0x2009, 0x8020,
+ 0x2200, 0x0002, 0x4707, 0x46de, 0x472f, 0x473b, 0x2071, 0x0000,
+ 0x20a9, 0x0032, 0x0f04, 0x4707, 0x7018, 0xd084, 0x1dd8, 0x7122,
0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080,
- 0x2071, 0x9200, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000,
+ 0x2071, 0x8b00, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000,
0x70ae, 0x002e, 0x00ee, 0x015e, 0x0005, 0x6844, 0xa086, 0x0100,
0x1130, 0x6868, 0xa005, 0x1118, 0x2009, 0x8020, 0x0888, 0x2071,
- 0x9328, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000, 0x7012, 0x7018,
+ 0x8c13, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000, 0x7012, 0x7018,
0xa06d, 0x711a, 0x0110, 0x6902, 0x0008, 0x711e, 0x0c10, 0xa18c,
- 0x00ff, 0xa186, 0x0013, 0x01e0, 0xa186, 0x001b, 0x01c8, 0xa186,
- 0x0023, 0x01e8, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e, 0x0118,
- 0xa18e, 0x001f, 0x19e0, 0x684c, 0xd0cc, 0x09c8, 0x6850, 0xa084,
- 0x00ff, 0xa086, 0x0001, 0x1998, 0x2009, 0x8021, 0x0804, 0x4840,
- 0x6848, 0xa005, 0x1960, 0x2009, 0x8022, 0x0804, 0x4840, 0x2071,
- 0x0000, 0x7018, 0xd084, 0x1918, 0x00e6, 0x2071, 0x9281, 0x7140,
- 0x00ee, 0x6838, 0xa102, 0x0a04, 0x486f, 0x684c, 0xa005, 0x1158,
- 0x00e6, 0x2071, 0x9281, 0x7004, 0x00ee, 0xd08c, 0x1904, 0x486f,
- 0x2001, 0x8024, 0x0040, 0x6848, 0xd084, 0x1118, 0x2001, 0x8023,
- 0x0010, 0x2001, 0x8027, 0x7022, 0x6840, 0x7026, 0x683c, 0x702a,
- 0x6850, 0x702e, 0x0026, 0x0036, 0x6b38, 0x2e10, 0xa290, 0x0072,
- 0x2d00, 0xa080, 0x0015, 0x200c, 0x2112, 0x8000, 0x200c, 0x8210,
- 0x8319, 0x1dd0, 0x003e, 0x002e, 0x0804, 0x4854, 0x7084, 0x8008,
- 0xa092, 0x001e, 0x1a04, 0x486f, 0x7186, 0xae90, 0x0003, 0xa210,
- 0x683c, 0x2012, 0x0080, 0x7084, 0x8008, 0xa092, 0x000f, 0x1a04,
- 0x486f, 0x7186, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012,
- 0x8210, 0x6840, 0x2012, 0x7088, 0xa10a, 0x0a04, 0x4858, 0x718c,
- 0x7084, 0xa10a, 0x0a04, 0x4858, 0x2071, 0x0000, 0x7018, 0xd084,
- 0x1904, 0x4858, 0x2071, 0x946e, 0x7000, 0xa086, 0x0002, 0x1150,
- 0x080c, 0x4b12, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
- 0x0804, 0x4858, 0x080c, 0x4b3c, 0x2071, 0x0000, 0x701b, 0x0001,
- 0x2091, 0x4080, 0x0804, 0x4858, 0x0006, 0x6837, 0x0103, 0x20a9,
- 0x001c, 0xad80, 0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x000e,
- 0x684a, 0x6952, 0x0005, 0x2071, 0x9328, 0x7004, 0x0002, 0x4948,
- 0x4958, 0x4afd, 0x4afe, 0x4b0b, 0x4b11, 0x4949, 0x4aee, 0x4a9a,
- 0x0005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4956, 0x2009, 0x000d,
- 0x7030, 0x200a, 0x2091, 0x4080, 0x7007, 0x0001, 0x012e, 0x0005,
- 0x2069, 0x94f8, 0x683c, 0xa005, 0x03f8, 0x11f0, 0x0126, 0x2091,
- 0x8000, 0x2069, 0x0000, 0x6934, 0x2001, 0x9334, 0x2004, 0xa10a,
- 0x0170, 0x0e04, 0x497c, 0x2069, 0x0000, 0x6818, 0xd084, 0x1158,
- 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x2069,
- 0x94f8, 0x683f, 0xffff, 0x012e, 0x2069, 0x9200, 0x6844, 0x6964,
- 0xa102, 0x2069, 0x946e, 0x688a, 0x6984, 0x701c, 0xa06d, 0x0120,
- 0x81ff, 0x0904, 0x49d1, 0x00a0, 0x81ff, 0x0904, 0x4a6f, 0x2071,
- 0x946e, 0x7184, 0x7088, 0xa10a, 0x1258, 0x7190, 0x2071, 0x94f8,
- 0x7038, 0xa005, 0x0128, 0x1b04, 0x4a6f, 0x713a, 0x0804, 0x4a6f,
- 0x2071, 0x946e, 0x718c, 0x0126, 0x2091, 0x8000, 0x7084, 0xa10a,
- 0x0a04, 0x4a70, 0x0e04, 0x4a2d, 0x2071, 0x0000, 0x7018, 0xd084,
- 0x1904, 0x4a2d, 0x2001, 0xffff, 0x2071, 0x94f8, 0x703a, 0x2071,
- 0x946e, 0x7000, 0xa086, 0x0002, 0x1150, 0x080c, 0x4b12, 0x2071,
- 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, 0x4a2d, 0x080c,
- 0x4b3c, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804,
- 0x4a2d, 0x2071, 0x946e, 0x7000, 0xa005, 0x0904, 0x4a51, 0x6934,
- 0xa186, 0x0103, 0x1904, 0x4a30, 0x6948, 0x6844, 0xa105, 0x1904,
- 0x4a47, 0x2071, 0x946e, 0x7000, 0x0002, 0x4a51, 0x4a11, 0x49e9,
- 0x49fb, 0x7084, 0x8008, 0xa092, 0x001e, 0x1a04, 0x4a6f, 0xae90,
- 0x0003, 0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0x9328, 0x080c,
- 0x4b95, 0x0804, 0x4a6f, 0x7084, 0x8008, 0xa092, 0x000f, 0x1a04,
- 0x4a6f, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210,
- 0x6840, 0x2012, 0x7186, 0x2071, 0x9328, 0x080c, 0x4b95, 0x0804,
- 0x4a6f, 0x2009, 0x8020, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4a2d,
- 0x2071, 0x0000, 0x7018, 0xd084, 0x1180, 0x7122, 0x683c, 0x7026,
- 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x012e, 0x2071,
- 0x9328, 0x080c, 0x4b95, 0x0804, 0x4a6f, 0x012e, 0x0804, 0x4a6f,
- 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e, 0x0118,
- 0xa18e, 0x001f, 0x11b0, 0x684c, 0xd0cc, 0x0198, 0x6850, 0xa084,
- 0x00ff, 0xa086, 0x0001, 0x1168, 0x2009, 0x8021, 0x0860, 0x6844,
- 0xa086, 0x0100, 0x1130, 0x6868, 0xa005, 0x1118, 0x2009, 0x8020,
- 0x0810, 0x2071, 0x9328, 0x080c, 0x4ba7, 0x01c8, 0x2071, 0x9328,
- 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003, 0x1130,
- 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x7007, 0x0003,
- 0x080c, 0x4bc0, 0x7050, 0xa086, 0x0100, 0x0904, 0x4afe, 0x0005,
- 0x2071, 0x9328, 0x080c, 0x4ba7, 0x0518, 0x2071, 0x946e, 0x7084,
- 0x700a, 0x20a9, 0x0020, 0x2099, 0x946f, 0x20a1, 0x9496, 0x53a3,
- 0x7087, 0x0000, 0x2071, 0x9328, 0x2069, 0x94b6, 0x706c, 0x6826,
- 0x7070, 0x682a, 0x7074, 0x682e, 0x7078, 0x6832, 0x2d10, 0x080c,
- 0x14c7, 0x7007, 0x0008, 0x2001, 0xffff, 0x2071, 0x94f8, 0x703a,
- 0x012e, 0x08a8, 0x2069, 0x94b6, 0x6808, 0xa08e, 0x0000, 0x0904,
- 0x4aed, 0xa08e, 0x0200, 0x0904, 0x4aeb, 0xa08e, 0x0100, 0x1904,
- 0x4aed, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4ae9, 0x2069, 0x0000,
- 0x6818, 0xd084, 0x15b0, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230,
- 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0048, 0x706c, 0xa080,
- 0x0040, 0x706e, 0x1220, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132,
- 0x6936, 0x2001, 0x9493, 0x2004, 0xa005, 0x1190, 0x6934, 0x2069,
- 0x946e, 0x689c, 0x699e, 0x2069, 0x94f8, 0xa102, 0x1118, 0x683c,
- 0xa005, 0x1368, 0x2001, 0x9494, 0x200c, 0x810d, 0x693e, 0x0038,
- 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x7007,
- 0x0001, 0x012e, 0x0010, 0x7007, 0x0005, 0x0005, 0x701c, 0xa06d,
- 0x0158, 0x080c, 0x4ba7, 0x0140, 0x7007, 0x0003, 0x080c, 0x4bc0,
- 0x7050, 0xa086, 0x0100, 0x0110, 0x0005, 0x0005, 0x7050, 0xa09e,
- 0x0100, 0x1118, 0x7007, 0x0004, 0x0030, 0xa086, 0x0200, 0x1110,
- 0x7007, 0x0005, 0x0005, 0x080c, 0x4b61, 0x7006, 0x080c, 0x4b95,
- 0x0005, 0x0005, 0x00e6, 0x0156, 0x2071, 0x946e, 0x7184, 0x81ff,
- 0x0500, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8,
- 0x2014, 0x7226, 0x8000, 0x0f04, 0x4b36, 0x2014, 0x722a, 0x8000,
- 0x0f04, 0x4b36, 0x2014, 0x722e, 0x8000, 0x0f04, 0x4b36, 0x2014,
- 0x723a, 0x8000, 0x0f04, 0x4b36, 0x2014, 0x723e, 0xa180, 0x8030,
- 0x7022, 0x015e, 0x00ee, 0x0005, 0x00e6, 0x0156, 0x2071, 0x946e,
- 0x7184, 0x81ff, 0x01d8, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071,
- 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x2014, 0x722a, 0x8000,
- 0x0f04, 0x4b58, 0x2014, 0x723a, 0x8000, 0x2014, 0x723e, 0x0018,
- 0x2001, 0x8020, 0x0010, 0xa180, 0x8042, 0x7022, 0x015e, 0x00ee,
- 0x0005, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034,
- 0x706e, 0x7038, 0x7072, 0x0048, 0x706c, 0xa080, 0x0040, 0x706e,
- 0x1220, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001,
- 0x700e, 0x11a0, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4b91, 0x2001,
- 0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x012e, 0x0005,
- 0x2001, 0x000d, 0x2102, 0x2001, 0x0001, 0x0005, 0x2001, 0x0007,
- 0x0005, 0x2001, 0x0006, 0x012e, 0x0005, 0x701c, 0xa06d, 0x0170,
- 0x0126, 0x2091, 0x8000, 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e,
- 0xa005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1493, 0x0005, 0x2019,
- 0x000d, 0x2304, 0x230c, 0xa10e, 0x0130, 0x2304, 0x230c, 0xa10e,
- 0x0110, 0xa006, 0x0060, 0x732c, 0x8319, 0x7130, 0xa102, 0x1118,
- 0x2300, 0xa005, 0x0020, 0x0210, 0xa302, 0x0008, 0x8002, 0x0005,
- 0x2d00, 0x7026, 0xa080, 0x000d, 0x7056, 0x7053, 0x0000, 0x0126,
- 0x2091, 0x8000, 0x2009, 0x9508, 0x2104, 0xc08d, 0x200a, 0x012e,
- 0x080c, 0x14df, 0x0005, 0x7088, 0xa08a, 0x0027, 0x1220, 0xa082,
- 0x001d, 0x0033, 0x0010, 0x080c, 0x13fe, 0x6027, 0x1e00, 0x0005,
- 0x4c57, 0x4be9, 0x4bff, 0x4c27, 0x4c4a, 0x4c7c, 0x4c8e, 0x4bff,
- 0x4c68, 0x6803, 0x0010, 0x6124, 0xd1e4, 0x1180, 0x080c, 0x4cd7,
- 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1cc, 0x0140, 0x708b, 0x0020,
+ 0x00ff, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e, 0x0118, 0xa18e,
+ 0x001f, 0x1d28, 0x684c, 0xd0cc, 0x0d10, 0x6850, 0xa084, 0x00ff,
+ 0xa086, 0x0001, 0x19e0, 0x2009, 0x8021, 0x0804, 0x46d8, 0x7084,
+ 0x8008, 0xa092, 0x001e, 0x1a98, 0x7186, 0xae90, 0x0003, 0xa210,
+ 0x683c, 0x2012, 0x0078, 0x7084, 0x8008, 0xa092, 0x000f, 0x1a38,
+ 0x7186, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210,
+ 0x6840, 0x2012, 0x7088, 0xa10a, 0x0a04, 0x46f0, 0x718c, 0x7084,
+ 0xa10a, 0x0a04, 0x46f0, 0x2071, 0x0000, 0x7018, 0xd084, 0x1904,
+ 0x46f0, 0x2071, 0x8d34, 0x7000, 0xa086, 0x0002, 0x1150, 0x080c,
+ 0x495f, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804,
+ 0x46f0, 0x080c, 0x4989, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091,
+ 0x4080, 0x0804, 0x46f0, 0x0006, 0x684c, 0x0006, 0x6837, 0x0103,
+ 0x20a9, 0x001c, 0xad80, 0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4,
+ 0x000e, 0xa084, 0x00ff, 0x684e, 0x000e, 0x684a, 0x6952, 0x0005,
+ 0x2071, 0x8c13, 0x7004, 0x0002, 0x4795, 0x47a5, 0x494a, 0x494b,
+ 0x4958, 0x495e, 0x4796, 0x493b, 0x48e7, 0x0005, 0x0126, 0x2091,
+ 0x8000, 0x0e04, 0x47a3, 0x2009, 0x000d, 0x7030, 0x200a, 0x2091,
+ 0x4080, 0x7007, 0x0001, 0x012e, 0x0005, 0x2069, 0x8dbd, 0x683c,
+ 0xa005, 0x03f8, 0x11f0, 0x0126, 0x2091, 0x8000, 0x2069, 0x0000,
+ 0x6934, 0x2001, 0x8c1f, 0x2004, 0xa10a, 0x0170, 0x0e04, 0x47c8,
+ 0x2069, 0x0000, 0x6818, 0xd084, 0x1158, 0x2009, 0x8040, 0x6922,
+ 0x681b, 0x0001, 0x2091, 0x4080, 0x2069, 0x8dbd, 0x683f, 0xffff,
+ 0x012e, 0x2069, 0x8b00, 0x6844, 0x6964, 0xa102, 0x2069, 0x8d34,
+ 0x688a, 0x6984, 0x701c, 0xa06d, 0x0120, 0x81ff, 0x0904, 0x481e,
+ 0x00a0, 0x81ff, 0x0904, 0x48bc, 0x2071, 0x8d34, 0x7184, 0x7088,
+ 0xa10a, 0x1258, 0x7190, 0x2071, 0x8dbd, 0x7038, 0xa005, 0x0128,
+ 0x1b04, 0x48bc, 0x713a, 0x0804, 0x48bc, 0x2071, 0x8d34, 0x718c,
+ 0x0126, 0x2091, 0x8000, 0x7084, 0xa10a, 0x0a04, 0x48bd, 0x0e04,
+ 0x487a, 0x2071, 0x0000, 0x7018, 0xd084, 0x1904, 0x487a, 0x2001,
+ 0xffff, 0x2071, 0x8dbd, 0x703a, 0x2071, 0x8d34, 0x7000, 0xa086,
+ 0x0002, 0x1150, 0x080c, 0x495f, 0x2071, 0x0000, 0x701b, 0x0001,
+ 0x2091, 0x4080, 0x0804, 0x487a, 0x080c, 0x4989, 0x2071, 0x0000,
+ 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, 0x487a, 0x2071, 0x8d34,
+ 0x7000, 0xa005, 0x0904, 0x489e, 0x6934, 0xa186, 0x0103, 0x1904,
+ 0x487d, 0x6948, 0x6844, 0xa105, 0x1904, 0x4894, 0x2071, 0x8d34,
+ 0x7000, 0x0002, 0x489e, 0x485e, 0x4836, 0x4848, 0x7084, 0x8008,
+ 0xa092, 0x001e, 0x1a04, 0x48bc, 0xae90, 0x0003, 0xa210, 0x683c,
+ 0x2012, 0x7186, 0x2071, 0x8c13, 0x080c, 0x49e2, 0x0804, 0x48bc,
+ 0x7084, 0x8008, 0xa092, 0x000f, 0x1a04, 0x48bc, 0xae90, 0x0003,
+ 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7186,
+ 0x2071, 0x8c13, 0x080c, 0x49e2, 0x0804, 0x48bc, 0x2009, 0x8020,
+ 0x0126, 0x2091, 0x8000, 0x0e04, 0x487a, 0x2071, 0x0000, 0x7018,
+ 0xd084, 0x1180, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b,
+ 0x0001, 0x2091, 0x4080, 0x012e, 0x2071, 0x8c13, 0x080c, 0x49e2,
+ 0x0804, 0x48bc, 0x012e, 0x0804, 0x48bc, 0xa18c, 0x00ff, 0xa186,
+ 0x0017, 0x0130, 0xa186, 0x001e, 0x0118, 0xa18e, 0x001f, 0x11b0,
+ 0x684c, 0xd0cc, 0x0198, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001,
+ 0x1168, 0x2009, 0x8021, 0x0860, 0x6844, 0xa086, 0x0100, 0x1130,
+ 0x6868, 0xa005, 0x1118, 0x2009, 0x8020, 0x0810, 0x2071, 0x8c13,
+ 0x080c, 0x49f4, 0x01c8, 0x2071, 0x8c13, 0x700f, 0x0001, 0x6934,
+ 0xa184, 0x00ff, 0xa086, 0x0003, 0x1130, 0x810f, 0xa18c, 0x00ff,
+ 0x8101, 0x0108, 0x710e, 0x7007, 0x0003, 0x080c, 0x4a0d, 0x7050,
+ 0xa086, 0x0100, 0x0904, 0x494b, 0x0005, 0x2071, 0x8c13, 0x080c,
+ 0x49f4, 0x0518, 0x2071, 0x8d34, 0x7084, 0x700a, 0x20a9, 0x0020,
+ 0x2099, 0x8d35, 0x20a1, 0x8d5c, 0x53a3, 0x7087, 0x0000, 0x2071,
+ 0x8c13, 0x2069, 0x8d7c, 0x706c, 0x6826, 0x7070, 0x682a, 0x7074,
+ 0x682e, 0x7078, 0x6832, 0x2d10, 0x080c, 0x14d3, 0x7007, 0x0008,
+ 0x2001, 0xffff, 0x2071, 0x8dbd, 0x703a, 0x012e, 0x08a8, 0x2069,
+ 0x8d7c, 0x6808, 0xa08e, 0x0000, 0x0904, 0x493a, 0xa08e, 0x0200,
+ 0x0904, 0x4938, 0xa08e, 0x0100, 0x1904, 0x493a, 0x0126, 0x2091,
+ 0x8000, 0x0e04, 0x4936, 0x2069, 0x0000, 0x6818, 0xd084, 0x15b0,
+ 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034, 0x706e,
+ 0x7038, 0x7072, 0x0048, 0x706c, 0xa080, 0x0040, 0x706e, 0x1220,
+ 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x2001, 0x8d59,
+ 0x2004, 0xa005, 0x1190, 0x6934, 0x2069, 0x8d34, 0x689c, 0x699e,
+ 0x2069, 0x8dbd, 0xa102, 0x1118, 0x683c, 0xa005, 0x1368, 0x2001,
+ 0x8d5a, 0x200c, 0x810d, 0x693e, 0x0038, 0x2009, 0x8040, 0x6922,
+ 0x681b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x012e, 0x0010,
+ 0x7007, 0x0005, 0x0005, 0x701c, 0xa06d, 0x0158, 0x080c, 0x49f4,
+ 0x0140, 0x7007, 0x0003, 0x080c, 0x4a0d, 0x7050, 0xa086, 0x0100,
+ 0x0110, 0x0005, 0x0005, 0x7050, 0xa09e, 0x0100, 0x1118, 0x7007,
+ 0x0004, 0x0030, 0xa086, 0x0200, 0x1110, 0x7007, 0x0005, 0x0005,
+ 0x080c, 0x49ae, 0x7006, 0x080c, 0x49e2, 0x0005, 0x0005, 0x00e6,
+ 0x0156, 0x2071, 0x8d34, 0x7184, 0x81ff, 0x0500, 0xa006, 0x7086,
+ 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000,
+ 0x0f04, 0x4983, 0x2014, 0x722a, 0x8000, 0x0f04, 0x4983, 0x2014,
+ 0x722e, 0x8000, 0x0f04, 0x4983, 0x2014, 0x723a, 0x8000, 0x0f04,
+ 0x4983, 0x2014, 0x723e, 0xa180, 0x8030, 0x7022, 0x015e, 0x00ee,
+ 0x0005, 0x00e6, 0x0156, 0x2071, 0x8d34, 0x7184, 0x81ff, 0x01d8,
+ 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014,
+ 0x7226, 0x8000, 0x2014, 0x722a, 0x8000, 0x0f04, 0x49a5, 0x2014,
+ 0x723a, 0x8000, 0x2014, 0x723e, 0x0018, 0x2001, 0x8020, 0x0010,
+ 0xa180, 0x8042, 0x7022, 0x015e, 0x00ee, 0x0005, 0x702c, 0x7130,
+ 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072,
+ 0x0048, 0x706c, 0xa080, 0x0040, 0x706e, 0x1220, 0x7070, 0xa081,
+ 0x0000, 0x7072, 0x7132, 0x700c, 0x8001, 0x700e, 0x11a0, 0x0126,
+ 0x2091, 0x8000, 0x0e04, 0x49de, 0x2001, 0x000d, 0x2102, 0x2091,
+ 0x4080, 0x2001, 0x0001, 0x012e, 0x0005, 0x2001, 0x000d, 0x2102,
+ 0x2001, 0x0001, 0x0005, 0x2001, 0x0007, 0x0005, 0x2001, 0x0006,
+ 0x012e, 0x0005, 0x701c, 0xa06d, 0x0170, 0x0126, 0x2091, 0x8000,
+ 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, 0xa005, 0x1108, 0x701a,
+ 0x012e, 0x080c, 0x149f, 0x0005, 0x2019, 0x000d, 0x2304, 0x230c,
+ 0xa10e, 0x0130, 0x2304, 0x230c, 0xa10e, 0x0110, 0xa006, 0x0060,
+ 0x732c, 0x8319, 0x7130, 0xa102, 0x1118, 0x2300, 0xa005, 0x0020,
+ 0x0210, 0xa302, 0x0008, 0x8002, 0x0005, 0x2d00, 0x7026, 0xa080,
+ 0x000d, 0x7056, 0x7053, 0x0000, 0x0126, 0x2091, 0x8000, 0x2009,
+ 0x8dcd, 0x2104, 0xc08d, 0x200a, 0x012e, 0x080c, 0x14eb, 0x0005,
+ 0x7088, 0xa08a, 0x0028, 0x1220, 0xa082, 0x001d, 0x0033, 0x0010,
+ 0x080c, 0x1410, 0x6027, 0x1e00, 0x0005, 0x4ab8, 0x4a4a, 0x4a60,
+ 0x4a88, 0x4aab, 0x4add, 0x4aef, 0x4a60, 0x4ac9, 0x4a37, 0x00d6,
+ 0x2069, 0x0200, 0x6804, 0xa005, 0x1158, 0x6808, 0xa005, 0x1140,
+ 0x708b, 0x0027, 0x7003, 0x0003, 0x6028, 0xa085, 0x0400, 0x602a,
+ 0x00de, 0x0005, 0x6803, 0x0010, 0x6124, 0xd1e4, 0x1180, 0x080c,
+ 0x4b52, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1cc, 0x0140, 0x708b,
+ 0x0020, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b, 0x001f, 0x0005,
+ 0x6803, 0x0008, 0x6124, 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4,
+ 0x1198, 0xa184, 0x1e00, 0x11d8, 0x60e3, 0x0001, 0x600c, 0xc0b4,
+ 0x600e, 0x080c, 0x4c72, 0x6803, 0x0000, 0x708b, 0x0027, 0x2001,
+ 0x8b25, 0x2003, 0x0000, 0x0058, 0x708b, 0x001e, 0x0040, 0x708b,
+ 0x001d, 0x0028, 0x708b, 0x0020, 0x0010, 0x708b, 0x001f, 0x0005,
+ 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x4c72, 0x6803,
+ 0x0000, 0x6124, 0xd1d4, 0x11a0, 0xd1dc, 0x1178, 0xd1e4, 0x1150,
+ 0xa184, 0x1e00, 0x1178, 0x708b, 0x0027, 0x2001, 0x8b25, 0x2003,
+ 0x0000, 0x0040, 0x708b, 0x001e, 0x0028, 0x708b, 0x001d, 0x0010,
+ 0x708b, 0x001f, 0x0005, 0x6803, 0x0020, 0x6124, 0xd1dc, 0x1128,
+ 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b, 0x001d, 0x0005,
+ 0x080c, 0x4b7e, 0x6124, 0xd1dc, 0x1158, 0x080c, 0x4b52, 0xd1d4,
+ 0x1128, 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b, 0x001f,
+ 0x0005, 0x6803, 0x0020, 0x6124, 0xd1d4, 0x1160, 0xd1cc, 0x1150,
+ 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b, 0x001e, 0x0028, 0x708b,
+ 0x001d, 0x0010, 0x708b, 0x0021, 0x0005, 0x080c, 0x4b7e, 0x6124,
+ 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b, 0x001e,
0x0028, 0x708b, 0x001d, 0x0010, 0x708b, 0x001f, 0x0005, 0x6803,
- 0x0008, 0x6124, 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198,
- 0xa184, 0x1e00, 0x11d8, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e,
- 0x080c, 0x4df5, 0x6803, 0x0000, 0x708b, 0x0026, 0x2001, 0x9225,
- 0x2003, 0x0000, 0x0058, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d,
- 0x0028, 0x708b, 0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x60e3,
- 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x4df5, 0x6803, 0x0000,
- 0x6124, 0xd1d4, 0x11a0, 0xd1dc, 0x1178, 0xd1e4, 0x1150, 0xa184,
- 0x1e00, 0x1178, 0x708b, 0x0026, 0x2001, 0x9225, 0x2003, 0x0000,
- 0x0040, 0x708b, 0x001e, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b,
- 0x001f, 0x0005, 0x6803, 0x0020, 0x6124, 0xd1dc, 0x1128, 0xd1e4,
- 0x0128, 0x708b, 0x001e, 0x0010, 0x708b, 0x001d, 0x0005, 0x080c,
- 0x4d03, 0x6124, 0xd1dc, 0x1158, 0x080c, 0x4cd7, 0xd1d4, 0x1128,
- 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b, 0x001f, 0x0005,
- 0x6803, 0x0020, 0x6124, 0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc,
- 0x1128, 0xd1e4, 0x0140, 0x708b, 0x001e, 0x0028, 0x708b, 0x001d,
- 0x0010, 0x708b, 0x0021, 0x0005, 0x080c, 0x4d03, 0x6124, 0xd1d4,
- 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b, 0x001e, 0x0028,
- 0x708b, 0x001d, 0x0010, 0x708b, 0x001f, 0x0005, 0x6803, 0x0010,
- 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4,
- 0x0158, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d, 0x0028, 0x708b,
- 0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x00c6, 0x00d6, 0x00e6,
- 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x9200, 0x2091,
- 0x8000, 0x080c, 0x4de1, 0x0150, 0x080c, 0x4dd7, 0x1138, 0x2001,
- 0x0001, 0x080c, 0x23ba, 0x080c, 0x4d9a, 0x00a0, 0x080c, 0x4d00,
- 0x0178, 0x2001, 0x0001, 0x080c, 0x23ba, 0x7088, 0xa086, 0x001e,
- 0x0120, 0x7088, 0xa086, 0x0022, 0x1118, 0x708b, 0x0025, 0x0010,
- 0x708b, 0x0021, 0x012e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0016,
- 0x0026, 0x2009, 0x0064, 0x2011, 0x4ce2, 0x080c, 0x57b3, 0x002e,
- 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c, 0x6f1e, 0x2071,
- 0x9200, 0x080c, 0x4ca5, 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0026,
- 0x00e6, 0x2011, 0x4ce2, 0x2071, 0x94f8, 0x701c, 0xa206, 0x1118,
- 0x7018, 0xa005, 0x0110, 0xa085, 0x0001, 0x00ee, 0x002e, 0x0005,
- 0x6020, 0xd09c, 0x0005, 0x6803, 0x0040, 0x0156, 0x20a9, 0x002d,
- 0x1d04, 0x4d08, 0x2091, 0x6000, 0x1f04, 0x4d08, 0x015e, 0x0005,
- 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071,
- 0x9200, 0x2001, 0x94d8, 0x200c, 0xa186, 0x0000, 0x0158, 0xa186,
- 0x0001, 0x0158, 0xa186, 0x0002, 0x0158, 0xa186, 0x0003, 0x0158,
- 0x0804, 0x4d88, 0x708b, 0x0022, 0x0048, 0x708b, 0x0021, 0x0030,
- 0x708b, 0x0023, 0x0038, 0x708b, 0x0024, 0x0020, 0xa085, 0x0001,
- 0x080c, 0x4e05, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001,
- 0x080c, 0x2460, 0x0026, 0x2011, 0x0003, 0x080c, 0x718f, 0x002e,
- 0x7000, 0xa08e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b,
- 0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024,
- 0xd0ac, 0x0118, 0x012e, 0x015e, 0x04c8, 0x6803, 0x0080, 0x6803,
- 0x0000, 0x6904, 0xd1d4, 0x1130, 0x6803, 0x0100, 0x1f04, 0x4d57,
- 0x080c, 0x4e12, 0x012e, 0x015e, 0x080c, 0x4dd7, 0x01a8, 0x6044,
- 0xa005, 0x0168, 0x6050, 0x0006, 0xa085, 0x0020, 0x6052, 0x080c,
- 0x4e12, 0xa006, 0x8001, 0x1df0, 0x000e, 0x6052, 0x0028, 0x6804,
- 0xd0d4, 0x1110, 0x080c, 0x4e12, 0x2001, 0x94d8, 0x2003, 0x0004,
- 0x080c, 0x4bd3, 0x080c, 0x4dd7, 0x0148, 0x6804, 0xd0d4, 0x1130,
- 0xd0dc, 0x1100, 0x2001, 0x94d8, 0x2003, 0x0000, 0x00ee, 0x00de,
- 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069,
- 0x0140, 0x2071, 0x9200, 0x2001, 0x94d7, 0x2003, 0x0000, 0x2001,
- 0x94c8, 0x2003, 0x0000, 0x708b, 0x0000, 0x60e3, 0x0000, 0x6887,
- 0x0000, 0x2001, 0x0000, 0x080c, 0x2460, 0x6803, 0x0000, 0x6043,
- 0x0090, 0x6027, 0xffff, 0x602b, 0x002f, 0x2001, 0x9225, 0x2003,
- 0x0000, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, 0x94d7,
- 0x2004, 0xa086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x2001, 0x9271,
- 0x2004, 0xa084, 0x0030, 0xa086, 0x0000, 0x000e, 0x0005, 0x0006,
- 0x2001, 0x9271, 0x2004, 0xa084, 0x0030, 0xa086, 0x0030, 0x000e,
- 0x0005, 0x0006, 0x2001, 0x9271, 0x2004, 0xa084, 0x0030, 0xa086,
- 0x0010, 0x000e, 0x0005, 0x0006, 0x2001, 0x9271, 0x2004, 0xa084,
- 0x0030, 0xa086, 0x0020, 0x000e, 0x0005, 0x2001, 0x920c, 0x2004,
- 0xd0a4, 0x0150, 0x080c, 0x2480, 0x0036, 0x2019, 0x0028, 0x080c,
- 0x264b, 0x003e, 0xa006, 0x0009, 0x0005, 0x00e6, 0x2071, 0x920c,
- 0x2e04, 0x0118, 0xa085, 0x0010, 0x0010, 0xa084, 0xffef, 0x2072,
- 0x00ee, 0x0005, 0x6050, 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006,
- 0x600c, 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x602f, 0x0100,
- 0x602f, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x000e, 0x602a,
- 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2,
- 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x2460,
- 0x6803, 0x0080, 0x6803, 0x0000, 0x6803, 0x0020, 0x000e, 0x6052,
- 0x6050, 0x0005, 0x2071, 0x92f6, 0x7003, 0x0000, 0x7007, 0x0000,
- 0x700f, 0x0000, 0x702b, 0x0001, 0x704f, 0x0000, 0x7053, 0x0001,
- 0x705f, 0x0020, 0x7063, 0x0040, 0x7083, 0x0000, 0x708b, 0x0000,
- 0x708f, 0x0001, 0x70bf, 0x0000, 0x0005, 0x00e6, 0x2071, 0x92f6,
- 0x6848, 0xa005, 0x1130, 0x7028, 0xc085, 0x702a, 0xa085, 0x0001,
- 0x0428, 0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858, 0x703e, 0x707a,
- 0x685c, 0x7042, 0x707e, 0x6848, 0x702e, 0x6840, 0x7032, 0x2009,
- 0x000c, 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084,
- 0xffc0, 0xa210, 0x2100, 0xa319, 0x7272, 0x7376, 0x7028, 0xc084,
- 0x702a, 0x7007, 0x0001, 0x700f, 0x0000, 0xa006, 0x00ee, 0x0005,
- 0x2b78, 0x2071, 0x92f6, 0x7004, 0x0043, 0x700c, 0x0002, 0x4e9c,
- 0x4e93, 0x4e93, 0x4e93, 0x4e93, 0x0005, 0x4ef2, 0x4ef3, 0x4f25,
- 0x4f26, 0x4ef0, 0x4f5a, 0x4f5f, 0x4f90, 0x4f91, 0x4fac, 0x4fad,
- 0x4fae, 0x4faf, 0x4fb0, 0x4fb1, 0x502d, 0x5054, 0x700c, 0x0002,
- 0x4eb5, 0x4ef0, 0x4ef0, 0x4ef1, 0x4ef1, 0x7830, 0x7930, 0xa106,
- 0x0120, 0x7830, 0x7930, 0xa106, 0x1510, 0x7030, 0xa10a, 0x01f8,
- 0x1210, 0x712c, 0xa10a, 0xa18a, 0x0002, 0x12d0, 0x080c, 0x145f,
- 0x01b0, 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001, 0x0003, 0x7057,
- 0x0000, 0x0126, 0x0006, 0x2091, 0x8000, 0x2009, 0x9508, 0x2104,
- 0xc085, 0x200a, 0x000e, 0x700e, 0x012e, 0x080c, 0x14df, 0x0005,
- 0x080c, 0x145f, 0x0de0, 0x2d00, 0x705a, 0x080c, 0x145f, 0x1108,
- 0x0c10, 0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, 0x0004, 0x08f8,
- 0x0005, 0x0005, 0x0005, 0x700c, 0x0002, 0x4efa, 0x4efd, 0x4f0b,
- 0x4f24, 0x4f24, 0x080c, 0x4eae, 0x0005, 0x0126, 0x8001, 0x700e,
- 0x7058, 0x0006, 0x080c, 0x5311, 0x0120, 0x2091, 0x8000, 0x080c,
- 0x4eae, 0x00de, 0x0048, 0x0126, 0x8001, 0x700e, 0x080c, 0x5311,
- 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000,
- 0x6834, 0xa084, 0x00ff, 0xa08a, 0x0020, 0x1218, 0x00db, 0x012e,
- 0x0005, 0x012e, 0x080c, 0x4fb2, 0x0005, 0x0005, 0x0005, 0x00e6,
- 0x2071, 0x92f6, 0x700c, 0x0002, 0x4f31, 0x4f31, 0x4f31, 0x4f33,
- 0x4f36, 0x00ee, 0x0005, 0x700f, 0x0001, 0x0010, 0x700f, 0x0002,
- 0x00ee, 0x0005, 0x4fb2, 0x4fb2, 0x4fce, 0x4fb2, 0x50e0, 0x4fb2,
- 0x4fb2, 0x4fb2, 0x4fb2, 0x4fb2, 0x4fce, 0x5119, 0x515c, 0x51a5,
- 0x51b9, 0x4fb2, 0x4fb2, 0x4fea, 0x4fce, 0x4ffe, 0x4fb2, 0x5013,
- 0x5243, 0x525e, 0x4fb2, 0x4fea, 0x4fb2, 0x4ffe, 0x4fb2, 0x4fb2,
- 0x5013, 0x525e, 0x7020, 0x2068, 0x080c, 0x1493, 0x0005, 0x700c,
- 0x0002, 0x4f66, 0x4f69, 0x4f77, 0x4f8f, 0x4f8f, 0x080c, 0x4eae,
- 0x0005, 0x0126, 0x8001, 0x700e, 0x7058, 0x0006, 0x080c, 0x5311,
- 0x0120, 0x2091, 0x8000, 0x080c, 0x4eae, 0x00de, 0x0048, 0x0126,
- 0x8001, 0x700e, 0x080c, 0x5311, 0x7058, 0x2068, 0x7084, 0x705a,
+ 0x0010, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128,
+ 0xd1e4, 0x0158, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d, 0x0028,
+ 0x708b, 0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x00c6, 0x00d6,
+ 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x8b00,
+ 0x2091, 0x8000, 0x080c, 0x4c42, 0x11b8, 0x7088, 0xa086, 0x0027,
+ 0x1198, 0x6027, 0x0200, 0xe000, 0xe000, 0x6024, 0xd0cc, 0x0148,
+ 0x2001, 0x8d9d, 0x2003, 0x0001, 0x2001, 0x8b00, 0x2003, 0x0001,
+ 0x0420, 0x6028, 0xc0cd, 0x602a, 0x080c, 0x4c5e, 0x0150, 0x080c,
+ 0x4c54, 0x1138, 0x2001, 0x0001, 0x080c, 0x2298, 0x080c, 0x4c15,
+ 0x00a0, 0x080c, 0x4b7b, 0x0178, 0x2001, 0x0001, 0x080c, 0x2298,
+ 0x7088, 0xa086, 0x001e, 0x0120, 0x7088, 0xa086, 0x0022, 0x1118,
+ 0x708b, 0x0025, 0x0010, 0x708b, 0x0021, 0x012e, 0x00ee, 0x00de,
+ 0x00ce, 0x0005, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x4b5d,
+ 0x080c, 0x5601, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016,
+ 0x080c, 0x66f7, 0x2071, 0x8b00, 0x080c, 0x4b06, 0x001e, 0x00fe,
+ 0x00ee, 0x0005, 0x0026, 0x00e6, 0x2011, 0x4b5d, 0x2071, 0x8dbd,
+ 0x701c, 0xa206, 0x1118, 0x7018, 0xa005, 0x0110, 0xa085, 0x0001,
+ 0x00ee, 0x002e, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6803, 0x0040,
+ 0x0156, 0x20a9, 0x002d, 0x1d04, 0x4b83, 0x2091, 0x6000, 0x1f04,
+ 0x4b83, 0x015e, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100,
+ 0x2069, 0x0140, 0x2071, 0x8b00, 0x2001, 0x8d9d, 0x200c, 0xa186,
+ 0x0000, 0x0158, 0xa186, 0x0001, 0x0158, 0xa186, 0x0002, 0x0158,
+ 0xa186, 0x0003, 0x0158, 0x0804, 0x4c03, 0x708b, 0x0022, 0x0048,
+ 0x708b, 0x0021, 0x0030, 0x708b, 0x0023, 0x0038, 0x708b, 0x0024,
+ 0x0020, 0xa085, 0x0001, 0x080c, 0x4c82, 0x60e3, 0x0000, 0x6887,
+ 0x0001, 0x2001, 0x0001, 0x080c, 0x233e, 0x0026, 0x2011, 0x0003,
+ 0x080c, 0x695c, 0x002e, 0x7000, 0xa08e, 0x0004, 0x0118, 0x602b,
+ 0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000,
+ 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0118, 0x012e, 0x015e, 0x04c8,
+ 0x6803, 0x0080, 0x6803, 0x0000, 0x6904, 0xd1d4, 0x1130, 0x6803,
+ 0x0100, 0x1f04, 0x4bd2, 0x080c, 0x4c8f, 0x012e, 0x015e, 0x080c,
+ 0x4c54, 0x01a8, 0x6044, 0xa005, 0x0168, 0x6050, 0x0006, 0xa085,
+ 0x0020, 0x6052, 0x080c, 0x4c8f, 0xa006, 0x8001, 0x1df0, 0x000e,
+ 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x4c8f, 0x2001,
+ 0x8d9d, 0x2003, 0x0004, 0x080c, 0x4a20, 0x080c, 0x4c54, 0x0148,
+ 0x6804, 0xd0d4, 0x1130, 0xd0dc, 0x1100, 0x2001, 0x8d9d, 0x2003,
+ 0x0000, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6,
+ 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x8b00, 0x2001, 0x8d9c,
+ 0x2003, 0x0000, 0x2001, 0x8d8d, 0x2003, 0x0000, 0x708b, 0x0000,
+ 0x60e3, 0x0000, 0x6887, 0x0000, 0x2001, 0x0000, 0x080c, 0x233e,
+ 0x6803, 0x0000, 0x6043, 0x0090, 0x6043, 0x0010, 0x2001, 0x8b25,
+ 0x2003, 0x0000, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de,
+ 0x00ce, 0x0005, 0x0006, 0x2001, 0x8d9c, 0x2004, 0xa086, 0xaaaa,
+ 0x000e, 0x0005, 0x0006, 0x2001, 0x8b71, 0x2004, 0xa084, 0x0030,
+ 0xa086, 0x0000, 0x000e, 0x0005, 0x0006, 0x2001, 0x8b71, 0x2004,
+ 0xa084, 0x0030, 0xa086, 0x0030, 0x000e, 0x0005, 0x0006, 0x2001,
+ 0x8b71, 0x2004, 0xa084, 0x0030, 0xa086, 0x0010, 0x000e, 0x0005,
+ 0x0006, 0x2001, 0x8b71, 0x2004, 0xa084, 0x0030, 0xa086, 0x0020,
+ 0x000e, 0x0005, 0x2001, 0x8b0c, 0x2004, 0xd0a4, 0x0150, 0x080c,
+ 0x235e, 0x0036, 0x2019, 0x0028, 0x080c, 0x2542, 0x003e, 0xa006,
+ 0x0009, 0x0005, 0x00e6, 0x2071, 0x8b0c, 0x2e04, 0x0118, 0xa085,
+ 0x0010, 0x0010, 0xa084, 0xffef, 0x2072, 0x00ee, 0x0005, 0x6050,
+ 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004,
+ 0x0006, 0x6028, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, 0x602f,
+ 0x0080, 0x602f, 0x0000, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e,
+ 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2, 0x60e3, 0x0000, 0x6887,
+ 0x0001, 0x2001, 0x0001, 0x080c, 0x233e, 0x6803, 0x0080, 0x6803,
+ 0x0000, 0x6803, 0x0020, 0x000e, 0x6052, 0x6050, 0x0005, 0x0156,
+ 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140,
+ 0x2071, 0x8b00, 0x6028, 0xa084, 0xe1ff, 0x602a, 0x6027, 0x0200,
+ 0x6803, 0x0010, 0x20a9, 0x04e2, 0x6024, 0xd0cc, 0x1188, 0x1d04,
+ 0x4cd4, 0x2091, 0x6000, 0x1f04, 0x4cd4, 0x2001, 0x8d9d, 0x2003,
+ 0x0001, 0x2001, 0x8b00, 0x2003, 0x0001, 0xa085, 0x0001, 0x0410,
+ 0x6803, 0x0000, 0x20a9, 0x04e2, 0x6027, 0x1e00, 0x2009, 0x1e00,
+ 0xe000, 0x6024, 0xa10c, 0x0138, 0x1d04, 0x4cec, 0x2091, 0x6000,
+ 0x1f04, 0x4cec, 0x0c10, 0x6028, 0xa085, 0x1e00, 0x602a, 0x60e3,
+ 0x0000, 0x709c, 0x6886, 0x2001, 0x8d8d, 0x2004, 0x080c, 0x233e,
+ 0x60e2, 0xa006, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x015e, 0x0005,
+ 0x0156, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071,
+ 0x8b00, 0x2069, 0x0200, 0x6804, 0xa005, 0x1118, 0x6808, 0xa005,
+ 0x0158, 0x6028, 0xa084, 0xfbff, 0x602a, 0x6027, 0x0400, 0x708b,
+ 0x0026, 0x7003, 0x0001, 0x0460, 0x2069, 0x0140, 0x6803, 0x0008,
+ 0x20a9, 0x04e2, 0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024,
+ 0xa10c, 0x0188, 0x1d04, 0x4d32, 0x2091, 0x6000, 0x1f04, 0x4d32,
+ 0x2001, 0x8d9d, 0x2003, 0x0001, 0x2001, 0x8b00, 0x2003, 0x0001,
+ 0xa085, 0x0001, 0x0068, 0x6803, 0x0000, 0x60e3, 0x0000, 0x709c,
+ 0x6886, 0x2001, 0x8d8d, 0x2004, 0x080c, 0x233e, 0x60e2, 0xa006,
+ 0x00ee, 0x00de, 0x00ce, 0x001e, 0x015e, 0x0005, 0x2071, 0x8be1,
+ 0x7003, 0x0000, 0x7007, 0x0000, 0x700f, 0x0000, 0x702b, 0x0001,
+ 0x704f, 0x0000, 0x7053, 0x0001, 0x705f, 0x0020, 0x7063, 0x0040,
+ 0x7083, 0x0000, 0x708b, 0x0000, 0x708f, 0x0001, 0x70bf, 0x0000,
+ 0x0005, 0x00e6, 0x2071, 0x8be1, 0x6848, 0xa005, 0x1130, 0x7028,
+ 0xc085, 0x702a, 0xa085, 0x0001, 0x0428, 0x6a50, 0x7236, 0x6b54,
+ 0x733a, 0x6858, 0x703e, 0x707a, 0x685c, 0x7042, 0x707e, 0x6848,
+ 0x702e, 0x6840, 0x7032, 0x2009, 0x000c, 0x200a, 0x8007, 0x8006,
+ 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319,
+ 0x7272, 0x7376, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700f,
+ 0x0000, 0xa006, 0x00ee, 0x0005, 0x2b78, 0x2071, 0x8be1, 0x7004,
+ 0x0043, 0x700c, 0x0002, 0x4db8, 0x4daf, 0x4daf, 0x4daf, 0x4daf,
+ 0x0005, 0x4e0e, 0x4e0f, 0x4e41, 0x4e42, 0x4e0c, 0x4e76, 0x4e7b,
+ 0x4eac, 0x4ead, 0x4ec8, 0x4ec9, 0x4eca, 0x4ecb, 0x4ecc, 0x4ecd,
+ 0x4f32, 0x4f59, 0x700c, 0x0002, 0x4dd1, 0x4e0c, 0x4e0c, 0x4e0d,
+ 0x4e0d, 0x7830, 0x7930, 0xa106, 0x0120, 0x7830, 0x7930, 0xa106,
+ 0x1510, 0x7030, 0xa10a, 0x01f8, 0x1210, 0x712c, 0xa10a, 0xa18a,
+ 0x0002, 0x12d0, 0x080c, 0x146f, 0x01b0, 0x2d00, 0x705a, 0x7063,
+ 0x0040, 0x2001, 0x0003, 0x7057, 0x0000, 0x0126, 0x0006, 0x2091,
+ 0x8000, 0x2009, 0x8dcd, 0x2104, 0xc085, 0x200a, 0x000e, 0x700e,
+ 0x012e, 0x080c, 0x14eb, 0x0005, 0x080c, 0x146f, 0x0de0, 0x2d00,
+ 0x705a, 0x080c, 0x146f, 0x1108, 0x0c10, 0x2d00, 0x7086, 0x7063,
+ 0x0080, 0x2001, 0x0004, 0x08f8, 0x0005, 0x0005, 0x0005, 0x700c,
+ 0x0002, 0x4e16, 0x4e19, 0x4e27, 0x4e40, 0x4e40, 0x080c, 0x4dca,
+ 0x0005, 0x0126, 0x8001, 0x700e, 0x7058, 0x0006, 0x080c, 0x51f4,
+ 0x0120, 0x2091, 0x8000, 0x080c, 0x4dca, 0x00de, 0x0048, 0x0126,
+ 0x8001, 0x700e, 0x080c, 0x51f4, 0x7058, 0x2068, 0x7084, 0x705a,
0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a,
- 0x001a, 0x1218, 0x003b, 0x012e, 0x0005, 0x012e, 0x0419, 0x0005,
- 0x0005, 0x0005, 0x4fb2, 0x4fce, 0x50cc, 0x4fb2, 0x4fce, 0x4fb2,
- 0x4fce, 0x4fce, 0x4fb2, 0x4fce, 0x50cc, 0x4fce, 0x4fce, 0x4fce,
- 0x4fce, 0x4fce, 0x4fb2, 0x4fce, 0x50cc, 0x4fb2, 0x4fb2, 0x4fce,
- 0x4fb2, 0x4fb2, 0x4fb2, 0x4fce, 0x0005, 0x0005, 0x0005, 0x0005,
- 0x0005, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0d5,
- 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x4809, 0x012e, 0x0005,
- 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5, 0x683a, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x4809, 0x012e, 0x0005, 0x7007, 0x0001,
- 0x6838, 0xa084, 0x00ff, 0xc0ed, 0x683a, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x4809, 0x012e, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084,
- 0x00ff, 0xc0dd, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x4809,
- 0x012e, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0988, 0x8001,
- 0x1120, 0x7007, 0x0001, 0x0804, 0x508d, 0x7007, 0x0006, 0x7012,
- 0x2d00, 0x7016, 0x701a, 0x704b, 0x508d, 0x0005, 0x6834, 0x8007,
- 0xa084, 0x00ff, 0x0904, 0x4fc0, 0x8001, 0x1120, 0x7007, 0x0001,
- 0x0804, 0x50ac, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a,
- 0x704b, 0x50ac, 0x0005, 0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004,
- 0xa080, 0x0024, 0x2098, 0x20a1, 0x9321, 0x53a3, 0x6858, 0x7012,
- 0xa082, 0x0401, 0x1a04, 0x4fdc, 0x6884, 0xa08a, 0x0003, 0x1a04,
- 0x4fdc, 0xa080, 0x507e, 0x2005, 0x70c6, 0x7010, 0xa015, 0x0904,
- 0x5072, 0x080c, 0x145f, 0x1118, 0x7007, 0x000f, 0x0005, 0x2d00,
- 0x7022, 0x70c4, 0x2060, 0x2c05, 0x6836, 0xe004, 0xad00, 0x7096,
- 0xe008, 0xa20a, 0x1210, 0xa00e, 0x2200, 0x7112, 0xe20c, 0x8003,
- 0x800b, 0xa296, 0x0004, 0x0108, 0xa108, 0x719a, 0x810b, 0x719e,
- 0xae90, 0x0022, 0x080c, 0x14c7, 0x7090, 0xa08e, 0x0100, 0x0170,
- 0xa086, 0x0200, 0x0118, 0x7007, 0x0010, 0x0005, 0x7020, 0x2068,
- 0x080c, 0x1493, 0x7014, 0x2068, 0x0804, 0x4fdc, 0x7020, 0x2068,
- 0x7018, 0x6802, 0x6807, 0x0000, 0x2d08, 0x2068, 0x6906, 0x711a,
- 0x0804, 0x502d, 0x7014, 0x2068, 0x7007, 0x0001, 0x6834, 0xa084,
- 0x00ff, 0xa086, 0x001e, 0x0904, 0x5276, 0x0078, 0x5081, 0x5085,
- 0x5089, 0x0002, 0x0011, 0x0007, 0x0004, 0x000a, 0x000f, 0x0005,
- 0x0006, 0x0012, 0x000f, 0x0005, 0x0006, 0x2009, 0x922f, 0x210c,
- 0x81ff, 0x11a8, 0x6838, 0xa084, 0x00ff, 0x683a, 0x6853, 0x0000,
- 0x080c, 0x423e, 0x1108, 0x0005, 0x080c, 0x492c, 0x0126, 0x2091,
- 0x8000, 0x080c, 0x8527, 0x080c, 0x4809, 0x012e, 0x0ca0, 0x2001,
- 0x0028, 0x2009, 0x0000, 0x0c80, 0x2009, 0x922f, 0x210c, 0x81ff,
- 0x11a8, 0x6858, 0xa005, 0x01a8, 0x6838, 0xa084, 0x00ff, 0x683a,
- 0x6853, 0x0000, 0x080c, 0x42db, 0x1108, 0x0005, 0x684a, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x4809, 0x012e, 0x0cb8, 0x2001, 0x0028,
- 0x0ca8, 0x2001, 0x0000, 0x0c90, 0x7018, 0x6802, 0x2d08, 0x2068,
- 0x6906, 0x711a, 0x7010, 0x8001, 0x7012, 0x0118, 0x7007, 0x0006,
- 0x0030, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x080f, 0x0005,
- 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084,
- 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x01b0, 0x2009, 0x0000,
- 0x20a9, 0x007e, 0xa096, 0x0002, 0x0178, 0xa005, 0x11f8, 0x6944,
- 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4434, 0x11c0, 0x0066, 0x6e50,
- 0x080c, 0x450d, 0x006e, 0x0090, 0x0046, 0x2011, 0x920c, 0x2224,
- 0xc484, 0xc48c, 0x2412, 0x004e, 0x00c6, 0x080c, 0x4434, 0x1110,
- 0x080c, 0x4664, 0x8108, 0x1f04, 0x510d, 0x00ce, 0x080c, 0x1493,
- 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0x9252,
- 0x2004, 0xd0a4, 0x0580, 0x2061, 0x9566, 0x6100, 0xd184, 0x0178,
- 0x6858, 0xa084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, 0x6004,
- 0xa005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011,
- 0x0001, 0x6860, 0xa005, 0x1110, 0x2001, 0x001e, 0x8000, 0x6016,
- 0x6858, 0xa084, 0x00ff, 0x0178, 0x6006, 0x6858, 0x8007, 0xa084,
- 0x00ff, 0x0148, 0x600a, 0x6858, 0x8000, 0x1108, 0xc28d, 0x6202,
- 0x012e, 0x0804, 0x5300, 0x012e, 0x0804, 0x52fa, 0x012e, 0x0804,
- 0x52f4, 0x012e, 0x0804, 0x52f7, 0x0126, 0x2091, 0x8000, 0x7007,
- 0x0001, 0x2001, 0x9252, 0x2004, 0xd0a4, 0x05e0, 0x2061, 0x9566,
- 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0x6c48,
- 0xa484, 0x0003, 0x0170, 0x6958, 0xa18c, 0x00ff, 0x8001, 0x1120,
- 0x2100, 0xa210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0xa212,
- 0x02f0, 0xa484, 0x000c, 0x0188, 0x6958, 0x810f, 0xa18c, 0x00ff,
- 0xa082, 0x0004, 0x1120, 0x2100, 0xa318, 0x0288, 0x0030, 0xa082,
- 0x0004, 0x1168, 0x2100, 0xa31a, 0x0250, 0x6860, 0xa005, 0x0110,
- 0x8000, 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x5300, 0x012e,
- 0x0804, 0x52fd, 0x012e, 0x0804, 0x52fa, 0x0126, 0x2091, 0x8000,
- 0x7007, 0x0001, 0x2061, 0x9566, 0x6300, 0xd38c, 0x1120, 0x6308,
- 0x8318, 0x0220, 0x630a, 0x012e, 0x0804, 0x530e, 0x012e, 0x0804,
- 0x52fd, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c,
- 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x9566, 0x6000, 0xa084, 0xfcff,
- 0x6002, 0x00ce, 0x04d8, 0x6858, 0xa005, 0x0904, 0x521a, 0x685c,
- 0xa065, 0x0904, 0x5216, 0x2001, 0x922f, 0x2004, 0xa005, 0x0118,
- 0x080c, 0x849b, 0x0030, 0x6013, 0x0400, 0x2009, 0x0041, 0x080c,
- 0x7518, 0x6958, 0xa18c, 0xf600, 0xa186, 0x2000, 0x01b8, 0xa186,
- 0x0400, 0x01a0, 0xa186, 0x1000, 0x0140, 0xa186, 0x4000, 0x01b0,
- 0x6118, 0x2104, 0xc0fc, 0x200a, 0x0088, 0x00c6, 0x2061, 0x9566,
- 0x6000, 0xa084, 0xfdff, 0x6002, 0x00ce, 0x0040, 0x0026, 0x2009,
- 0x0000, 0x2011, 0xfdff, 0x080c, 0x585b, 0x002e, 0x684c, 0xd0c4,
- 0x0148, 0x2061, 0x9566, 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000,
- 0x0208, 0x600a, 0x00ce, 0x012e, 0x0804, 0x5300, 0x00ce, 0x012e,
- 0x0804, 0x52fa, 0x6954, 0xa186, 0x002e, 0x0d40, 0xa186, 0x002d,
- 0x0d28, 0xa186, 0x002a, 0x1130, 0x2001, 0x920c, 0x200c, 0xc194,
- 0x2102, 0x08e0, 0xa186, 0x0020, 0x0170, 0xa186, 0x0029, 0x1d30,
- 0x6944, 0xa18c, 0xff00, 0x810f, 0x080c, 0x4434, 0x1978, 0x6000,
- 0xc0e4, 0x6002, 0x0858, 0x685c, 0xa065, 0x09c0, 0x2001, 0x94dd,
- 0x2004, 0x6016, 0x0818, 0x2061, 0x9566, 0x6000, 0xd084, 0x0190,
- 0xd08c, 0x1904, 0x530e, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210,
- 0x0220, 0x6206, 0x012e, 0x0804, 0x530e, 0x012e, 0x6853, 0x0016,
- 0x0804, 0x5307, 0x6853, 0x0007, 0x0804, 0x5307, 0x6834, 0x8007,
- 0xa084, 0x00ff, 0x1118, 0x080c, 0x4fc0, 0x0078, 0x2030, 0x8001,
- 0x1120, 0x7007, 0x0001, 0x0051, 0x0040, 0x7007, 0x0006, 0x7012,
- 0x2d00, 0x7016, 0x701a, 0x704b, 0x5276, 0x0005, 0x00e6, 0x0126,
- 0x2091, 0x8000, 0x2009, 0x922f, 0x210c, 0x81ff, 0x1904, 0x52e9,
- 0x2009, 0x920c, 0x210c, 0xd194, 0x1904, 0x52f1, 0x6848, 0x2070,
- 0xae82, 0x9900, 0x0a04, 0x52dd, 0x2001, 0x9216, 0x2004, 0xae02,
- 0x1a04, 0x52dd, 0x2061, 0x9566, 0x6100, 0xa184, 0x0001, 0x0578,
- 0xa184, 0x0100, 0x1904, 0x52e0, 0xa184, 0x0200, 0x1904, 0x52e3,
- 0x601c, 0xa005, 0x1904, 0x52e6, 0x711c, 0xa186, 0x0006, 0x1520,
- 0x7018, 0xa005, 0x05f0, 0x2004, 0xd0e4, 0x15f0, 0xd0fc, 0x1598,
- 0x6853, 0x0000, 0x6803, 0x0000, 0x2d08, 0x7010, 0xa005, 0x1138,
- 0x7112, 0x2e60, 0x080c, 0x57ca, 0x012e, 0x00ee, 0x0005, 0x2068,
- 0x6800, 0xa005, 0x1de0, 0x6902, 0x012e, 0x00ee, 0x0005, 0x012e,
- 0x00ee, 0x6853, 0x0006, 0x04d8, 0x6944, 0xa18c, 0xff00, 0x810f,
- 0x080c, 0x4434, 0x11c8, 0x6000, 0xd0e4, 0x11b0, 0x711c, 0xa186,
- 0x0007, 0x1118, 0x6853, 0x0002, 0x0088, 0x6853, 0x0008, 0x0070,
- 0x6853, 0x000e, 0x0058, 0x6853, 0x0017, 0x0040, 0x6853, 0x0035,
- 0x0028, 0x6853, 0x0028, 0x0010, 0x6853, 0x0029, 0x012e, 0x00ee,
- 0x00b0, 0x6853, 0x002a, 0x0cd0, 0x2009, 0x003e, 0x0058, 0x2009,
- 0x0004, 0x0040, 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010,
- 0x2009, 0x0001, 0x6854, 0xa084, 0xff00, 0xa105, 0x6856, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x4809, 0x012e, 0x0005, 0x080c, 0x1493,
- 0x0005, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034,
- 0x7072, 0x7038, 0x7076, 0x0058, 0x7070, 0xa080, 0x0040, 0x7072,
- 0x1230, 0x7074, 0xa081, 0x0000, 0x7076, 0xa085, 0x0001, 0x7932,
- 0x7132, 0x0005, 0x00d6, 0x080c, 0x57c1, 0x00de, 0x0005, 0x00d6,
- 0x2011, 0x0004, 0x2204, 0xa085, 0x8002, 0x2012, 0x00de, 0x0005,
- 0x20e1, 0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000,
- 0x0118, 0xa086, 0x1000, 0x1520, 0x20e1, 0x0004, 0x3d60, 0xd1bc,
- 0x1170, 0x2100, 0xa084, 0xff00, 0xa086, 0x0500, 0x1140, 0x0026,
- 0x2c10, 0x080c, 0x566e, 0x002e, 0x0198, 0x0070, 0x3e60, 0xac84,
- 0x0003, 0x1170, 0xac82, 0x9900, 0x0258, 0x6858, 0xac02, 0x1240,
- 0x2009, 0x0047, 0x080c, 0x7518, 0x7a1c, 0xd284, 0x1988, 0x0005,
- 0xa016, 0x080c, 0x16c6, 0x0cc0, 0x0156, 0x0136, 0x0146, 0x20e1,
- 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0070, 0x1528, 0xa484, 0x7000,
- 0xa086, 0x1000, 0x11a0, 0x04a1, 0x01f0, 0x20e1, 0x3000, 0x7828,
- 0x7828, 0x080c, 0x53cc, 0x014e, 0x013e, 0x015e, 0x2009, 0x94ed,
- 0x2104, 0xa005, 0x1108, 0x0005, 0x080c, 0x6462, 0x0ce0, 0xa484,
- 0x7000, 0x1148, 0x00e9, 0x0190, 0x7000, 0xa084, 0xff00, 0xa086,
- 0x8100, 0x0d18, 0x0058, 0xd5a4, 0x0140, 0x080c, 0x1c26, 0x20e1,
- 0x9010, 0x2001, 0x0138, 0x2202, 0x0038, 0x0051, 0x080c, 0x9157,
- 0x20e1, 0x3000, 0x7828, 0x7828, 0x014e, 0x013e, 0x015e, 0x08d8,
- 0xa484, 0x01ff, 0x6882, 0xa005, 0x0160, 0xa080, 0x001f, 0xa084,
- 0x03f8, 0x80ac, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5,
- 0x0005, 0x20a9, 0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a,
- 0x53a5, 0xa085, 0x0001, 0x0ca0, 0x7000, 0xa084, 0xff00, 0xa08c,
- 0xf000, 0x8007, 0xa196, 0x0000, 0x1118, 0x0804, 0x5571, 0x0005,
- 0xa196, 0x2000, 0x1148, 0x6900, 0xa18e, 0x0001, 0x1118, 0x080c,
- 0x3a6a, 0x0ca8, 0x0039, 0x0c98, 0xa196, 0x8000, 0x1d80, 0x080c,
- 0x55f9, 0x0c68, 0x00c6, 0x6a80, 0x82ff, 0x0904, 0x5506, 0x7110,
- 0xa18c, 0xff00, 0x810f, 0xa196, 0x0001, 0x0120, 0xa196, 0x0023,
- 0x1904, 0x5506, 0xa08e, 0x0023, 0x1558, 0x080c, 0x565c, 0x0904,
- 0x5506, 0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, 0x1150, 0x7034,
- 0xa005, 0x1904, 0x5506, 0x2009, 0x0015, 0x080c, 0x7518, 0x0804,
- 0x5506, 0xa08e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c, 0x7518,
- 0x0804, 0x5506, 0xa08e, 0x0100, 0x1904, 0x5506, 0x7034, 0xa005,
- 0x1904, 0x5506, 0x2009, 0x0016, 0x080c, 0x7518, 0x0804, 0x5506,
- 0xa08e, 0x0022, 0x1904, 0x5506, 0x7030, 0xa08e, 0x0300, 0x1568,
- 0x68c8, 0xd0a4, 0x0510, 0xc0b5, 0x68ca, 0x7100, 0xa18c, 0x00ff,
- 0x696e, 0x7004, 0x6872, 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea,
- 0x0006, 0xa084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x2435, 0x7932,
- 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x240b, 0x694e, 0x703c,
- 0x00e6, 0x2071, 0x0140, 0x7086, 0x00ee, 0x7034, 0xa005, 0x1904,
- 0x5506, 0x2009, 0x0017, 0x0804, 0x54d9, 0xa08e, 0x0400, 0x1158,
- 0x7034, 0xa005, 0x1904, 0x5506, 0x68c8, 0xc0a5, 0x68ca, 0x2009,
- 0x0030, 0x0804, 0x54d9, 0xa08e, 0x0500, 0x1140, 0x7034, 0xa005,
- 0x1904, 0x5506, 0x2009, 0x0018, 0x0804, 0x54d9, 0xa08e, 0x2010,
- 0x1120, 0x2009, 0x0019, 0x0804, 0x54d9, 0xa08e, 0x2110, 0x1120,
- 0x2009, 0x001a, 0x0804, 0x54d9, 0xa08e, 0x5200, 0x1140, 0x7034,
- 0xa005, 0x1904, 0x5506, 0x2009, 0x001b, 0x0804, 0x54d9, 0xa08e,
- 0x5000, 0x1140, 0x7034, 0xa005, 0x1904, 0x5506, 0x2009, 0x001c,
- 0x0804, 0x54d9, 0xa08e, 0x1200, 0x1138, 0x7034, 0xa005, 0x1904,
- 0x5506, 0x2009, 0x0024, 0x04a8, 0xa08c, 0xff00, 0xa18e, 0x2400,
+ 0x0020, 0x1218, 0x00db, 0x012e, 0x0005, 0x012e, 0x080c, 0x4ece,
+ 0x0005, 0x0005, 0x0005, 0x00e6, 0x2071, 0x8be1, 0x700c, 0x0002,
+ 0x4e4d, 0x4e4d, 0x4e4d, 0x4e4f, 0x4e52, 0x00ee, 0x0005, 0x700f,
+ 0x0001, 0x0010, 0x700f, 0x0002, 0x00ee, 0x0005, 0x4ece, 0x4ece,
+ 0x4eea, 0x4ece, 0x4fc5, 0x4ece, 0x4ece, 0x4ece, 0x4ece, 0x4ece,
+ 0x4eea, 0x4ffe, 0x5041, 0x508a, 0x509e, 0x4ece, 0x4ece, 0x4f06,
+ 0x4eea, 0x4ece, 0x4ece, 0x4f1a, 0x5128, 0x5143, 0x4ece, 0x4f06,
+ 0x4ece, 0x4ece, 0x4ece, 0x4ece, 0x4f1a, 0x5143, 0x7020, 0x2068,
+ 0x080c, 0x149f, 0x0005, 0x700c, 0x0002, 0x4e82, 0x4e85, 0x4e93,
+ 0x4eab, 0x4eab, 0x080c, 0x4dca, 0x0005, 0x0126, 0x8001, 0x700e,
+ 0x7058, 0x0006, 0x080c, 0x51f4, 0x0120, 0x2091, 0x8000, 0x080c,
+ 0x4dca, 0x00de, 0x0048, 0x0126, 0x8001, 0x700e, 0x080c, 0x51f4,
+ 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000,
+ 0x6834, 0xa084, 0x00ff, 0xa08a, 0x001a, 0x1218, 0x003b, 0x012e,
+ 0x0005, 0x012e, 0x0419, 0x0005, 0x0005, 0x0005, 0x4ece, 0x4eea,
+ 0x4fb1, 0x4ece, 0x4eea, 0x4ece, 0x4eea, 0x4eea, 0x4ece, 0x4eea,
+ 0x4fb1, 0x4eea, 0x4eea, 0x4eea, 0x4eea, 0x4eea, 0x4ece, 0x4eea,
+ 0x4fb1, 0x4ece, 0x4ece, 0x4eea, 0x4ece, 0x4ece, 0x4ece, 0x4eea,
+ 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x7007, 0x0001,
+ 0x6838, 0xa084, 0x00ff, 0xc0d5, 0x683a, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x46a1, 0x012e, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084,
+ 0x00ff, 0xc0e5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x46a1,
+ 0x012e, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed,
+ 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x46a1, 0x012e, 0x0005,
+ 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x0126,
+ 0x2091, 0x8000, 0x080c, 0x46a1, 0x012e, 0x0005, 0x6834, 0x8007,
+ 0xa084, 0x00ff, 0x0988, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804,
+ 0x4f92, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b,
+ 0x4f92, 0x0005, 0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080,
+ 0x0024, 0x2098, 0x20a1, 0x8c0c, 0x53a3, 0x6858, 0x7012, 0xa082,
+ 0x0401, 0x1a70, 0x6884, 0xa08a, 0x0003, 0x1a50, 0xa080, 0x4f83,
+ 0x2005, 0x70c6, 0x7010, 0xa015, 0x0904, 0x4f77, 0x080c, 0x146f,
+ 0x1118, 0x7007, 0x000f, 0x0005, 0x2d00, 0x7022, 0x70c4, 0x2060,
+ 0x2c05, 0x6836, 0xe004, 0xad00, 0x7096, 0xe008, 0xa20a, 0x1210,
+ 0xa00e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, 0xa296, 0x0004,
+ 0x0108, 0xa108, 0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x080c,
+ 0x14d3, 0x7090, 0xa08e, 0x0100, 0x0170, 0xa086, 0x0200, 0x0118,
+ 0x7007, 0x0010, 0x0005, 0x7020, 0x2068, 0x080c, 0x149f, 0x7014,
+ 0x2068, 0x0804, 0x4ef8, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807,
+ 0x0000, 0x2d08, 0x2068, 0x6906, 0x711a, 0x0804, 0x4f32, 0x7014,
+ 0x2068, 0x7007, 0x0001, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e,
+ 0x0904, 0x515b, 0x0078, 0x4f86, 0x4f8a, 0x4f8e, 0x0002, 0x0011,
+ 0x0007, 0x0004, 0x000a, 0x000f, 0x0005, 0x0006, 0x0012, 0x000f,
+ 0x0005, 0x0006, 0x2009, 0x8b2f, 0x210c, 0x81ff, 0x11a8, 0x6838,
+ 0xa084, 0x00ff, 0x683a, 0x6853, 0x0000, 0x080c, 0x4170, 0x1108,
+ 0x0005, 0x080c, 0x4773, 0x0126, 0x2091, 0x8000, 0x080c, 0x7dc8,
+ 0x080c, 0x46a1, 0x012e, 0x0ca0, 0x2001, 0x0028, 0x2009, 0x0000,
+ 0x0c80, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, 0x711a, 0x7010,
+ 0x8001, 0x7012, 0x0118, 0x7007, 0x0006, 0x0030, 0x7014, 0x2068,
+ 0x7007, 0x0001, 0x7048, 0x080f, 0x0005, 0x7007, 0x0001, 0x6944,
+ 0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084, 0x00ff, 0x20a9, 0x0001,
+ 0xa096, 0x0001, 0x01b0, 0x2009, 0x0000, 0x20a9, 0x007e, 0xa096,
+ 0x0002, 0x0178, 0xa005, 0x11f8, 0x6944, 0x810f, 0xa18c, 0x00ff,
+ 0x080c, 0x430a, 0x11c0, 0x0066, 0x6e50, 0x080c, 0x43e6, 0x006e,
+ 0x0090, 0x0046, 0x2011, 0x8b0c, 0x2224, 0xc484, 0xc48c, 0x2412,
+ 0x004e, 0x00c6, 0x080c, 0x430a, 0x1110, 0x080c, 0x453d, 0x8108,
+ 0x1f04, 0x4ff2, 0x00ce, 0x080c, 0x149f, 0x0005, 0x0126, 0x2091,
+ 0x8000, 0x7007, 0x0001, 0x2001, 0x8b52, 0x2004, 0xd0a4, 0x0580,
+ 0x2061, 0x8e2a, 0x6100, 0xd184, 0x0178, 0x6858, 0xa084, 0x00ff,
+ 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, 0xa005, 0x1538, 0x6003,
+ 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, 0x0001, 0x6860, 0xa005,
+ 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, 0x6858, 0xa084, 0x00ff,
+ 0x0178, 0x6006, 0x6858, 0x8007, 0xa084, 0x00ff, 0x0148, 0x600a,
+ 0x6858, 0x8000, 0x1108, 0xc28d, 0x6202, 0x012e, 0x0804, 0x51e3,
+ 0x012e, 0x0804, 0x51dd, 0x012e, 0x0804, 0x51d7, 0x012e, 0x0804,
+ 0x51da, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0x8b52,
+ 0x2004, 0xd0a4, 0x05e0, 0x2061, 0x8e2a, 0x6000, 0xd084, 0x05b8,
+ 0x6204, 0x6308, 0xd08c, 0x1530, 0x6c48, 0xa484, 0x0003, 0x0170,
+ 0x6958, 0xa18c, 0x00ff, 0x8001, 0x1120, 0x2100, 0xa210, 0x0620,
+ 0x0028, 0x8001, 0x1508, 0x2100, 0xa212, 0x02f0, 0xa484, 0x000c,
+ 0x0188, 0x6958, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x1120,
+ 0x2100, 0xa318, 0x0288, 0x0030, 0xa082, 0x0004, 0x1168, 0x2100,
+ 0xa31a, 0x0250, 0x6860, 0xa005, 0x0110, 0x8000, 0x6016, 0x6206,
+ 0x630a, 0x012e, 0x0804, 0x51e3, 0x012e, 0x0804, 0x51e0, 0x012e,
+ 0x0804, 0x51dd, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061,
+ 0x8e2a, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a,
+ 0x012e, 0x0804, 0x51f1, 0x012e, 0x0804, 0x51e0, 0x0126, 0x00c6,
+ 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0148, 0x00c6,
+ 0x2061, 0x8e2a, 0x6000, 0xa084, 0xfcff, 0x6002, 0x00ce, 0x04d8,
+ 0x6858, 0xa005, 0x0904, 0x50ff, 0x685c, 0xa065, 0x0904, 0x50fb,
+ 0x2001, 0x8b2f, 0x2004, 0xa005, 0x0118, 0x080c, 0x7d3c, 0x0068,
+ 0x6013, 0x0400, 0x6027, 0x0000, 0x694c, 0xd1a4, 0x0110, 0x6950,
+ 0x6126, 0x2009, 0x0041, 0x080c, 0x6d3f, 0x6958, 0xa18c, 0xff00,
+ 0xa186, 0x2000, 0x0180, 0xa186, 0x0400, 0x0168, 0xa186, 0x1000,
+ 0x0108, 0x0088, 0x00c6, 0x2061, 0x8e2a, 0x6000, 0xa084, 0xfdff,
+ 0x6002, 0x00ce, 0x0040, 0x0026, 0x2009, 0x0000, 0x2011, 0xfdff,
+ 0x080c, 0x5734, 0x002e, 0x684c, 0xd0c4, 0x0148, 0x2061, 0x8e2a,
+ 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce,
+ 0x012e, 0x0804, 0x51e3, 0x00ce, 0x012e, 0x0804, 0x51dd, 0x6954,
+ 0xa186, 0x002e, 0x0d40, 0xa186, 0x002d, 0x0d28, 0xa186, 0x002a,
+ 0x1130, 0x2001, 0x8b0c, 0x200c, 0xc194, 0x2102, 0x08e0, 0xa186,
+ 0x0020, 0x0170, 0xa186, 0x0029, 0x1d30, 0x6944, 0xa18c, 0xff00,
+ 0x810f, 0x080c, 0x430a, 0x1978, 0x6000, 0xc0e4, 0x6002, 0x0858,
+ 0x685c, 0xa065, 0x09c0, 0x2001, 0x8da2, 0x2004, 0x6016, 0x0818,
+ 0x2061, 0x8e2a, 0x6000, 0xd084, 0x0190, 0xd08c, 0x1904, 0x51f1,
+ 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, 0x0220, 0x6206, 0x012e,
+ 0x0804, 0x51f1, 0x012e, 0x6853, 0x0016, 0x0804, 0x51ea, 0x6853,
+ 0x0007, 0x0804, 0x51ea, 0x6834, 0x8007, 0xa084, 0x00ff, 0x1118,
+ 0x080c, 0x4edc, 0x0078, 0x2030, 0x8001, 0x1120, 0x7007, 0x0001,
+ 0x0051, 0x0040, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a,
+ 0x704b, 0x515b, 0x0005, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2009,
+ 0x8b2f, 0x210c, 0x81ff, 0x1904, 0x51cc, 0x2009, 0x8b0c, 0x210c,
+ 0xd194, 0x1904, 0x51d4, 0x6848, 0x2070, 0xae82, 0x9200, 0x0a04,
+ 0x51c0, 0x2001, 0x8b16, 0x2004, 0xae02, 0x1a04, 0x51c0, 0x2061,
+ 0x8e2a, 0x6100, 0xa184, 0x0001, 0x0568, 0xa184, 0x0100, 0x1904,
+ 0x51c3, 0xa184, 0x0200, 0x1904, 0x51c6, 0x601c, 0xa005, 0x1904,
+ 0x51c9, 0x711c, 0xa186, 0x0006, 0x1510, 0x7018, 0xa005, 0x05e0,
+ 0x2004, 0xd0e4, 0x15e0, 0x6853, 0x0000, 0x6803, 0x0000, 0x2d08,
+ 0x7010, 0xa005, 0x1138, 0x7112, 0x2e60, 0x080c, 0x56a3, 0x012e,
+ 0x00ee, 0x0005, 0x2068, 0x6800, 0xa005, 0x1de0, 0x6902, 0x012e,
+ 0x00ee, 0x0005, 0x012e, 0x00ee, 0x6853, 0x0006, 0x04d8, 0x6944,
+ 0xa18c, 0xff00, 0x810f, 0x080c, 0x430a, 0x11c8, 0x6000, 0xd0e4,
+ 0x11b0, 0x711c, 0xa186, 0x0007, 0x1118, 0x6853, 0x0002, 0x0088,
+ 0x6853, 0x0008, 0x0070, 0x6853, 0x000e, 0x0058, 0x6853, 0x0017,
+ 0x0040, 0x6853, 0x0035, 0x0028, 0x6853, 0x0028, 0x0010, 0x6853,
+ 0x0029, 0x012e, 0x00ee, 0x00b0, 0x6853, 0x002a, 0x0cd0, 0x2009,
+ 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006, 0x0028,
+ 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, 0x6854, 0xa084, 0xff00,
+ 0xa105, 0x6856, 0x0126, 0x2091, 0x8000, 0x080c, 0x46a1, 0x012e,
+ 0x0005, 0x080c, 0x149f, 0x0005, 0x702c, 0x7130, 0x8108, 0xa102,
+ 0x0230, 0xa00e, 0x7034, 0x7072, 0x7038, 0x7076, 0x0058, 0x7070,
+ 0xa080, 0x0040, 0x7072, 0x1230, 0x7074, 0xa081, 0x0000, 0x7076,
+ 0xa085, 0x0001, 0x7932, 0x7132, 0x0005, 0x00d6, 0x080c, 0x569a,
+ 0x00de, 0x0005, 0x00d6, 0x2011, 0x0004, 0x2204, 0xa085, 0x8002,
+ 0x2012, 0x00de, 0x0005, 0x20e1, 0x0002, 0x3d08, 0x20e1, 0x2000,
+ 0x3d00, 0xa084, 0x7000, 0x0118, 0xa086, 0x1000, 0x11b8, 0x20e1,
+ 0x0004, 0x3d60, 0xd1bc, 0x1108, 0x3e60, 0xac84, 0x0003, 0x1170,
+ 0xac82, 0x9200, 0x0258, 0x6858, 0xac02, 0x1240, 0x2009, 0x0047,
+ 0x080c, 0x6d3f, 0x7a1c, 0xd284, 0x19f0, 0x0005, 0xa016, 0x080c,
+ 0x16d1, 0x0cc0, 0x0156, 0x0136, 0x0146, 0x20e1, 0x3000, 0x3d20,
+ 0x3e28, 0xa584, 0x0070, 0x1530, 0xa484, 0x7000, 0xa086, 0x1000,
+ 0x11a8, 0x080c, 0x5295, 0x01f0, 0x20e1, 0x3000, 0x7828, 0x7828,
+ 0x080c, 0x52b1, 0x014e, 0x013e, 0x015e, 0x2009, 0x8db2, 0x2104,
+ 0xa005, 0x1108, 0x0005, 0x080c, 0x5d10, 0x0ce0, 0xa484, 0x7000,
+ 0x1508, 0x0459, 0x01a8, 0x7000, 0xa084, 0xff00, 0xa086, 0x8100,
+ 0x0d18, 0x0070, 0xd5a4, 0x0158, 0x080c, 0x1b5e, 0x20e1, 0x9010,
+ 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0038, 0x00a9,
+ 0x080c, 0x8a02, 0x20e1, 0x3000, 0x7828, 0x7828, 0x014e, 0x013e,
+ 0x015e, 0x08c0, 0x0051, 0x0da0, 0x080c, 0x8a02, 0x20e1, 0x3000,
+ 0x7828, 0x7828, 0x080c, 0x5556, 0x0c88, 0xa484, 0x01ff, 0x6882,
+ 0xa005, 0x0160, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac, 0x20e1,
+ 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x0005, 0x20a9, 0x000c,
+ 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085, 0x0001,
+ 0x0ca0, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, 0x8007, 0xa196,
+ 0x0000, 0x1118, 0x0804, 0x5459, 0x0005, 0xa196, 0x2000, 0x1148,
+ 0x6900, 0xa18e, 0x0001, 0x1118, 0x080c, 0x399f, 0x0ca8, 0x0039,
+ 0x0c98, 0xa196, 0x8000, 0x1d80, 0x080c, 0x54e1, 0x0c68, 0x00c6,
+ 0x6a80, 0x82ff, 0x0904, 0x53ee, 0x7110, 0xa18c, 0xff00, 0x810f,
+ 0xa196, 0x0001, 0x0120, 0xa196, 0x0023, 0x1904, 0x53ee, 0xa08e,
+ 0x0023, 0x1558, 0x080c, 0x5544, 0x0904, 0x53ee, 0x7124, 0x610a,
+ 0x7030, 0xa08e, 0x0200, 0x1150, 0x7034, 0xa005, 0x1904, 0x53ee,
+ 0x2009, 0x0015, 0x080c, 0x6d3f, 0x0804, 0x53ee, 0xa08e, 0x0210,
+ 0x1130, 0x2009, 0x0015, 0x080c, 0x6d3f, 0x0804, 0x53ee, 0xa08e,
+ 0x0100, 0x1904, 0x53ee, 0x7034, 0xa005, 0x1904, 0x53ee, 0x2009,
+ 0x0016, 0x080c, 0x6d3f, 0x0804, 0x53ee, 0xa08e, 0x0022, 0x1904,
+ 0x53ee, 0x7030, 0xa08e, 0x0300, 0x1580, 0x68c8, 0xd0a4, 0x0528,
+ 0xc0b5, 0x68ca, 0x7100, 0xa18c, 0x00ff, 0x696e, 0x7004, 0x6872,
+ 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea, 0x0006, 0xa084, 0x00ff,
+ 0x0016, 0x2008, 0x080c, 0x2313, 0x7932, 0x7936, 0x001e, 0x000e,
+ 0x00fe, 0x080c, 0x22e9, 0x694e, 0x703c, 0x00e6, 0x2071, 0x0140,
+ 0x7086, 0x2071, 0x8b00, 0x709e, 0x00ee, 0x7034, 0xa005, 0x1904,
+ 0x53ee, 0x2009, 0x0017, 0x0804, 0x53c1, 0xa08e, 0x0400, 0x1158,
+ 0x7034, 0xa005, 0x1904, 0x53ee, 0x68c8, 0xc0a5, 0x68ca, 0x2009,
+ 0x0030, 0x0804, 0x53c1, 0xa08e, 0x0500, 0x1140, 0x7034, 0xa005,
+ 0x1904, 0x53ee, 0x2009, 0x0018, 0x0804, 0x53c1, 0xa08e, 0x2010,
+ 0x1120, 0x2009, 0x0019, 0x0804, 0x53c1, 0xa08e, 0x2110, 0x1120,
+ 0x2009, 0x001a, 0x0804, 0x53c1, 0xa08e, 0x5200, 0x1140, 0x7034,
+ 0xa005, 0x1904, 0x53ee, 0x2009, 0x001b, 0x0804, 0x53c1, 0xa08e,
+ 0x5000, 0x1140, 0x7034, 0xa005, 0x1904, 0x53ee, 0x2009, 0x001c,
+ 0x0804, 0x53c1, 0xa08e, 0x1200, 0x1138, 0x7034, 0xa005, 0x1904,
+ 0x53ee, 0x2009, 0x0024, 0x04a8, 0xa08c, 0xff00, 0xa18e, 0x2400,
0x1118, 0x2009, 0x002d, 0x0468, 0xa08c, 0xff00, 0xa18e, 0x5300,
0x1118, 0x2009, 0x002a, 0x0428, 0xa08e, 0x0f00, 0x1118, 0x2009,
0x0020, 0x00f8, 0xa08e, 0x5300, 0x1108, 0x00c8, 0xa08e, 0x6104,
- 0x11b0, 0x2011, 0x978d, 0x8208, 0x2204, 0xa082, 0x0004, 0x20a8,
+ 0x11b0, 0x2011, 0x908d, 0x8208, 0x2204, 0xa082, 0x0004, 0x20a8,
0x95ac, 0x95ac, 0x2011, 0x8015, 0x211c, 0x8108, 0x2124, 0x080c,
- 0x3698, 0x8108, 0x1f04, 0x54ca, 0x2009, 0x0023, 0x0010, 0x2009,
- 0x001d, 0x0016, 0x2011, 0x9783, 0x2204, 0x8211, 0x220c, 0x080c,
- 0x240b, 0x1530, 0x080c, 0x4400, 0x1518, 0x6612, 0x6516, 0x86ff,
+ 0x3617, 0x8108, 0x1f04, 0x53b2, 0x2009, 0x0023, 0x0010, 0x2009,
+ 0x001d, 0x0016, 0x2011, 0x9083, 0x2204, 0x8211, 0x220c, 0x080c,
+ 0x22e9, 0x1530, 0x080c, 0x42d6, 0x1518, 0x6612, 0x6516, 0x86ff,
0x0180, 0x001e, 0x0016, 0xa186, 0x0017, 0x1158, 0x686c, 0xa606,
0x1140, 0x6870, 0xa506, 0xa084, 0xff00, 0x1118, 0x6000, 0xc0f5,
- 0x6002, 0x00c6, 0x080c, 0x749c, 0x0168, 0x001e, 0x611a, 0x601f,
- 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0x7518, 0x00ce, 0x0005,
+ 0x6002, 0x00c6, 0x080c, 0x6cc2, 0x0168, 0x001e, 0x611a, 0x601f,
+ 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0x6d3f, 0x00ce, 0x0005,
0x001e, 0x0ce0, 0x00ce, 0x0ce0, 0x00e6, 0x00d6, 0x2028, 0x2130,
0xa696, 0x00ff, 0x1518, 0xa596, 0xfffd, 0x1120, 0x2009, 0x007f,
- 0x0804, 0x556d, 0xa596, 0xfffe, 0x1120, 0x2009, 0x007e, 0x0804,
- 0x556d, 0xa596, 0xfffc, 0x1120, 0x2009, 0x0080, 0x0804, 0x556d,
+ 0x0804, 0x5455, 0xa596, 0xfffe, 0x1120, 0x2009, 0x007e, 0x0804,
+ 0x5455, 0xa596, 0xfffc, 0x1120, 0x2009, 0x0080, 0x0804, 0x5455,
0xa594, 0xff00, 0xa296, 0xfc00, 0x1148, 0x2011, 0x0000, 0x2021,
- 0x0081, 0x20a9, 0x007e, 0x2071, 0x93ef, 0x00a0, 0x2011, 0x0000,
- 0x2019, 0x9232, 0x231c, 0xd3ac, 0x0138, 0x2021, 0x0000, 0x20a9,
- 0x00ff, 0x2071, 0x936e, 0x0030, 0x2021, 0x0081, 0x20a9, 0x007e,
- 0x2071, 0x93ef, 0x2e1c, 0x83ff, 0x1128, 0x82ff, 0x1198, 0x2410,
+ 0x0081, 0x20a9, 0x007e, 0x2071, 0x8cb5, 0x00a0, 0x2011, 0x0000,
+ 0x2019, 0x8b32, 0x231c, 0xd3ac, 0x0138, 0x2021, 0x0000, 0x20a9,
+ 0x00ff, 0x2071, 0x8c34, 0x0030, 0x2021, 0x0081, 0x20a9, 0x007e,
+ 0x2071, 0x8cb5, 0x2e1c, 0x83ff, 0x1128, 0x82ff, 0x1198, 0x2410,
0xc2fd, 0x0080, 0x2368, 0x6f10, 0x0006, 0x2100, 0xa706, 0x000e,
0x6b14, 0x1120, 0xa346, 0x1110, 0x2408, 0x0078, 0x87ff, 0x1110,
- 0x83ff, 0x0d58, 0x8420, 0x8e70, 0x1f04, 0x554a, 0x82ff, 0x1118,
+ 0x83ff, 0x0d58, 0x8420, 0x8e70, 0x1f04, 0x5432, 0x82ff, 0x1118,
0xa085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0xa006, 0x00de, 0x00ee,
- 0x0005, 0xa084, 0x0007, 0x000a, 0x0005, 0x557d, 0x557d, 0x557d,
- 0x557d, 0x557d, 0x557e, 0x5593, 0x55e6, 0x0005, 0x7110, 0xd1bc,
- 0x0188, 0x7120, 0x2160, 0xac8c, 0x0003, 0x1160, 0xac8a, 0x9900,
+ 0x0005, 0xa084, 0x0007, 0x000a, 0x0005, 0x5465, 0x5465, 0x5465,
+ 0x5465, 0x5465, 0x5466, 0x547b, 0x54ce, 0x0005, 0x7110, 0xd1bc,
+ 0x0188, 0x7120, 0x2160, 0xac8c, 0x0003, 0x1160, 0xac8a, 0x9200,
0x0248, 0x6858, 0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0046,
- 0x080c, 0x7518, 0x0005, 0x00c6, 0x7110, 0xd1bc, 0x1904, 0x55e4,
- 0x2011, 0x9783, 0x2204, 0x8211, 0x220c, 0x080c, 0x240b, 0x1904,
- 0x55e4, 0x080c, 0x4434, 0x1904, 0x55e4, 0x6000, 0xd0ec, 0x15e0,
+ 0x080c, 0x6d3f, 0x0005, 0x00c6, 0x7110, 0xd1bc, 0x1904, 0x54cc,
+ 0x2011, 0x9083, 0x2204, 0x8211, 0x220c, 0x080c, 0x22e9, 0x1904,
+ 0x54cc, 0x080c, 0x430a, 0x1904, 0x54cc, 0x6000, 0xd0ec, 0x15e0,
0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, 0x0160, 0x080c,
- 0x4dc5, 0x11d0, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x11a0,
- 0xa295, 0x0600, 0x6206, 0x00c6, 0x080c, 0x749c, 0x001e, 0x0520,
+ 0x4c42, 0x11d0, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x11a0,
+ 0xa295, 0x0600, 0x6206, 0x00c6, 0x080c, 0x6cc2, 0x001e, 0x0520,
0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6122, 0x2009,
- 0x0044, 0x080c, 0x7518, 0x00c0, 0x00c6, 0x080c, 0x749c, 0x001e,
+ 0x0044, 0x080c, 0x6d3f, 0x00c0, 0x00c6, 0x080c, 0x6cc2, 0x001e,
0x0198, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0xa286, 0x0004,
0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001,
- 0x080c, 0x603e, 0x080c, 0x6462, 0x00ce, 0x0005, 0x7110, 0xd1bc,
- 0x0178, 0x7020, 0x2060, 0xac84, 0x0003, 0x1150, 0xac82, 0x9900,
- 0x0238, 0x6858, 0xac02, 0x1220, 0x2009, 0x0045, 0x080c, 0x7518,
+ 0x080c, 0x58e2, 0x080c, 0x5d10, 0x00ce, 0x0005, 0x7110, 0xd1bc,
+ 0x0178, 0x7020, 0x2060, 0xac84, 0x0003, 0x1150, 0xac82, 0x9200,
+ 0x0238, 0x6858, 0xac02, 0x1220, 0x2009, 0x0045, 0x080c, 0x6d3f,
0x0005, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000, 0x1138,
- 0xa084, 0x000f, 0xa08a, 0x0006, 0x1a0c, 0x13fe, 0x000b, 0x0005,
- 0x560e, 0x560f, 0x560e, 0x560e, 0x5644, 0x5650, 0x0005, 0x7110,
- 0xd1bc, 0x1588, 0x700c, 0x7108, 0x080c, 0x240b, 0x1560, 0x080c,
- 0x4400, 0x1548, 0x6612, 0x6516, 0x6204, 0xa294, 0xff00, 0x8217,
+ 0xa084, 0x000f, 0xa08a, 0x0006, 0x1a0c, 0x1410, 0x000b, 0x0005,
+ 0x54f6, 0x54f7, 0x54f6, 0x54f6, 0x552c, 0x5538, 0x0005, 0x7110,
+ 0xd1bc, 0x1588, 0x700c, 0x7108, 0x080c, 0x22e9, 0x1560, 0x080c,
+ 0x42d6, 0x1548, 0x6612, 0x6516, 0x6204, 0xa294, 0xff00, 0x8217,
0xa286, 0x0004, 0x0118, 0xa286, 0x0006, 0x1178, 0x00c6, 0x080c,
- 0x749c, 0x001e, 0x01c0, 0x611a, 0x601f, 0x0005, 0x7120, 0x610a,
- 0x2009, 0x0088, 0x080c, 0x7518, 0x0070, 0x00c6, 0x080c, 0x749c,
+ 0x6cc2, 0x001e, 0x01c0, 0x611a, 0x601f, 0x0005, 0x7120, 0x610a,
+ 0x2009, 0x0088, 0x080c, 0x6d3f, 0x0070, 0x00c6, 0x080c, 0x6cc2,
0x001e, 0x0148, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x2009,
- 0x0001, 0x080c, 0x7518, 0x0005, 0x7110, 0xd1bc, 0x0140, 0x00a1,
- 0x0130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c, 0x7518, 0x0005,
+ 0x0001, 0x080c, 0x6d3f, 0x0005, 0x7110, 0xd1bc, 0x0140, 0x00a1,
+ 0x0130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c, 0x6d3f, 0x0005,
0x7110, 0xd1bc, 0x0140, 0x0041, 0x0130, 0x7124, 0x610a, 0x2009,
- 0x008a, 0x080c, 0x7518, 0x0005, 0x7020, 0x2060, 0xac84, 0x0003,
- 0x1158, 0xac82, 0x9900, 0x0240, 0x2001, 0x9216, 0x2004, 0xac02,
+ 0x008a, 0x080c, 0x6d3f, 0x0005, 0x7020, 0x2060, 0xac84, 0x0003,
+ 0x1158, 0xac82, 0x9200, 0x0240, 0x2001, 0x8b16, 0x2004, 0xac02,
0x1218, 0xa085, 0x0001, 0x0005, 0xa006, 0x0ce8, 0x00c6, 0x00d6,
- 0x00e6, 0x20e1, 0x0000, 0x3d08, 0xa18c, 0x00ff, 0xa18e, 0x00ff,
- 0x1150, 0x3e00, 0xa086, 0xffff, 0x1130, 0x2001, 0x94c6, 0x2064,
- 0x2009, 0x00ff, 0x0060, 0x20e1, 0x0001, 0x3d08, 0x3e00, 0x0156,
- 0x080c, 0x240b, 0x015e, 0x1578, 0x080c, 0x4434, 0x1560, 0x2138,
- 0x873f, 0x2c00, 0x2070, 0x20e1, 0x0003, 0x3d18, 0x831f, 0xa39c,
- 0x00ff, 0x0036, 0x0036, 0x003e, 0x003e, 0x20e1, 0x2000, 0x3d00,
- 0xa084, 0x7000, 0xa086, 0x1000, 0x0120, 0x080c, 0x5cc0, 0x1198,
- 0x0040, 0x080c, 0x749c, 0x0178, 0x2e00, 0x601a, 0x620a, 0x601f,
- 0x0009, 0x2009, 0x0101, 0x080c, 0x7518, 0xa085, 0x0001, 0x00ee,
- 0x00de, 0x00ce, 0x0005, 0xa006, 0x00ee, 0x00de, 0x00ce, 0x0005,
- 0x2071, 0x94f8, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a,
- 0x7012, 0x7017, 0x9900, 0x7007, 0x0000, 0x7026, 0x702b, 0x6f2b,
- 0x7032, 0x7037, 0x6f69, 0x703b, 0xffff, 0x703f, 0xffff, 0x0005,
- 0x2071, 0x94f8, 0x1d04, 0x5720, 0x2091, 0x6000, 0x700c, 0x8001,
- 0x700e, 0x1120, 0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091,
- 0x8000, 0x7024, 0xa00d, 0x0158, 0x7020, 0x8001, 0x7022, 0x1138,
- 0x7023, 0x0009, 0x8109, 0x7126, 0x1110, 0x7028, 0x080f, 0x7030,
- 0xa00d, 0x0158, 0x702c, 0x8001, 0x702e, 0x1138, 0x702f, 0x0009,
- 0x8109, 0x7132, 0x1110, 0x7034, 0x080f, 0x7038, 0xa005, 0x0118,
- 0x0310, 0x8001, 0x703a, 0x703c, 0xa005, 0x0118, 0x0310, 0x8001,
- 0x703e, 0x7018, 0xa00d, 0x0158, 0x7008, 0x8001, 0x700a, 0x1138,
- 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f, 0x012e,
- 0x7004, 0x0002, 0x5746, 0x5747, 0x575f, 0x00e6, 0x2071, 0x94f8,
- 0x7018, 0xa005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee,
- 0x0005, 0x00e6, 0x0006, 0x2071, 0x94f8, 0x701c, 0xa206, 0x1110,
- 0x701a, 0x701e, 0x000e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x94f8,
- 0x6088, 0xa102, 0x0208, 0x618a, 0x00ee, 0x0005, 0x0005, 0x7110,
- 0x080c, 0x4434, 0x1158, 0x6088, 0x8001, 0x0240, 0x608a, 0x1130,
- 0x0126, 0x2091, 0x8000, 0x080c, 0x6462, 0x012e, 0x8108, 0xa182,
- 0x00ff, 0x0218, 0xa00e, 0x7007, 0x0002, 0x7112, 0x0005, 0x7014,
- 0x2060, 0x0126, 0x2091, 0x8000, 0x6014, 0xa005, 0x0518, 0x8001,
- 0x6016, 0x1500, 0x611c, 0xa186, 0x0003, 0x0130, 0xa186, 0x0006,
- 0x0118, 0xa186, 0x0009, 0x11a0, 0x6010, 0x2068, 0x6854, 0xa08a,
- 0x199a, 0x0270, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a, 0x0210,
- 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x0010,
- 0x080c, 0x8185, 0x012e, 0xac88, 0x000c, 0x7116, 0x2001, 0x9217,
- 0x2004, 0xa102, 0x0220, 0x7017, 0x9900, 0x7007, 0x0000, 0x0005,
- 0x00e6, 0x2071, 0x94f8, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee,
- 0x0005, 0x2001, 0x9501, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071,
- 0x94f8, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0x9504,
- 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x94f8, 0x711a, 0x721e,
- 0x700b, 0x0009, 0x00ee, 0x0005, 0x00c6, 0x2061, 0x9566, 0x00ce,
- 0x0005, 0xa184, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x9566,
- 0x2060, 0x0005, 0x6854, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999,
- 0xa005, 0x1150, 0x00c6, 0x2061, 0x9566, 0x6014, 0x00ce, 0xa005,
- 0x1138, 0x2001, 0x001e, 0x0020, 0xa08e, 0xffff, 0x1108, 0xa006,
- 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c, 0x00c0,
- 0xa18e, 0x00c0, 0x0588, 0xd0b4, 0x1138, 0xd0bc, 0x11f0, 0x2009,
- 0x0006, 0x080c, 0x5838, 0x0005, 0xd0fc, 0x0140, 0xa084, 0x0003,
- 0xa08e, 0x0003, 0x05b8, 0xa08e, 0x0000, 0x15a0, 0x2009, 0x9273,
- 0x2104, 0xd084, 0x0128, 0x2009, 0x0042, 0x080c, 0x7518, 0x0005,
- 0x2009, 0x0043, 0x080c, 0x7518, 0x0005, 0xd0fc, 0x0140, 0xa084,
- 0x0003, 0xa08e, 0x0003, 0x01f0, 0xa08e, 0x0000, 0x11d8, 0x2009,
- 0x0042, 0x080c, 0x7518, 0x0005, 0xd0fc, 0x0168, 0xa084, 0x0003,
- 0xa08e, 0x0003, 0x0178, 0xa08e, 0x0002, 0x0138, 0x2009, 0x0041,
- 0x080c, 0x7518, 0x0005, 0x0051, 0x0ce8, 0x2009, 0x0043, 0x080c,
- 0x7518, 0x0cc0, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001,
- 0x6010, 0xa0ec, 0xf000, 0x01f0, 0x2068, 0x6952, 0x6800, 0x6012,
- 0xa186, 0x0001, 0x1188, 0x694c, 0xa18c, 0x8100, 0xa18e, 0x8100,
- 0x1158, 0x00c6, 0x2061, 0x9566, 0x6200, 0xd28c, 0x1120, 0x6204,
- 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x4809, 0x6010, 0xa06d,
- 0x190c, 0x57ca, 0x0005, 0x0156, 0x00c6, 0x2061, 0x9566, 0x6000,
- 0x81ff, 0x0110, 0xa205, 0x0008, 0xa204, 0x6002, 0x00ce, 0x015e,
- 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0xa005, 0x0120, 0x8001,
- 0x680a, 0xa085, 0x0001, 0x0005, 0x2071, 0x9349, 0x7003, 0x0006,
- 0x7007, 0x0000, 0x700f, 0x0000, 0x7013, 0x0001, 0x702f, 0x0006,
- 0x7033, 0x0001, 0x7063, 0x0000, 0x0005, 0x00e6, 0x2071, 0x9349,
- 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834, 0x7026, 0x705a, 0x6838,
- 0x702a, 0x705e, 0x6824, 0x7016, 0x683c, 0x701a, 0x2009, 0x0070,
- 0x200a, 0xa005, 0x0150, 0x2009, 0x0000, 0xa188, 0x000c, 0x8001,
- 0x1de0, 0x2100, 0xa210, 0x1208, 0x8318, 0x7252, 0x7356, 0x7010,
- 0xc084, 0x7012, 0x7007, 0x0001, 0x700f, 0x0000, 0xa006, 0x00ee,
- 0x0005, 0x2b78, 0x2071, 0x9349, 0x7004, 0x004b, 0x700c, 0x0002,
- 0x58bb, 0x58b4, 0x58b4, 0x0005, 0x58c5, 0x5913, 0x5914, 0x5915,
- 0x5916, 0x5929, 0x592a, 0x700c, 0x0cba, 0x2f00, 0xa080, 0x0070,
- 0x2004, 0x2f08, 0xa188, 0x0070, 0x210c, 0xa106, 0x0150, 0x2f00,
- 0xa080, 0x0070, 0x2004, 0x2f08, 0xa188, 0x0070, 0x210c, 0xa106,
- 0x15c8, 0x7018, 0xa10a, 0x05b0, 0x1210, 0x7114, 0xa10a, 0xa192,
- 0x000a, 0x0210, 0x2009, 0x000a, 0x00d6, 0x0016, 0x2001, 0x9281,
- 0xa080, 0x0011, 0x2014, 0x2001, 0x9363, 0xa080, 0x0005, 0x2004,
- 0xa100, 0xa202, 0x001e, 0x00de, 0x02e8, 0x080c, 0x5976, 0x2200,
- 0xa102, 0x0208, 0x2208, 0x713a, 0x080c, 0x5a67, 0x2100, 0x7042,
- 0x2001, 0x0002, 0x7037, 0x0000, 0x0126, 0x0006, 0x2091, 0x8000,
- 0x2009, 0x9508, 0x2104, 0xc095, 0x200a, 0x000e, 0x700e, 0x012e,
- 0x080c, 0x14df, 0x0005, 0x0005, 0x0005, 0x0005, 0x700c, 0x0002,
- 0x591b, 0x591e, 0x5928, 0x080c, 0x58c3, 0x0005, 0x0126, 0x8001,
- 0x700e, 0x7138, 0x0041, 0x2091, 0x8000, 0x080c, 0x58c3, 0x012e,
- 0x0005, 0x0005, 0x0005, 0x7018, 0xa100, 0x7214, 0xa21a, 0x1130,
- 0x701c, 0x7052, 0x7020, 0x7056, 0xa006, 0x0068, 0x0006, 0x080c,
- 0x5a67, 0x2100, 0x7250, 0xa210, 0x7252, 0x1220, 0x7054, 0xa081,
- 0x0000, 0x7056, 0x000e, 0x2f08, 0xa188, 0x0070, 0x200a, 0x701a,
- 0x0005, 0x00e6, 0x2071, 0x9349, 0x700c, 0x0002, 0x5951, 0x5951,
- 0x5953, 0x00ee, 0x0005, 0x700f, 0x0001, 0x00ee, 0x0005, 0x00d6,
- 0x00e6, 0x2071, 0x9363, 0xa006, 0x7006, 0x700e, 0x701a, 0x701e,
- 0x7022, 0x702a, 0x7026, 0x080c, 0x5b1b, 0x0170, 0x080c, 0x5b4d,
- 0x0158, 0x2d00, 0x7002, 0x700a, 0x701a, 0x7013, 0x0001, 0x701f,
- 0x0007, 0x00ee, 0x00de, 0x0005, 0xa00e, 0x0cd8, 0x00e6, 0x00d6,
- 0x00c6, 0x2071, 0x9363, 0x721c, 0x2100, 0xa202, 0x1618, 0x080c,
- 0x5b4d, 0x090c, 0x13fe, 0x7018, 0xa005, 0x1160, 0x2d00, 0x7002,
- 0x700a, 0x701a, 0xa006, 0x7006, 0x700e, 0x6806, 0x6802, 0x7012,
- 0x701e, 0x0038, 0x2060, 0x6806, 0x2d00, 0x6002, 0x701a, 0x6803,
- 0x0000, 0x7010, 0x8000, 0x7012, 0x701c, 0xa080, 0x0007, 0x701e,
- 0x721c, 0x08d0, 0x721c, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x0156,
- 0x0136, 0x0146, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x9363,
- 0x7300, 0xa398, 0x0003, 0x7104, 0x080c, 0x5a67, 0x810c, 0x2100,
- 0xa318, 0x8003, 0x2228, 0x2021, 0x0054, 0xa402, 0xa532, 0x0208,
- 0x2028, 0x2500, 0x8004, 0x20a8, 0x23a0, 0xe000, 0xe000, 0xe000,
- 0x53a5, 0x2508, 0x080c, 0x5a70, 0x2130, 0x7014, 0xa600, 0x7016,
- 0x2600, 0x711c, 0xa102, 0x701e, 0x7004, 0xa600, 0x2008, 0xa082,
- 0x0007, 0x1180, 0x7000, 0x2004, 0xa005, 0x1140, 0x2009, 0x0001,
- 0x0026, 0x080c, 0x5976, 0x002e, 0x7000, 0x2004, 0x7002, 0x7007,
- 0x0000, 0x0008, 0x7106, 0x2500, 0xa212, 0x1910, 0x012e, 0x00ee,
- 0x014e, 0x013e, 0x015e, 0x0005, 0x0016, 0x0026, 0x00e6, 0x00d6,
- 0x04e9, 0x15c8, 0x2170, 0x2805, 0xac68, 0x2900, 0x0002, 0x5a0f,
- 0x5a0f, 0x5a13, 0x5a0f, 0x5a13, 0x5a0f, 0x5a0f, 0x5a0f, 0x5a0f,
- 0x5a0f, 0x5a1c, 0x5a0f, 0x5a1c, 0x5a0f, 0x5a0f, 0x5a0f, 0x080c,
- 0x13fe, 0xa005, 0x00d8, 0x7000, 0x6802, 0x7004, 0x6806, 0x7010,
- 0x680a, 0x680f, 0x0000, 0x0060, 0x7010, 0x6812, 0x6817, 0x0000,
- 0x7000, 0x6802, 0x7004, 0x6806, 0x7008, 0x680a, 0x700c, 0x680e,
- 0x00de, 0x685c, 0x8000, 0x685e, 0x00d6, 0xa006, 0x00de, 0x00ee,
- 0x002e, 0x001e, 0x0005, 0xa085, 0x0001, 0x0cc0, 0x00e6, 0x0036,
- 0x2071, 0x9363, 0x7014, 0xa005, 0x0538, 0x8001, 0x7016, 0x7008,
- 0xa080, 0x0003, 0x710c, 0x2110, 0x0411, 0x810c, 0xa118, 0x8210,
- 0xa282, 0x0007, 0x11b0, 0x7008, 0x2004, 0xa005, 0x0178, 0x00d6,
- 0x0006, 0x7008, 0x2068, 0x080c, 0x5b5c, 0x000e, 0x2068, 0x6807,
- 0x0000, 0x700a, 0x00de, 0x7010, 0x8001, 0x7012, 0x700f, 0x0000,
- 0x0008, 0x720e, 0x2308, 0xa006, 0x003e, 0x00ee, 0x0005, 0x0006,
- 0x810b, 0x810b, 0x2100, 0x810b, 0xa100, 0x2008, 0x000e, 0x0005,
- 0x0006, 0x0026, 0x2100, 0xa005, 0x0160, 0xa092, 0x000c, 0x0248,
- 0x2009, 0x0000, 0x8108, 0xa082, 0x000c, 0x1de0, 0x002e, 0x000e,
- 0x0005, 0x2009, 0x0000, 0x0cd0, 0x2d00, 0xa0b8, 0x0008, 0x690c,
- 0x6810, 0x2019, 0x0001, 0x2031, 0x5ab2, 0xa112, 0x0220, 0x0118,
- 0x8318, 0x2208, 0x0cd0, 0x6808, 0xa005, 0x0108, 0x8318, 0x233a,
- 0x6804, 0xd084, 0x2300, 0x2021, 0x0001, 0x1150, 0xa082, 0x0003,
- 0x0967, 0x0a67, 0x8420, 0xa082, 0x0007, 0x0967, 0x0a67, 0x0cd0,
- 0xa082, 0x0002, 0x0967, 0x0a67, 0x8420, 0xa082, 0x0005, 0x0967,
- 0x0a67, 0x0cd0, 0x6c1a, 0x2d00, 0xa0b8, 0x0007, 0x00e6, 0x2071,
- 0x9200, 0x7128, 0x6810, 0x2019, 0x0001, 0xa10a, 0x0118, 0x0210,
- 0x8318, 0x0cd8, 0x2031, 0x5ac5, 0x0870, 0x6c16, 0x00ee, 0x0005,
- 0x00e6, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2e00, 0x2060, 0x2071,
- 0x9363, 0x2009, 0x0001, 0x0026, 0x080c, 0x5976, 0x002e, 0x7300,
- 0xa398, 0x0003, 0x7104, 0x080c, 0x5a67, 0x810c, 0x2100, 0xa318,
- 0x6834, 0xa084, 0x00ff, 0xa086, 0x0024, 0x00d6, 0x2368, 0x1138,
- 0x6000, 0x6802, 0x6004, 0x6806, 0x6008, 0x6812, 0x0050, 0x6000,
- 0x6802, 0x6004, 0x6806, 0x6008, 0x680a, 0x600c, 0x680e, 0x6010,
- 0x6812, 0x00de, 0x7014, 0x8000, 0x7016, 0x711c, 0x8109, 0x711e,
- 0x7004, 0x8000, 0x2008, 0xa082, 0x0007, 0x1180, 0x7000, 0x2004,
- 0xa005, 0x1140, 0x2009, 0x0001, 0x0026, 0x080c, 0x5976, 0x002e,
- 0x7000, 0x2004, 0x7002, 0x7007, 0x0000, 0x0008, 0x7106, 0x012e,
- 0x00ce, 0x00ee, 0x0005, 0x00d6, 0x0046, 0x0126, 0x2091, 0x8000,
- 0x2001, 0x9281, 0xa080, 0x0011, 0x2004, 0x8003, 0x2020, 0x080c,
- 0x145f, 0x01d0, 0x2d00, 0x7026, 0x6803, 0x0000, 0x6807, 0x0000,
- 0x080c, 0x145f, 0x0188, 0x7024, 0x6802, 0x6807, 0x0000, 0x2d00,
- 0x7026, 0xa4a2, 0x0007, 0x0110, 0x0208, 0x0c90, 0xa085, 0x0001,
- 0x012e, 0x004e, 0x00de, 0x0005, 0x7024, 0xa005, 0x0dc8, 0x2068,
- 0x2024, 0x080c, 0x1493, 0x2400, 0x0cc0, 0x0126, 0x2091, 0x8000,
- 0x7024, 0x2068, 0xa005, 0x0130, 0x2004, 0x7026, 0x6803, 0x0000,
- 0x6807, 0x0000, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7024,
- 0x6802, 0x2d00, 0x7026, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x00d6,
- 0x00c6, 0x0086, 0x0046, 0x0056, 0x0026, 0x2031, 0x0000, 0x2001,
- 0x934a, 0x2004, 0xa005, 0x0904, 0x5bee, 0x2071, 0x9281, 0x20e1,
- 0x0002, 0x3d08, 0xd19c, 0x0140, 0x2069, 0x9200, 0x6a28, 0x761c,
- 0x7114, 0x2041, 0x0000, 0x0028, 0x7118, 0x720c, 0x7620, 0x7008,
- 0x2040, 0x080c, 0x5d03, 0x0904, 0x5bee, 0x7004, 0xd084, 0x1128,
- 0x2021, 0x0024, 0x2029, 0x0002, 0x0020, 0x2021, 0x002c, 0x2029,
- 0x000a, 0x080c, 0x147c, 0x0904, 0x5bee, 0x2d00, 0x2060, 0x6436,
- 0x0016, 0x20e1, 0x0001, 0x3d08, 0x3e00, 0xa18c, 0x00ff, 0x6142,
- 0x603e, 0x001e, 0x6746, 0x2700, 0xa086, 0xff00, 0x1118, 0x6063,
- 0x0000, 0x0010, 0x6063, 0x0003, 0xa006, 0x6002, 0x602a, 0x602e,
- 0x6006, 0x603a, 0x604a, 0x6052, 0x6056, 0x605e, 0x6066, 0x604e,
- 0x2800, 0x606a, 0x604c, 0xc0ad, 0x604e, 0x665a, 0x2c00, 0x2078,
- 0x0479, 0x607f, 0xffff, 0x6083, 0x0000, 0x8109, 0x0180, 0x080c,
- 0x147c, 0x01c0, 0x2d00, 0x7806, 0x2f00, 0x6802, 0x6d36, 0xa006,
- 0x2d00, 0x2520, 0x00e9, 0x2d00, 0x2078, 0x8109, 0x1d80, 0x2c00,
- 0xa005, 0x002e, 0x005e, 0x004e, 0x008e, 0x00ce, 0x00de, 0x00ee,
- 0x00fe, 0x0005, 0x2c00, 0x2068, 0x080c, 0x14a3, 0x2600, 0x2071,
- 0x9363, 0x7120, 0xa102, 0x0a0c, 0x13fe, 0x7022, 0xa006, 0x0c48,
- 0x00d6, 0x00c6, 0x0136, 0x0146, 0x0156, 0x0016, 0x2068, 0x2400,
- 0xa084, 0x000f, 0xa080, 0x1f59, 0x2005, 0x2005, 0xad60, 0x2c00,
- 0x2d08, 0xa188, 0x0030, 0xa102, 0x20a8, 0x2c00, 0x20a0, 0x2001,
- 0xffff, 0x40a4, 0x001e, 0x015e, 0x014e, 0x013e, 0x00ce, 0x00de,
- 0x0005, 0x00c6, 0x00e6, 0x00f6, 0x6858, 0x2071, 0x9363, 0x7120,
- 0xa102, 0x0a0c, 0x13fe, 0x7022, 0x6960, 0x694e, 0x697c, 0x2009,
- 0xffff, 0x7818, 0xa102, 0xe000, 0x0006, 0x0006, 0x0006, 0x0006,
- 0x0006, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x6852, 0x684b,
- 0x0000, 0x6868, 0xa005, 0x0118, 0x6848, 0xc085, 0x684a, 0x2d00,
- 0xa080, 0x0015, 0x2038, 0x2031, 0x0018, 0x6864, 0x2020, 0x683a,
- 0x685c, 0xa08a, 0x00ff, 0x1a0c, 0x13fe, 0x2028, 0x2d00, 0x2060,
- 0x2078, 0x6934, 0xa18c, 0x000f, 0xa188, 0x1f59, 0x2145, 0x685c,
- 0x2050, 0xa005, 0x0530, 0x2805, 0xac70, 0x6834, 0xa084, 0x00ff,
- 0xa086, 0x0024, 0x1110, 0x7008, 0x0040, 0x6834, 0xa084, 0x00ff,
- 0xa086, 0x002c, 0x190c, 0x13fe, 0x7010, 0x0006, 0x2400, 0xa005,
- 0x000e, 0x0168, 0x203a, 0x8738, 0x8631, 0x090c, 0x13fe, 0x8421,
- 0x8529, 0x0138, 0x080c, 0x1f1b, 0x090c, 0x13fe, 0x08e0, 0x080c,
- 0x5ac8, 0x6837, 0x0023, 0x00fe, 0x00ee, 0x00ce, 0x0005, 0x00e6,
- 0x00c6, 0x00a6, 0x0086, 0x0056, 0x6858, 0x2071, 0x9363, 0x7120,
- 0xa102, 0x0a0c, 0x13fe, 0x7022, 0x2d00, 0x2060, 0x6934, 0xa18c,
- 0x000f, 0xa188, 0x1f59, 0x2145, 0x685c, 0x2050, 0xa005, 0x01d0,
- 0x2028, 0x2805, 0xac70, 0x6834, 0xa084, 0x00ff, 0xa086, 0x0024,
- 0x1110, 0x7008, 0x0008, 0x7010, 0x0006, 0xa086, 0xffff, 0x000e,
- 0x0110, 0x080c, 0x5ac8, 0x8529, 0x0128, 0x080c, 0x1f1b, 0x090c,
- 0x13fe, 0x0c38, 0x005e, 0x008e, 0x00ae, 0x00ce, 0x00ee, 0x0005,
- 0x70ac, 0xa005, 0x0138, 0x2060, 0x6008, 0xa306, 0x0110, 0x600c,
- 0x0cc0, 0x0005, 0xa085, 0x0001, 0x0ce0, 0x70ac, 0x600e, 0x2c00,
- 0x70ae, 0x0005, 0x00f6, 0x00d6, 0x0036, 0x70ac, 0xa005, 0x090c,
- 0x13fe, 0x2068, 0x2079, 0x0000, 0x2c08, 0xa11e, 0x1118, 0x680c,
- 0x70ae, 0x0060, 0xa106, 0x0140, 0x2d00, 0x2078, 0x680c, 0xa005,
- 0x090c, 0x13fe, 0x2068, 0x0cb0, 0x6b0c, 0x7b0e, 0x600f, 0x0000,
- 0x003e, 0x00de, 0x00fe, 0x0005, 0x00e6, 0x080c, 0x5c87, 0x6018,
- 0x2070, 0xa006, 0x70b2, 0x70b6, 0x080c, 0x14a3, 0x0899, 0x080c,
- 0x74f2, 0x00ee, 0x0005, 0x00d6, 0x0026, 0x0016, 0x2061, 0x9363,
- 0x6020, 0x6414, 0xa600, 0xa42a, 0x02c8, 0x6022, 0x2069, 0x9281,
- 0x6828, 0x6114, 0xa102, 0x1260, 0x2011, 0x8025, 0x080c, 0x3698,
- 0xa080, 0x0013, 0x2004, 0xa080, 0x0000, 0x200c, 0x8108, 0x2102,
- 0xa085, 0x0001, 0x001e, 0x002e, 0x00de, 0x0005, 0x2069, 0x9281,
- 0x6804, 0xd09c, 0x0120, 0x2011, 0x8026, 0x080c, 0x3698, 0x2001,
- 0x9281, 0xa080, 0x0013, 0x2004, 0xa080, 0x0001, 0x200c, 0x8108,
- 0x2102, 0xa006, 0x2031, 0x0000, 0x0c28, 0x0066, 0x6000, 0xa0b2,
- 0x0010, 0x1a0c, 0x13fe, 0x0013, 0x006e, 0x0005, 0x5d56, 0x5d56,
- 0x5d56, 0x5d58, 0x5db1, 0x5d56, 0x5d56, 0x5d56, 0x5de6, 0x5d56,
- 0x5e34, 0x5d56, 0x5d56, 0x5d56, 0x5d56, 0x5d56, 0x080c, 0x13fe,
- 0xa182, 0x0100, 0x0002, 0x5d6a, 0x5d6a, 0x5d6a, 0x5d6c, 0x5d85,
- 0x5d9d, 0x5d6a, 0x5d6a, 0x5d6a, 0x5d6a, 0x5d6a, 0x5d6a, 0x5d6a,
- 0x5d6a, 0x5d6a, 0x080c, 0x13fe, 0x00d6, 0x080c, 0x641b, 0x080c,
- 0x651c, 0x6110, 0x2168, 0x684b, 0x0000, 0x00d6, 0x6018, 0x2068,
- 0x6008, 0x68b6, 0x68bb, 0x0500, 0xa006, 0x68b2, 0x00de, 0x080c,
- 0x4809, 0x080c, 0x74f2, 0x00de, 0x0005, 0x080c, 0x641b, 0x00f6,
- 0x00d6, 0x6110, 0x2178, 0x080c, 0x82ee, 0x0140, 0x784b, 0x0006,
- 0xa006, 0x70b2, 0x70b6, 0x2f68, 0x080c, 0x4809, 0x00de, 0x00fe,
- 0x080c, 0x74f2, 0x080c, 0x651c, 0x0005, 0x080c, 0x641b, 0x080c,
- 0x266c, 0x00d6, 0x6110, 0x2168, 0x080c, 0x82ee, 0x0120, 0x684b,
- 0x0029, 0x080c, 0x4809, 0x00de, 0x080c, 0x74f2, 0x080c, 0x651c,
- 0x0005, 0xa182, 0x0100, 0x0002, 0x5dc3, 0x5dc5, 0x5dcd, 0x5dc3,
- 0x5dc3, 0x5dc3, 0x5de1, 0x5dc3, 0x5dc3, 0x5dc3, 0x5dc3, 0x5dc3,
- 0x5dc3, 0x5dc3, 0x5dc3, 0x080c, 0x13fe, 0x20e1, 0x0005, 0x3d18,
- 0x3e20, 0x2c10, 0x080c, 0x16c6, 0x0005, 0x00d6, 0x00e6, 0x6110,
- 0x2168, 0x080c, 0x5c19, 0x080c, 0x4809, 0x6018, 0x2070, 0xa006,
- 0x70b2, 0x70b6, 0x080c, 0x5cd2, 0x00ee, 0x00de, 0x080c, 0x74f2,
- 0x0005, 0x080c, 0x5cf4, 0x080c, 0x473b, 0x0005, 0xa182, 0x0100,
- 0x0002, 0x5dfb, 0x5e16, 0x5df9, 0x5df9, 0x5df9, 0x5df9, 0x5df9,
- 0x5df9, 0x5df9, 0x5df9, 0x5df9, 0x5df9, 0x5df9, 0x5df9, 0x5df9,
- 0x5df9, 0x080c, 0x13fe, 0x00d6, 0x6003, 0x0003, 0x6106, 0x6010,
- 0x2068, 0x687c, 0x680a, 0x6880, 0x680e, 0x6813, 0x0000, 0x6817,
- 0x0000, 0x00de, 0x2c10, 0x080c, 0x1c88, 0x080c, 0x605b, 0x0126,
- 0x2091, 0x8000, 0x080c, 0x651c, 0x012e, 0x0005, 0x6003, 0x0004,
- 0x630a, 0x080c, 0x5b65, 0x0168, 0x6012, 0x600f, 0x0000, 0x080c,
- 0x5ccd, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x16c6,
- 0x0005, 0x2011, 0x0000, 0x080c, 0x16c6, 0x70b3, 0x0000, 0x70b7,
- 0x0000, 0x080c, 0x74f2, 0x0005, 0x00d6, 0x080c, 0x641b, 0x080c,
- 0x651c, 0x6110, 0x2168, 0x684b, 0x0000, 0x00d6, 0x6018, 0x2068,
- 0x6008, 0x68b6, 0x68bb, 0x0500, 0xa006, 0x68b2, 0x00de, 0x080c,
- 0x4809, 0x080c, 0x74f2, 0x00de, 0x0005, 0x6000, 0xa08a, 0x0010,
- 0x1a0c, 0x13fe, 0x000b, 0x0005, 0x5e64, 0x5e64, 0x5e64, 0x5e66,
- 0x5e7f, 0x5e64, 0x5e64, 0x5e64, 0x5e64, 0x5e64, 0x5e64, 0x5e64,
- 0x5e64, 0x5e64, 0x5e64, 0x5e64, 0x080c, 0x13fe, 0x080c, 0x7366,
- 0x190c, 0x13fe, 0x6110, 0x2168, 0x684b, 0x0006, 0x00d6, 0x6018,
- 0x2068, 0x6008, 0x68b6, 0x68bb, 0x0500, 0xa006, 0x68b2, 0x00de,
- 0x080c, 0x4809, 0x080c, 0x74f2, 0x00de, 0x0005, 0x0005, 0x0005,
- 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x13fe, 0x000b, 0x0005, 0x5e97,
- 0x5e97, 0x5e97, 0x5e99, 0x5e9b, 0x5e97, 0x5e97, 0x5e97, 0x5e97,
- 0x5e97, 0x5e97, 0x5e97, 0x5e97, 0x5e97, 0x5e97, 0x5e97, 0x080c,
- 0x13fe, 0x080c, 0x13fe, 0x00d6, 0x6010, 0x2068, 0x080c, 0x5cf4,
- 0x00de, 0x0005, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e,
- 0x1208, 0xa200, 0x1f04, 0x5ea6, 0x8086, 0x818e, 0x0005, 0x0156,
- 0x20a9, 0x0010, 0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213, 0x818d,
- 0x0228, 0xa11a, 0x1220, 0x1f04, 0x5eb6, 0x0028, 0xa11a, 0x2308,
- 0x8210, 0x1f04, 0x5eb6, 0x0006, 0x3200, 0xa084, 0xefff, 0x2080,
- 0x000e, 0x015e, 0x0005, 0x0006, 0x3200, 0xa085, 0x1000, 0x0cb8,
- 0x0126, 0x2091, 0x2400, 0x2079, 0x94e5, 0x012e, 0x00d6, 0x2069,
- 0x94e5, 0x6803, 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001,
- 0x206a, 0x00de, 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0xa084,
- 0x0007, 0x0002, 0x5ef4, 0x5f15, 0x5f68, 0x5efa, 0x5f15, 0x5ef4,
- 0x5ef2, 0x5ef2, 0x080c, 0x13fe, 0x080c, 0x57a1, 0x080c, 0x6462,
- 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011,
- 0x40af, 0x080c, 0x5731, 0x7828, 0xa092, 0x0002, 0x1228, 0x8000,
- 0x782a, 0x080c, 0x40fc, 0x0c88, 0x080c, 0x40af, 0x7807, 0x0003,
- 0x7827, 0x0000, 0x782b, 0x0000, 0x0c40, 0x080c, 0x57a1, 0x3c00,
- 0x0006, 0x2011, 0x0209, 0x20e1, 0x4000, 0x2214, 0x000e, 0x20e0,
- 0x82ff, 0x0178, 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824,
- 0xa065, 0x090c, 0x13fe, 0x2009, 0x0013, 0x080c, 0x7518, 0x00ce,
- 0x0005, 0x3900, 0xa082, 0x9606, 0x1210, 0x080c, 0x7432, 0x00c6,
- 0x7824, 0xa065, 0x090c, 0x13fe, 0x7804, 0xa086, 0x0004, 0x0904,
- 0x5fa8, 0x7828, 0xa092, 0x2710, 0x1230, 0x8000, 0x782a, 0x00ce,
- 0x080c, 0x6f11, 0x0c20, 0x6104, 0xa186, 0x0003, 0x1188, 0x00e6,
- 0x2071, 0x9200, 0x70d4, 0x00ee, 0xd08c, 0x0150, 0x00c6, 0x00e6,
- 0x2061, 0x0100, 0x2071, 0x9200, 0x080c, 0x4105, 0x00ee, 0x00ce,
- 0x080c, 0x91a0, 0x2009, 0x0014, 0x080c, 0x7518, 0x00ce, 0x0838,
- 0x2001, 0x9501, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b,
- 0x0000, 0x7824, 0xa065, 0x090c, 0x13fe, 0x2009, 0x0013, 0x080c,
- 0x7563, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x3900, 0xa082, 0x9606,
- 0x1210, 0x080c, 0x7432, 0x7824, 0xa005, 0x090c, 0x13fe, 0x781c,
- 0xa06d, 0x090c, 0x13fe, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160,
- 0x080c, 0x74f2, 0x693c, 0x81ff, 0x090c, 0x13fe, 0x8109, 0x693e,
- 0x6854, 0xa015, 0x0110, 0x7a1e, 0x0010, 0x7918, 0x791e, 0x7807,
- 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce, 0x080c, 0x6462, 0x0888,
- 0x6104, 0xa186, 0x0002, 0x0128, 0xa186, 0x0004, 0x0110, 0x0804,
- 0x5f41, 0x7808, 0xac06, 0x0904, 0x5f41, 0x080c, 0x6389, 0x080c,
- 0x603e, 0x00ce, 0x080c, 0x6462, 0x0804, 0x5f2f, 0x00c6, 0x6027,
- 0x0002, 0x62c8, 0x60c4, 0xa205, 0x11a0, 0x793c, 0xa1e5, 0x0000,
- 0x0150, 0x2009, 0x0049, 0x601c, 0xa086, 0x0009, 0x1110, 0x2009,
- 0x0103, 0x080c, 0x7518, 0x2011, 0x9504, 0x2013, 0x0000, 0x00ce,
- 0x0005, 0x3908, 0xa192, 0x9606, 0x1210, 0x080c, 0x7432, 0x6017,
- 0x0010, 0x793c, 0x81ff, 0x0d78, 0x793c, 0xa188, 0x0007, 0x210c,
- 0xa18e, 0x0006, 0x1118, 0x6017, 0x0012, 0x0c48, 0x793c, 0xa188,
- 0x0007, 0x210c, 0xa18e, 0x0009, 0x0db0, 0x6017, 0x0016, 0x08f8,
- 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000,
- 0x2c08, 0x2061, 0x94e5, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005,
- 0x0148, 0xa080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e,
- 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0x94e5,
- 0x6000, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0xa086, 0x0001,
- 0x1110, 0x2c00, 0x681e, 0x6804, 0xa084, 0x0007, 0x0804, 0x646f,
- 0xc0d5, 0x6002, 0x6818, 0xa005, 0x0158, 0x6056, 0x605b, 0x0000,
- 0x0006, 0x2c00, 0x681a, 0x00de, 0x685a, 0x2069, 0x94e5, 0x0c18,
- 0x6056, 0x605a, 0x2c00, 0x681a, 0x681e, 0x08e8, 0x0006, 0x0016,
- 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061,
- 0x94e5, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0148, 0xa080,
- 0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005,
- 0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061,
- 0x94e5, 0x6034, 0xa005, 0x0130, 0xa080, 0x0003, 0x2102, 0x6136,
- 0x00ce, 0x0005, 0x613a, 0x6136, 0x0cd8, 0x00f6, 0x00e6, 0x00d6,
- 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x0126, 0x2071, 0x94e5,
- 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x60cb,
- 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x60c6, 0x88ff,
- 0x0118, 0x6020, 0xa106, 0x15d0, 0x703c, 0xac06, 0x1120, 0x6003,
- 0x000a, 0x630a, 0x0498, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a,
- 0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036,
- 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110,
- 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0x82ee, 0x0188,
- 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x11f8, 0x6837, 0x0103,
- 0x6b4a, 0x6847, 0x0000, 0x080c, 0x8527, 0x080c, 0x4809, 0x080c,
- 0x848f, 0x080c, 0x849b, 0x00ce, 0x0804, 0x607d, 0x2c78, 0x600c,
- 0x2060, 0x0804, 0x607d, 0x012e, 0x000e, 0x001e, 0x002e, 0x006e,
- 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006,
- 0x19e8, 0x080c, 0x9097, 0x0c28, 0x0006, 0x0066, 0x00c6, 0x00d6,
- 0x00f6, 0x2031, 0x0000, 0x0126, 0x2091, 0x8000, 0x2079, 0x94e5,
- 0x7838, 0xa065, 0x0510, 0x600c, 0x0006, 0x600f, 0x0000, 0x783c,
- 0xac06, 0x1128, 0x6003, 0x000a, 0x630a, 0x2c30, 0x00a0, 0x080c,
- 0x82ee, 0x0178, 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x11b0,
- 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x4809, 0x080c,
- 0x848f, 0x080c, 0x849b, 0x000e, 0x08e0, 0x7e3a, 0x7e36, 0x012e,
+ 0x00f6, 0x7000, 0xa084, 0xf000, 0xa086, 0xc000, 0x0598, 0x080c,
+ 0x6cc2, 0x0580, 0x00c6, 0x0046, 0x2011, 0x9083, 0x2204, 0x8211,
+ 0x220c, 0x080c, 0x22e9, 0x1568, 0x080c, 0x42d6, 0x1550, 0x6612,
+ 0x6516, 0x2c00, 0x004e, 0x00ce, 0x601a, 0x080c, 0x1488, 0x01f0,
+ 0x2d00, 0x6026, 0x6803, 0x0000, 0x6837, 0x0000, 0x6c3a, 0xadf8,
+ 0x000f, 0x20a9, 0x000e, 0x2fa0, 0x2e98, 0x53a3, 0x6013, 0x0205,
+ 0x6007, 0x003e, 0x601f, 0x0001, 0x6003, 0x0001, 0x080c, 0x58e2,
+ 0x080c, 0x5d10, 0x00fe, 0x00de, 0x00ce, 0x0005, 0x080c, 0x6d18,
+ 0x0cc8, 0x004e, 0x00ce, 0x0cd0, 0x2071, 0x8dbd, 0x7003, 0x0003,
+ 0x700f, 0x0361, 0xa006, 0x701a, 0x7012, 0x7017, 0x9200, 0x7007,
+ 0x0000, 0x7026, 0x702b, 0x6704, 0x7032, 0x7037, 0x6745, 0x703b,
+ 0xffff, 0x703f, 0xffff, 0x0005, 0x2071, 0x8dbd, 0x1d04, 0x55fc,
+ 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1120, 0x700f, 0x0361,
+ 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x7024, 0xa00d, 0x0158,
+ 0x7020, 0x8001, 0x7022, 0x1138, 0x7023, 0x0009, 0x8109, 0x7126,
+ 0x1110, 0x7028, 0x080f, 0x7030, 0xa00d, 0x0158, 0x702c, 0x8001,
+ 0x702e, 0x1138, 0x702f, 0x0009, 0x8109, 0x7132, 0x1110, 0x7034,
+ 0x080f, 0x7038, 0xa005, 0x0118, 0x0310, 0x8001, 0x703a, 0x703c,
+ 0xa005, 0x0118, 0x0310, 0x8001, 0x703e, 0x7018, 0xa00d, 0x0158,
+ 0x7008, 0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a,
+ 0x1110, 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x5622, 0x5623,
+ 0x563b, 0x00e6, 0x2071, 0x8dbd, 0x7018, 0xa005, 0x1120, 0x711a,
+ 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071,
+ 0x8dbd, 0x701c, 0xa206, 0x1110, 0x701a, 0x701e, 0x000e, 0x00ee,
+ 0x0005, 0x00e6, 0x2071, 0x8dbd, 0x6088, 0xa102, 0x0208, 0x618a,
+ 0x00ee, 0x0005, 0x0005, 0x7110, 0x080c, 0x430a, 0x1158, 0x6088,
+ 0x8001, 0x0240, 0x608a, 0x1130, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x5d10, 0x012e, 0x8108, 0xa182, 0x00ff, 0x0218, 0xa00e, 0x7007,
+ 0x0002, 0x7112, 0x0005, 0x7014, 0x2060, 0x0126, 0x2091, 0x8000,
+ 0x6014, 0xa005, 0x0500, 0x8001, 0x6016, 0x11e8, 0x611c, 0xa186,
+ 0x0003, 0x0118, 0xa186, 0x0006, 0x11a0, 0x6010, 0x2068, 0x6854,
+ 0xa08a, 0x199a, 0x0270, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a,
+ 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116,
+ 0x0010, 0x080c, 0x79ec, 0x012e, 0xac88, 0x000c, 0x7116, 0x2001,
+ 0x8b17, 0x2004, 0xa102, 0x0220, 0x7017, 0x9200, 0x7007, 0x0000,
+ 0x0005, 0x00e6, 0x2071, 0x8dbd, 0x7027, 0x07d0, 0x7023, 0x0009,
+ 0x00ee, 0x0005, 0x2001, 0x8dc6, 0x2003, 0x0000, 0x0005, 0x00e6,
+ 0x2071, 0x8dbd, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011,
+ 0x8dc9, 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x8dbd, 0x711a,
+ 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00c6, 0x2061, 0x8e2a,
+ 0x00ce, 0x0005, 0xa184, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080,
+ 0x8e2a, 0x2060, 0x0005, 0x6854, 0xa08a, 0x199a, 0x0210, 0x2001,
+ 0x1999, 0xa005, 0x1150, 0x00c6, 0x2061, 0x8e2a, 0x6014, 0x00ce,
+ 0xa005, 0x1138, 0x2001, 0x001e, 0x0020, 0xa08e, 0xffff, 0x1108,
+ 0xa006, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c,
+ 0x00c0, 0xa18e, 0x00c0, 0x0588, 0xd0b4, 0x1138, 0xd0bc, 0x11f0,
+ 0x2009, 0x0006, 0x080c, 0x5711, 0x0005, 0xd0fc, 0x0140, 0xa084,
+ 0x0003, 0xa08e, 0x0003, 0x05b8, 0xa08e, 0x0000, 0x15a0, 0x2009,
+ 0x8b73, 0x2104, 0xd084, 0x0128, 0x2009, 0x0042, 0x080c, 0x6d3f,
+ 0x0005, 0x2009, 0x0043, 0x080c, 0x6d3f, 0x0005, 0xd0fc, 0x0140,
+ 0xa084, 0x0003, 0xa08e, 0x0003, 0x01f0, 0xa08e, 0x0000, 0x11d8,
+ 0x2009, 0x0042, 0x080c, 0x6d3f, 0x0005, 0xd0fc, 0x0168, 0xa084,
+ 0x0003, 0xa08e, 0x0003, 0x0178, 0xa08e, 0x0002, 0x0138, 0x2009,
+ 0x0041, 0x080c, 0x6d3f, 0x0005, 0x0051, 0x0ce8, 0x2009, 0x0043,
+ 0x080c, 0x6d3f, 0x0cc0, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009,
+ 0x0001, 0x6010, 0xa0ec, 0xf000, 0x01f0, 0x2068, 0x6952, 0x6800,
+ 0x6012, 0xa186, 0x0001, 0x1188, 0x694c, 0xa18c, 0x8100, 0xa18e,
+ 0x8100, 0x1158, 0x00c6, 0x2061, 0x8e2a, 0x6200, 0xd28c, 0x1120,
+ 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x46a1, 0x6010,
+ 0xa06d, 0x190c, 0x56a3, 0x0005, 0x0156, 0x00c6, 0x2061, 0x8e2a,
+ 0x6000, 0x81ff, 0x0110, 0xa205, 0x0008, 0xa204, 0x6002, 0x00ce,
+ 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0xa005, 0x0120,
+ 0x8001, 0x680a, 0xa085, 0x0001, 0x0005, 0x20a9, 0x0010, 0xa006,
+ 0x8004, 0x8086, 0x818e, 0x1208, 0xa200, 0x1f04, 0x5751, 0x8086,
+ 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010, 0xa005, 0x01b8, 0xa11a,
+ 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a, 0x1220, 0x1f04, 0x5761,
+ 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04, 0x5761, 0x0006, 0x3200,
+ 0xa084, 0xefff, 0x2080, 0x000e, 0x015e, 0x0005, 0x0006, 0x3200,
+ 0xa085, 0x1000, 0x0cb8, 0x0126, 0x2091, 0x2400, 0x2079, 0x8daa,
+ 0x012e, 0x00d6, 0x2069, 0x8daa, 0x6803, 0x0005, 0x2069, 0x0004,
+ 0x2d04, 0xa085, 0x8001, 0x206a, 0x00de, 0x0005, 0x00c6, 0x6027,
+ 0x0001, 0x7804, 0xa084, 0x0007, 0x0002, 0x579f, 0x57c0, 0x5813,
+ 0x57a5, 0x57c0, 0x579f, 0x579d, 0x579d, 0x080c, 0x1410, 0x080c,
+ 0x567a, 0x080c, 0x5d10, 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110,
+ 0x00ce, 0x0005, 0x2011, 0x3fe7, 0x080c, 0x560d, 0x7828, 0xa092,
+ 0x0002, 0x1228, 0x8000, 0x782a, 0x080c, 0x4034, 0x0c88, 0x080c,
+ 0x3fe7, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0c40,
+ 0x080c, 0x567a, 0x3c00, 0x0006, 0x2011, 0x0209, 0x20e1, 0x4000,
+ 0x2214, 0x000e, 0x20e0, 0x82ff, 0x0178, 0x62c0, 0x82ff, 0x1160,
+ 0x782b, 0x0000, 0x7824, 0xa065, 0x090c, 0x1410, 0x2009, 0x0013,
+ 0x080c, 0x6d3f, 0x00ce, 0x0005, 0x3900, 0xa082, 0x8eca, 0x1210,
+ 0x080c, 0x6c01, 0x00c6, 0x7824, 0xa065, 0x090c, 0x1410, 0x7804,
+ 0xa086, 0x0004, 0x0904, 0x5853, 0x7828, 0xa092, 0x2710, 0x1230,
+ 0x8000, 0x782a, 0x00ce, 0x080c, 0x66ea, 0x0c20, 0x6104, 0xa186,
+ 0x0003, 0x1188, 0x00e6, 0x2071, 0x8b00, 0x70d4, 0x00ee, 0xd08c,
+ 0x0150, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x8b00, 0x080c,
+ 0x403d, 0x00ee, 0x00ce, 0x080c, 0x8a4b, 0x2009, 0x0014, 0x080c,
+ 0x6d3f, 0x00ce, 0x0838, 0x2001, 0x8dc6, 0x2003, 0x0000, 0x62c0,
+ 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, 0xa065, 0x090c, 0x1410,
+ 0x2009, 0x0013, 0x080c, 0x6d92, 0x00ce, 0x0005, 0x00c6, 0x00d6,
+ 0x3900, 0xa082, 0x8eca, 0x1210, 0x080c, 0x6c01, 0x7824, 0xa005,
+ 0x090c, 0x1410, 0x781c, 0xa06d, 0x090c, 0x1410, 0x6800, 0xc0dc,
+ 0x6802, 0x7924, 0x2160, 0x080c, 0x6d18, 0x693c, 0x81ff, 0x090c,
+ 0x1410, 0x8109, 0x693e, 0x6854, 0xa015, 0x0110, 0x7a1e, 0x0010,
+ 0x7918, 0x791e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce,
+ 0x080c, 0x5d10, 0x0888, 0x6104, 0xa186, 0x0002, 0x0128, 0xa186,
+ 0x0004, 0x0110, 0x0804, 0x57ec, 0x7808, 0xac06, 0x0904, 0x57ec,
+ 0x080c, 0x5c37, 0x080c, 0x58e2, 0x00ce, 0x080c, 0x5d10, 0x0804,
+ 0x57da, 0x00c6, 0x6027, 0x0002, 0x62c8, 0x60c4, 0xa205, 0x1170,
+ 0x793c, 0xa1e5, 0x0000, 0x0120, 0x2009, 0x0049, 0x080c, 0x6d3f,
+ 0x2011, 0x8dc9, 0x2013, 0x0000, 0x00ce, 0x0005, 0x3908, 0xa192,
+ 0x8eca, 0x1210, 0x080c, 0x6c01, 0x793c, 0x81ff, 0x0d88, 0x793c,
+ 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x1138, 0x6014, 0xa084,
+ 0x0184, 0xa085, 0x0012, 0x6016, 0x0c38, 0x6014, 0xa084, 0x0184,
+ 0xa085, 0x0016, 0x6016, 0x0c00, 0x0006, 0x0016, 0x00c6, 0x0126,
+ 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0x8daa, 0x6020,
+ 0x8000, 0x6022, 0x6010, 0xa005, 0x0148, 0xa080, 0x0003, 0x2102,
+ 0x6112, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x6116, 0x6112,
+ 0x0cc0, 0x00d6, 0x2069, 0x8daa, 0x6000, 0xd0d4, 0x0168, 0x6820,
+ 0x8000, 0x6822, 0xa086, 0x0001, 0x1110, 0x2c00, 0x681e, 0x6804,
+ 0xa084, 0x0007, 0x0804, 0x5d16, 0xc0d5, 0x6002, 0x6818, 0xa005,
+ 0x0158, 0x6056, 0x605b, 0x0000, 0x0006, 0x2c00, 0x681a, 0x00de,
+ 0x685a, 0x2069, 0x8daa, 0x0c18, 0x6056, 0x605a, 0x2c00, 0x681a,
+ 0x681e, 0x08e8, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000,
+ 0x600f, 0x0000, 0x2c08, 0x2061, 0x8daa, 0x6020, 0x8000, 0x6022,
+ 0x6008, 0xa005, 0x0148, 0xa080, 0x0003, 0x2102, 0x610a, 0x012e,
+ 0x00ce, 0x001e, 0x000e, 0x0005, 0x610e, 0x610a, 0x0cc0, 0x00c6,
+ 0x600f, 0x0000, 0x2c08, 0x2061, 0x8daa, 0x6034, 0xa005, 0x0130,
+ 0xa080, 0x0003, 0x2102, 0x6136, 0x00ce, 0x0005, 0x613a, 0x6136,
+ 0x0cd8, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016,
+ 0x0006, 0x0126, 0x2071, 0x8daa, 0x7638, 0x2660, 0x2678, 0x2091,
+ 0x8000, 0x8cff, 0x0904, 0x597a, 0x6018, 0xa080, 0x0028, 0x2004,
+ 0xa206, 0x1904, 0x5975, 0x88ff, 0x0120, 0x6020, 0xa106, 0x1904,
+ 0x5975, 0x703c, 0xac06, 0x1170, 0x0036, 0x2019, 0x0001, 0x080c,
+ 0x68e5, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047,
+ 0x0000, 0x003e, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a, 0x7034,
+ 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010,
+ 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e,
+ 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0x7b8f, 0x0188, 0x6010,
+ 0x2068, 0x601c, 0xa086, 0x0003, 0x11f8, 0x6837, 0x0103, 0x6b4a,
+ 0x6847, 0x0000, 0x080c, 0x7dc8, 0x080c, 0x46a1, 0x080c, 0x7d30,
+ 0x080c, 0x7d3c, 0x00ce, 0x0804, 0x5921, 0x2c78, 0x600c, 0x2060,
+ 0x0804, 0x5921, 0x012e, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce,
+ 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19e8,
+ 0x080c, 0x8942, 0x0c28, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x00f6,
+ 0x2031, 0x0000, 0x0126, 0x2091, 0x8000, 0x2079, 0x8daa, 0x7838,
+ 0xa065, 0x0558, 0x600c, 0x0006, 0x600f, 0x0000, 0x783c, 0xac06,
+ 0x1170, 0x0036, 0x2019, 0x0001, 0x080c, 0x68e5, 0x7833, 0x0000,
+ 0x783f, 0x0000, 0x7843, 0x0000, 0x7847, 0x0000, 0x003e, 0x080c,
+ 0x7b8f, 0x0178, 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x11b0,
+ 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x46a1, 0x080c,
+ 0x7d30, 0x080c, 0x7d3c, 0x000e, 0x0898, 0x7e3a, 0x7e36, 0x012e,
0x00fe, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x601c, 0xa086,
- 0x0006, 0x0150, 0x601c, 0xa086, 0x0009, 0x1d10, 0x6b4a, 0x080c,
- 0x4809, 0x080c, 0x74f2, 0x0c38, 0x080c, 0x9097, 0x0c10, 0x0016,
- 0x0026, 0x0086, 0x2041, 0x0000, 0x0099, 0x080c, 0x61d3, 0x008e,
- 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0x94e5, 0x2091,
- 0x8000, 0x080c, 0x625e, 0x080c, 0x62be, 0x012e, 0x00fe, 0x0005,
- 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126,
- 0x2091, 0x8000, 0x2071, 0x94e5, 0x7614, 0x2660, 0x2678, 0x8cff,
- 0x0904, 0x61c3, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904,
- 0x61be, 0x88ff, 0x0120, 0x6020, 0xa106, 0x1904, 0x61be, 0x7024,
- 0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c,
- 0x57a1, 0x080c, 0x6f1e, 0x68c3, 0x0000, 0x080c, 0x7356, 0x7027,
- 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120,
- 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084,
- 0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a,
- 0x04a8, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, 0xac36,
- 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013,
- 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008,
- 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, 0x82ee, 0x0178,
- 0x601c, 0xa086, 0x0003, 0x1500, 0x6837, 0x0103, 0x6b4a, 0x6847,
- 0x0000, 0x080c, 0x8527, 0x080c, 0x4809, 0x080c, 0x848f, 0x080c,
- 0x849b, 0x080c, 0x7238, 0x00ce, 0x0804, 0x614f, 0x2c78, 0x600c,
- 0x2060, 0x0804, 0x614f, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce,
- 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19e0,
- 0x080c, 0x9097, 0x0c20, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000,
- 0xa280, 0x936e, 0x2004, 0xa065, 0x0904, 0x625a, 0x00f6, 0x00e6,
- 0x00d6, 0x0066, 0x2071, 0x94e5, 0x6654, 0x7018, 0xac06, 0x1108,
- 0x761a, 0x701c, 0xac06, 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e,
- 0x0008, 0x761e, 0x6058, 0xa07d, 0x0108, 0x7e56, 0xa6ed, 0x0000,
- 0x0110, 0x2f00, 0x685a, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000,
- 0xc0d4, 0xc0dc, 0x6002, 0x080c, 0x43ba, 0x0904, 0x6256, 0x7624,
- 0x86ff, 0x05e8, 0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6,
- 0x2069, 0x0100, 0x68c0, 0xa005, 0x0548, 0x080c, 0x57a1, 0x080c,
- 0x6f1e, 0x68c3, 0x0000, 0x080c, 0x7356, 0x7027, 0x0000, 0x0036,
+ 0x0006, 0x1d30, 0x080c, 0x8942, 0x0c60, 0x0016, 0x0026, 0x0086,
+ 0x2041, 0x0000, 0x0099, 0x080c, 0x5a81, 0x008e, 0x002e, 0x001e,
+ 0x0005, 0x00f6, 0x0126, 0x2079, 0x8daa, 0x2091, 0x8000, 0x080c,
+ 0x5b0c, 0x080c, 0x5b6c, 0x012e, 0x00fe, 0x0005, 0x00f6, 0x00e6,
+ 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000,
+ 0x2071, 0x8daa, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x5a71,
+ 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x5a6c, 0x88ff,
+ 0x0120, 0x6020, 0xa106, 0x1904, 0x5a6c, 0x7024, 0xac06, 0x1538,
+ 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, 0x567a, 0x080c,
+ 0x66f7, 0x68c3, 0x0000, 0x080c, 0x6b23, 0x7027, 0x0000, 0x0036,
0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100,
0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
- 0x0001, 0x003e, 0x00de, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001,
- 0x603e, 0x2660, 0x080c, 0x849b, 0x00ce, 0x0048, 0x00de, 0x00c6,
- 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x6203, 0x8dff,
- 0x0148, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x8527,
- 0x080c, 0x4809, 0x080c, 0x7238, 0x0804, 0x6203, 0x006e, 0x00de,
- 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, 0x0005, 0x0006, 0x0066,
- 0x00c6, 0x00d6, 0x2031, 0x0000, 0x7814, 0xa065, 0x0904, 0x62b0,
- 0x600c, 0x0006, 0x600f, 0x0000, 0x7824, 0xac06, 0x1540, 0x2069,
- 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, 0x57a1, 0x080c, 0x6f1e,
- 0x68c3, 0x0000, 0x080c, 0x7356, 0x7827, 0x0000, 0x0036, 0x2069,
- 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803,
- 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
- 0x003e, 0x0028, 0x6003, 0x0009, 0x630a, 0x2c30, 0x00b0, 0x6010,
- 0x2068, 0x080c, 0x82ee, 0x0168, 0x601c, 0xa086, 0x0003, 0x11b8,
- 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x4809, 0x080c,
- 0x848f, 0x080c, 0x849b, 0x080c, 0x7238, 0x000e, 0x0804, 0x6265,
- 0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x601c,
- 0xa086, 0x0006, 0x1d28, 0x080c, 0x9097, 0x0c58, 0x0006, 0x0066,
- 0x00c6, 0x00d6, 0x7818, 0xa065, 0x0904, 0x6324, 0x6054, 0x0006,
- 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002,
- 0x080c, 0x43ba, 0x0904, 0x6321, 0x7e24, 0x86ff, 0x05e8, 0xa680,
- 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100, 0x68c0,
- 0xa005, 0x0548, 0x080c, 0x57a1, 0x080c, 0x6f1e, 0x68c3, 0x0000,
- 0x080c, 0x7356, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
+ 0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a, 0x04a8, 0x7014,
+ 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, 0xac36, 0x1140, 0x2c00,
+ 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c,
+ 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f,
+ 0x0000, 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0178, 0x601c, 0xa086,
+ 0x0003, 0x1500, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c,
+ 0x7dc8, 0x080c, 0x46a1, 0x080c, 0x7d30, 0x080c, 0x7d3c, 0x080c,
+ 0x6a05, 0x00ce, 0x0804, 0x59fd, 0x2c78, 0x600c, 0x2060, 0x0804,
+ 0x59fd, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee,
+ 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19e0, 0x080c, 0x8942,
+ 0x0c20, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0xa280, 0x8c34,
+ 0x2004, 0xa065, 0x0904, 0x5b08, 0x00f6, 0x00e6, 0x00d6, 0x0066,
+ 0x2071, 0x8daa, 0x6654, 0x7018, 0xac06, 0x1108, 0x761a, 0x701c,
+ 0xac06, 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e,
+ 0x6058, 0xa07d, 0x0108, 0x7e56, 0xa6ed, 0x0000, 0x0110, 0x2f00,
+ 0x685a, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc,
+ 0x6002, 0x080c, 0x4290, 0x0904, 0x5b04, 0x7624, 0x86ff, 0x05e8,
+ 0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100,
+ 0x68c0, 0xa005, 0x0548, 0x080c, 0x567a, 0x080c, 0x66f7, 0x68c3,
+ 0x0000, 0x080c, 0x6b23, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
+ 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000,
+ 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
+ 0x00de, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e, 0x2660,
+ 0x080c, 0x7d3c, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003,
+ 0x0009, 0x630a, 0x00ce, 0x0804, 0x5ab1, 0x8dff, 0x0148, 0x6837,
+ 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x7dc8, 0x080c, 0x46a1,
+ 0x080c, 0x6a05, 0x0804, 0x5ab1, 0x006e, 0x00de, 0x00ee, 0x00fe,
+ 0x012e, 0x000e, 0x00ce, 0x0005, 0x0006, 0x0066, 0x00c6, 0x00d6,
+ 0x2031, 0x0000, 0x7814, 0xa065, 0x0904, 0x5b5e, 0x600c, 0x0006,
+ 0x600f, 0x0000, 0x7824, 0xac06, 0x1540, 0x2069, 0x0100, 0x68c0,
+ 0xa005, 0x01f0, 0x080c, 0x567a, 0x080c, 0x66f7, 0x68c3, 0x0000,
+ 0x080c, 0x6b23, 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069,
- 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de,
+ 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0028,
+ 0x6003, 0x0009, 0x630a, 0x2c30, 0x00b0, 0x6010, 0x2068, 0x080c,
+ 0x7b8f, 0x0168, 0x601c, 0xa086, 0x0003, 0x11b8, 0x6837, 0x0103,
+ 0x6b4a, 0x6847, 0x0000, 0x080c, 0x46a1, 0x080c, 0x7d30, 0x080c,
+ 0x7d3c, 0x080c, 0x6a05, 0x000e, 0x0804, 0x5b13, 0x7e16, 0x7e12,
+ 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x601c, 0xa086, 0x0006,
+ 0x1d28, 0x080c, 0x8942, 0x0c58, 0x0006, 0x0066, 0x00c6, 0x00d6,
+ 0x7818, 0xa065, 0x0904, 0x5bd2, 0x6054, 0x0006, 0x6057, 0x0000,
+ 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x080c, 0x4290,
+ 0x0904, 0x5bcf, 0x7e24, 0x86ff, 0x05e8, 0xa680, 0x0004, 0x2004,
+ 0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0548,
+ 0x080c, 0x567a, 0x080c, 0x66f7, 0x68c3, 0x0000, 0x080c, 0x6b23,
+ 0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
+ 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824,
+ 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x603c,
+ 0xa005, 0x0110, 0x8001, 0x603e, 0x2660, 0x080c, 0x7d3c, 0x00ce,
+ 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce,
+ 0x0804, 0x5b7e, 0x8dff, 0x0138, 0x6837, 0x0103, 0x6b4a, 0x6847,
+ 0x0000, 0x080c, 0x46a1, 0x080c, 0x6a05, 0x0804, 0x5b7e, 0x000e,
+ 0x0804, 0x5b71, 0x781e, 0x781a, 0x00de, 0x00ce, 0x006e, 0x000e,
+ 0x0005, 0x00e6, 0x00d6, 0x0066, 0x6000, 0xd0dc, 0x0188, 0x604c,
+ 0xa06d, 0x0170, 0x6848, 0xa606, 0x1158, 0x2071, 0x8daa, 0x7024,
+ 0xa035, 0x0130, 0xa080, 0x0004, 0x2004, 0xad06, 0x1108, 0x0021,
+ 0x006e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, 0x0100, 0x78c0,
+ 0xa005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce,
+ 0x04a0, 0x080c, 0x66f7, 0x78c3, 0x0000, 0x080c, 0x6b23, 0x7027,
+ 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0xa384, 0x1000, 0x0120,
+ 0x7803, 0x0100, 0x7803, 0x0000, 0x2079, 0x0100, 0x7824, 0xd084,
+ 0x0110, 0x7827, 0x0001, 0x080c, 0x6b23, 0x003e, 0x080c, 0x4290,
0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e, 0x2660, 0x080c,
- 0x849b, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009,
- 0x630a, 0x00ce, 0x0804, 0x62d0, 0x8dff, 0x0138, 0x6837, 0x0103,
- 0x6b4a, 0x6847, 0x0000, 0x080c, 0x4809, 0x080c, 0x7238, 0x0804,
- 0x62d0, 0x000e, 0x0804, 0x62c3, 0x781e, 0x781a, 0x00de, 0x00ce,
- 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0066, 0x6000, 0xd0dc,
- 0x0188, 0x604c, 0xa06d, 0x0170, 0x6848, 0xa606, 0x1158, 0x2071,
- 0x94e5, 0x7024, 0xa035, 0x0130, 0xa080, 0x0004, 0x2004, 0xad06,
- 0x1108, 0x0021, 0x006e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079,
- 0x0100, 0x78c0, 0xa005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009,
- 0x630a, 0x00ce, 0x04a0, 0x080c, 0x6f1e, 0x78c3, 0x0000, 0x080c,
- 0x7356, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0xa384,
- 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x2079, 0x0100,
- 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c, 0x7356, 0x003e,
- 0x080c, 0x43ba, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e,
- 0x2660, 0x080c, 0x74f2, 0x00ce, 0x6837, 0x0103, 0x6b4a, 0x6847,
- 0x0000, 0x080c, 0x8527, 0x080c, 0x4809, 0x080c, 0x7238, 0x00fe,
- 0x0005, 0x00e6, 0x00c6, 0x2071, 0x94e5, 0x7004, 0xa084, 0x0007,
- 0x0002, 0x639b, 0x639e, 0x63b4, 0x63cd, 0x6406, 0x639b, 0x6399,
- 0x6399, 0x080c, 0x13fe, 0x00ce, 0x00ee, 0x0005, 0x7024, 0xa065,
- 0x0148, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015, 0x0150, 0x7216,
- 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee,
- 0x0005, 0x7216, 0x7212, 0x0cb0, 0x6018, 0x2060, 0x080c, 0x43ba,
- 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022, 0x0120, 0x6054,
- 0xa015, 0x0140, 0x721e, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce,
- 0x00ee, 0x0005, 0x7218, 0x721e, 0x0cb0, 0x7024, 0xa065, 0x0598,
- 0x700c, 0xac06, 0x1160, 0x080c, 0x7238, 0x600c, 0xa015, 0x0120,
- 0x720e, 0x600f, 0x0000, 0x0428, 0x720e, 0x720a, 0x0410, 0x7014,
- 0xac06, 0x1160, 0x080c, 0x7238, 0x600c, 0xa015, 0x0120, 0x7216,
- 0x600f, 0x0000, 0x00b0, 0x7216, 0x7212, 0x0098, 0x6018, 0x2060,
- 0x080c, 0x43ba, 0x6000, 0xc0dc, 0x6002, 0x080c, 0x7238, 0x701c,
- 0xa065, 0x0138, 0x6054, 0xa015, 0x0110, 0x721e, 0x0010, 0x7218,
- 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005, 0x7024, 0xa065,
- 0x0140, 0x080c, 0x7238, 0x600c, 0xa015, 0x0150, 0x720e, 0x600f,
- 0x0000, 0x080c, 0x7356, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005,
- 0x720e, 0x720a, 0x0cb0, 0x00d6, 0x2069, 0x94e5, 0x6830, 0xa084,
- 0x0003, 0x0002, 0x6428, 0x642a, 0x644a, 0x6426, 0x080c, 0x13fe,
- 0x00de, 0x0005, 0x00c6, 0x6840, 0xa086, 0x0001, 0x0198, 0x683c,
- 0xa065, 0x0130, 0x600c, 0xa015, 0x0150, 0x6a3a, 0x600f, 0x0000,
- 0x6833, 0x0000, 0x683f, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a,
- 0x6836, 0x0cb0, 0x6843, 0x0000, 0x6838, 0xa065, 0x0d88, 0x6003,
- 0x0003, 0x0c70, 0x00c6, 0x6843, 0x0000, 0x6847, 0x0000, 0x683c,
- 0xa065, 0x0168, 0x600c, 0xa015, 0x0130, 0x6a3a, 0x600f, 0x0000,
- 0x683f, 0x0000, 0x0020, 0x683f, 0x0000, 0x683a, 0x6836, 0x00ce,
- 0x00de, 0x0005, 0x00d6, 0x2001, 0x9295, 0x2004, 0xd084, 0x0110,
- 0x00de, 0x0005, 0x2069, 0x94e5, 0x6804, 0xa084, 0x0007, 0x0002,
- 0x647a, 0x650c, 0x650c, 0x650c, 0x650c, 0x650e, 0x6478, 0x6478,
- 0x080c, 0x13fe, 0x6820, 0xa005, 0x1110, 0x00de, 0x0005, 0x00c6,
- 0x680c, 0xa065, 0x0150, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000,
- 0x080c, 0x656d, 0x00ce, 0x00de, 0x0005, 0x6814, 0xa065, 0x0150,
- 0x6807, 0x0001, 0x6826, 0x682b, 0x0000, 0x080c, 0x656d, 0x00ce,
- 0x00de, 0x0005, 0x00e6, 0x0036, 0x6a1c, 0xa2f5, 0x0000, 0x0904,
- 0x6508, 0x704c, 0xa00d, 0x0118, 0x7088, 0xa005, 0x01a0, 0x7054,
- 0xa075, 0x0120, 0xa20e, 0x0904, 0x6508, 0x0028, 0x6818, 0xa20e,
- 0x0904, 0x6508, 0x2070, 0x704c, 0xa00d, 0x0d88, 0x7088, 0xa005,
- 0x1d70, 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, 0x1e40, 0x080c,
- 0x74c9, 0x0904, 0x6508, 0x8318, 0x733e, 0x6112, 0x2e10, 0x621a,
- 0xa180, 0x0015, 0x2004, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999,
- 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x00f6, 0x2c78,
- 0x71a0, 0x2001, 0x9232, 0x2004, 0xd0ac, 0x1110, 0xd1bc, 0x0150,
- 0x7100, 0xd1f4, 0x0120, 0x7114, 0xa18c, 0x00ff, 0x0040, 0x2009,
- 0x0000, 0x0028, 0xa1e0, 0x2719, 0x2c0d, 0xa18c, 0x00ff, 0x2061,
- 0x0100, 0x619a, 0x080c, 0x6a46, 0x7300, 0xc3dd, 0x7302, 0x6807,
- 0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, 0x781f, 0x0003, 0x7803,
- 0x0001, 0x7807, 0x0040, 0x00fe, 0x00ee, 0x00ce, 0x00de, 0x0005,
- 0x003e, 0x00ee, 0x00ce, 0x0cd0, 0x00de, 0x0005, 0x00c6, 0x680c,
- 0xa065, 0x0138, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c,
- 0x656d, 0x00ce, 0x00de, 0x0005, 0x00f6, 0x00d6, 0x2069, 0x94e5,
- 0x6830, 0xa086, 0x0000, 0x1590, 0x6838, 0xa07d, 0x0578, 0x781c,
- 0xa086, 0x0009, 0x1140, 0x7808, 0xd0fc, 0x0128, 0x2001, 0x94e6,
- 0x2004, 0xa005, 0x1518, 0x2f00, 0x6833, 0x0001, 0x683e, 0x6847,
- 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, 0x1d0f,
- 0x11c0, 0x012e, 0xe000, 0xe000, 0xe000, 0x6a3c, 0x2278, 0x781c,
- 0xa086, 0x0009, 0x1148, 0x7808, 0xd0fc, 0x0118, 0x080c, 0x6cf9,
- 0x0028, 0x080c, 0x6d75, 0x0010, 0x080c, 0x6dec, 0x00de, 0x00fe,
- 0x0005, 0x012e, 0xe000, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c,
- 0xa015, 0x0140, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f,
- 0x0000, 0x0c60, 0x683a, 0x6836, 0x0cc0, 0x601c, 0xa084, 0x000f,
- 0x000b, 0x0005, 0x657b, 0x6580, 0x68f8, 0x6a03, 0x6580, 0x68f8,
- 0x6a03, 0x657b, 0x6580, 0x080c, 0x6389, 0x080c, 0x6462, 0x0005,
- 0x0156, 0x0136, 0x0146, 0x00c6, 0x00f6, 0x6004, 0xa08a, 0x003e,
- 0x1a0c, 0x13fe, 0x6118, 0x2178, 0x79a0, 0x2011, 0x9232, 0x2214,
- 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120, 0x7914,
- 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8, 0x2719,
- 0x2f0d, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0x0033,
- 0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005, 0x65f5, 0x662d,
- 0x6647, 0x66fa, 0x6725, 0x672d, 0x674e, 0x675f, 0x6770, 0x6778,
- 0x6789, 0x6778, 0x67ce, 0x675f, 0x67ef, 0x67f7, 0x6770, 0x67f7,
- 0x6808, 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x65ec,
- 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x6fda, 0x6fef, 0x7012,
- 0x7036, 0x674e, 0x65ec, 0x674e, 0x6778, 0x65ec, 0x6647, 0x66fa,
- 0x65ec, 0x744f, 0x6778, 0x65ec, 0x746f, 0x6778, 0x65ec, 0x6770,
- 0x65ee, 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x65ec, 0x65ec,
- 0x65ec, 0x65ec, 0x65ec, 0x704b, 0x080c, 0x13fe, 0x2001, 0x9214,
- 0x2004, 0x609a, 0x080c, 0x6f0b, 0x0005, 0x20a1, 0x020b, 0x080c,
- 0x681d, 0x20a3, 0x5200, 0x20a3, 0x0000, 0x00d6, 0x2069, 0x9251,
+ 0x6d18, 0x00ce, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c,
+ 0x7dc8, 0x080c, 0x46a1, 0x080c, 0x6a05, 0x00fe, 0x0005, 0x00e6,
+ 0x00c6, 0x2071, 0x8daa, 0x7004, 0xa084, 0x0007, 0x0002, 0x5c49,
+ 0x5c4c, 0x5c62, 0x5c7b, 0x5cb4, 0x5c49, 0x5c47, 0x5c47, 0x080c,
+ 0x1410, 0x00ce, 0x00ee, 0x0005, 0x7024, 0xa065, 0x0148, 0x7020,
+ 0x8001, 0x7022, 0x600c, 0xa015, 0x0150, 0x7216, 0x600f, 0x0000,
+ 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005, 0x7216,
+ 0x7212, 0x0cb0, 0x6018, 0x2060, 0x080c, 0x4290, 0x6000, 0xc0dc,
+ 0x6002, 0x7020, 0x8001, 0x7022, 0x0120, 0x6054, 0xa015, 0x0140,
+ 0x721e, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005,
+ 0x7218, 0x721e, 0x0cb0, 0x7024, 0xa065, 0x0598, 0x700c, 0xac06,
+ 0x1160, 0x080c, 0x6a05, 0x600c, 0xa015, 0x0120, 0x720e, 0x600f,
+ 0x0000, 0x0428, 0x720e, 0x720a, 0x0410, 0x7014, 0xac06, 0x1160,
+ 0x080c, 0x6a05, 0x600c, 0xa015, 0x0120, 0x7216, 0x600f, 0x0000,
+ 0x00b0, 0x7216, 0x7212, 0x0098, 0x6018, 0x2060, 0x080c, 0x4290,
+ 0x6000, 0xc0dc, 0x6002, 0x080c, 0x6a05, 0x701c, 0xa065, 0x0138,
+ 0x6054, 0xa015, 0x0110, 0x721e, 0x0010, 0x7218, 0x721e, 0x7027,
+ 0x0000, 0x00ce, 0x00ee, 0x0005, 0x7024, 0xa065, 0x0140, 0x080c,
+ 0x6a05, 0x600c, 0xa015, 0x0150, 0x720e, 0x600f, 0x0000, 0x080c,
+ 0x6b23, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005, 0x720e, 0x720a,
+ 0x0cb0, 0x00d6, 0x2069, 0x8daa, 0x6830, 0xa084, 0x0003, 0x0002,
+ 0x5cd6, 0x5cd8, 0x5cf8, 0x5cd4, 0x080c, 0x1410, 0x00de, 0x0005,
+ 0x00c6, 0x6840, 0xa086, 0x0001, 0x0198, 0x683c, 0xa065, 0x0130,
+ 0x600c, 0xa015, 0x0150, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000,
+ 0x683f, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, 0x6836, 0x0cb0,
+ 0x6843, 0x0000, 0x6838, 0xa065, 0x0d88, 0x6003, 0x0003, 0x0c70,
+ 0x00c6, 0x6843, 0x0000, 0x6847, 0x0000, 0x683c, 0xa065, 0x0168,
+ 0x600c, 0xa015, 0x0130, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000,
+ 0x0020, 0x683f, 0x0000, 0x683a, 0x6836, 0x00ce, 0x00de, 0x0005,
+ 0x00d6, 0x2069, 0x8daa, 0x6804, 0xa084, 0x0007, 0x0002, 0x5d21,
+ 0x5db3, 0x5db3, 0x5db3, 0x5db3, 0x5db5, 0x5d1f, 0x5d1f, 0x080c,
+ 0x1410, 0x6820, 0xa005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c,
+ 0xa065, 0x0150, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c,
+ 0x5df4, 0x00ce, 0x00de, 0x0005, 0x6814, 0xa065, 0x0150, 0x6807,
+ 0x0001, 0x6826, 0x682b, 0x0000, 0x080c, 0x5df4, 0x00ce, 0x00de,
+ 0x0005, 0x00e6, 0x0036, 0x6a1c, 0xa2f5, 0x0000, 0x0904, 0x5daf,
+ 0x704c, 0xa00d, 0x0118, 0x7088, 0xa005, 0x01a0, 0x7054, 0xa075,
+ 0x0120, 0xa20e, 0x0904, 0x5daf, 0x0028, 0x6818, 0xa20e, 0x0904,
+ 0x5daf, 0x2070, 0x704c, 0xa00d, 0x0d88, 0x7088, 0xa005, 0x1d70,
+ 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, 0x1e40, 0x080c, 0x6cef,
+ 0x0904, 0x5daf, 0x8318, 0x733e, 0x6112, 0x2e10, 0x621a, 0xa180,
+ 0x0015, 0x2004, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003,
+ 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x00f6, 0x2c78, 0x71a0,
+ 0x2001, 0x8b32, 0x2004, 0xd0ac, 0x1110, 0xd1bc, 0x0150, 0x7100,
+ 0xd1f4, 0x0120, 0x7114, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000,
+ 0x0028, 0xa1e0, 0x263d, 0x2c0d, 0xa18c, 0x00ff, 0x2061, 0x0100,
+ 0x619a, 0x080c, 0x62f1, 0x7300, 0xc3dd, 0x7302, 0x6807, 0x0002,
+ 0x2f18, 0x6b26, 0x682b, 0x0000, 0x781f, 0x0003, 0x7803, 0x0001,
+ 0x7807, 0x0040, 0x00fe, 0x00ee, 0x00ce, 0x00de, 0x0005, 0x003e,
+ 0x00ee, 0x00ce, 0x0cd0, 0x00de, 0x0005, 0x00c6, 0x680c, 0xa065,
+ 0x0130, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x04a9, 0x00ce,
+ 0x00de, 0x0005, 0x00f6, 0x00d6, 0x2069, 0x8daa, 0x6830, 0xa086,
+ 0x0000, 0x1198, 0x6838, 0xa07d, 0x0180, 0x6833, 0x0001, 0x683e,
+ 0x6847, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c,
+ 0x1c40, 0x1130, 0x012e, 0x080c, 0x65ca, 0x00de, 0x00fe, 0x0005,
+ 0x012e, 0xe000, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015,
+ 0x0140, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000,
+ 0x0c60, 0x683a, 0x6836, 0x0cc0, 0x601c, 0xa084, 0x000f, 0x000b,
+ 0x0005, 0x5e02, 0x5e07, 0x618e, 0x62ae, 0x5e07, 0x618e, 0x62ae,
+ 0x5e02, 0x5e07, 0x080c, 0x5c37, 0x080c, 0x5d10, 0x0005, 0x0156,
+ 0x0136, 0x0146, 0x00c6, 0x00f6, 0x6004, 0xa08a, 0x0040, 0x1a0c,
+ 0x1410, 0x6118, 0x2178, 0x79a0, 0x2011, 0x8b32, 0x2214, 0xd2ac,
+ 0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c,
+ 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8, 0x263d, 0x2f0d,
+ 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0x0033, 0x00fe,
+ 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005, 0x5e7d, 0x5eb5, 0x5ecf,
+ 0x5f82, 0x5fad, 0x5fb5, 0x5fd6, 0x5fe7, 0x5ff8, 0x6000, 0x6011,
+ 0x6000, 0x6056, 0x5fe7, 0x6077, 0x607f, 0x5ff8, 0x607f, 0x6090,
+ 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74,
+ 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x67ad, 0x67c2, 0x67e5, 0x6809,
+ 0x5fd6, 0x5e74, 0x5fd6, 0x6000, 0x5e74, 0x5ecf, 0x5f82, 0x5e74,
+ 0x6c1e, 0x6000, 0x5e74, 0x6c3e, 0x6000, 0x5e74, 0x5ff8, 0x5e76,
+ 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74, 0x5e74,
+ 0x5e74, 0x5e74, 0x681e, 0x6c63, 0x080c, 0x1410, 0x2001, 0x8b14,
+ 0x2004, 0x609a, 0x080c, 0x66e4, 0x0005, 0x20a1, 0x020b, 0x080c,
+ 0x60a5, 0x20a3, 0x5200, 0x20a3, 0x0000, 0x00d6, 0x2069, 0x8b51,
0x6804, 0xd084, 0x0150, 0x6828, 0x20a3, 0x0000, 0x0016, 0x080c,
- 0x241f, 0x21a2, 0x001e, 0x00de, 0x0028, 0x00de, 0x20a3, 0x0000,
- 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x9205, 0x53a6, 0x20a9,
- 0x0004, 0x2099, 0x9201, 0x53a6, 0x20a3, 0x0000, 0x2001, 0x9214,
+ 0x22fd, 0x21a2, 0x001e, 0x00de, 0x0028, 0x00de, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x8b05, 0x53a6, 0x20a9,
+ 0x0004, 0x2099, 0x8b01, 0x53a6, 0x20a3, 0x0000, 0x2001, 0x8b14,
0x2004, 0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
- 0x60c3, 0x001c, 0x080c, 0x6f0b, 0x0005, 0x20a1, 0x020b, 0x080c,
- 0x681d, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x2001, 0x921b, 0x2004,
- 0x20a2, 0x2001, 0x921c, 0x2004, 0x20a2, 0x20a9, 0x0004, 0x2099,
- 0x9205, 0x53a6, 0x60c3, 0x0010, 0x080c, 0x6f0b, 0x0005, 0x20a1,
- 0x020b, 0x080c, 0x681d, 0x7818, 0xa080, 0x0028, 0x2004, 0xa086,
+ 0x60c3, 0x001c, 0x080c, 0x66e4, 0x0005, 0x20a1, 0x020b, 0x080c,
+ 0x60a5, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x2001, 0x8b1b, 0x2004,
+ 0x20a2, 0x2001, 0x8b1c, 0x2004, 0x20a2, 0x20a9, 0x0004, 0x2099,
+ 0x8b05, 0x53a6, 0x60c3, 0x0010, 0x080c, 0x66e4, 0x0005, 0x20a1,
+ 0x020b, 0x080c, 0x60a5, 0x7818, 0xa080, 0x0028, 0x2004, 0xa086,
0x007e, 0x1130, 0x20a3, 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0010,
0x20a3, 0x0300, 0x20a3, 0x0000, 0x7818, 0xa080, 0x0028, 0x2004,
- 0xa086, 0x007e, 0x1904, 0x66bc, 0x2001, 0x9232, 0x2004, 0xd0a4,
- 0x01c8, 0x2099, 0x94c7, 0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398,
+ 0xa086, 0x007e, 0x1904, 0x5f44, 0x2001, 0x8b32, 0x2004, 0xd0a4,
+ 0x01c8, 0x2099, 0x8d8c, 0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398,
0x3304, 0xa084, 0x2000, 0x20a2, 0x9398, 0x33a6, 0x9398, 0x20a3,
0x0000, 0x9398, 0x2001, 0x2710, 0x20a2, 0x9398, 0x33a6, 0x9398,
- 0x33a6, 0x00d0, 0x2099, 0x94c7, 0x33a6, 0x9398, 0x33a6, 0x9398,
- 0x3304, 0x080c, 0x4dc5, 0x1118, 0xa084, 0x37ff, 0x0010, 0xa084,
+ 0x33a6, 0x00d0, 0x2099, 0x8d8c, 0x33a6, 0x9398, 0x33a6, 0x9398,
+ 0x3304, 0x080c, 0x4c42, 0x1118, 0xa084, 0x37ff, 0x0010, 0xa084,
0x3fff, 0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
- 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x9205,
- 0x53a6, 0x20a9, 0x0004, 0x2099, 0x9201, 0x53a6, 0x20a9, 0x0008,
- 0x20a3, 0x0000, 0x1f04, 0x66a8, 0x20a9, 0x0008, 0x20a3, 0x0000,
- 0x1f04, 0x66ae, 0x2099, 0x94cf, 0x33a6, 0x20a9, 0x0007, 0x20a3,
- 0x0000, 0x1f04, 0x66b7, 0x0468, 0x2001, 0x9232, 0x2004, 0xd0a4,
- 0x0140, 0x2001, 0x94c8, 0x2004, 0x60e3, 0x0000, 0x080c, 0x2460,
- 0x60e2, 0x2099, 0x94c7, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004,
- 0x2099, 0x9205, 0x53a6, 0x20a9, 0x0004, 0x2099, 0x9201, 0x53a6,
- 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x66da, 0x20a9, 0x0008,
- 0x20a3, 0x0000, 0x1f04, 0x66e0, 0x2099, 0x94cf, 0x20a9, 0x0008,
- 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x66eb, 0x20a9,
- 0x000a, 0x20a3, 0x0000, 0x1f04, 0x66f1, 0x60c3, 0x0074, 0x080c,
- 0x6f0b, 0x0005, 0x20a1, 0x020b, 0x080c, 0x681d, 0x20a3, 0x2010,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0x8b05,
+ 0x53a6, 0x20a9, 0x0004, 0x2099, 0x8b01, 0x53a6, 0x20a9, 0x0008,
+ 0x20a3, 0x0000, 0x1f04, 0x5f30, 0x20a9, 0x0008, 0x20a3, 0x0000,
+ 0x1f04, 0x5f36, 0x2099, 0x8d94, 0x33a6, 0x20a9, 0x0007, 0x20a3,
+ 0x0000, 0x1f04, 0x5f3f, 0x0468, 0x2001, 0x8b32, 0x2004, 0xd0a4,
+ 0x0140, 0x2001, 0x8d8d, 0x2004, 0x60e3, 0x0000, 0x080c, 0x233e,
+ 0x60e2, 0x2099, 0x8d8c, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004,
+ 0x2099, 0x8b05, 0x53a6, 0x20a9, 0x0004, 0x2099, 0x8b01, 0x53a6,
+ 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x5f62, 0x20a9, 0x0008,
+ 0x20a3, 0x0000, 0x1f04, 0x5f68, 0x2099, 0x8d94, 0x20a9, 0x0008,
+ 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x5f73, 0x20a9,
+ 0x000a, 0x20a3, 0x0000, 0x1f04, 0x5f79, 0x60c3, 0x0074, 0x080c,
+ 0x66e4, 0x0005, 0x20a1, 0x020b, 0x080c, 0x60a5, 0x20a3, 0x2010,
0x20a3, 0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006, 0x20a2,
- 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x00f6, 0x2079, 0x9251, 0x7904,
+ 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x00f6, 0x2079, 0x8b51, 0x7904,
0x00fe, 0xd1ac, 0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085,
0x0010, 0xa085, 0x0002, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
- 0x60c3, 0x0014, 0x080c, 0x6f0b, 0x0005, 0x20a1, 0x020b, 0x080c,
- 0x681d, 0x20a3, 0x5000, 0x0804, 0x665a, 0x20a1, 0x020b, 0x080c,
- 0x681d, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3,
+ 0x60c3, 0x0014, 0x080c, 0x66e4, 0x0005, 0x20a1, 0x020b, 0x080c,
+ 0x60a5, 0x20a3, 0x5000, 0x0804, 0x5ee2, 0x20a1, 0x020b, 0x080c,
+ 0x60a5, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3,
0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
- 0x0000, 0x60c3, 0x0014, 0x080c, 0x6f0b, 0x0005, 0x20a1, 0x020b,
- 0x080c, 0x68a0, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000,
- 0x20a3, 0x0000, 0x60c3, 0x0004, 0x080c, 0x6f0b, 0x0005, 0x20a1,
- 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3,
- 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x6f0b, 0x0005,
- 0x20a1, 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0200, 0x0804, 0x665a,
- 0x20a1, 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0100, 0x20a3, 0x0000,
- 0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x6f0b,
- 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0210,
+ 0x0000, 0x60c3, 0x0014, 0x080c, 0x66e4, 0x0005, 0x20a1, 0x020b,
+ 0x080c, 0x612f, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x60c3, 0x0004, 0x080c, 0x66e4, 0x0005, 0x20a1,
+ 0x020b, 0x080c, 0x612f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3,
+ 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x66e4, 0x0005,
+ 0x20a1, 0x020b, 0x080c, 0x612f, 0x20a3, 0x0200, 0x0804, 0x5ee2,
+ 0x20a1, 0x020b, 0x080c, 0x612f, 0x20a3, 0x0100, 0x20a3, 0x0000,
+ 0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x66e4,
+ 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x612f, 0x20a3, 0x0210,
0x20a3, 0x0014, 0x20a3, 0x0800, 0x7818, 0x2068, 0x6894, 0xa086,
0x0014, 0x1178, 0x6998, 0xa184, 0xc000, 0x1140, 0xd1ec, 0x0118,
0x20a3, 0x2100, 0x0040, 0x20a3, 0x0100, 0x0028, 0x20a3, 0x0400,
0x0010, 0x20a3, 0x0700, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2,
- 0x20a2, 0x00f6, 0x2079, 0x9251, 0x7904, 0x00fe, 0xd1ac, 0x1110,
- 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010, 0x2009, 0x9273,
+ 0x20a2, 0x00f6, 0x2079, 0x8b51, 0x7904, 0x00fe, 0xd1ac, 0x1110,
+ 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010, 0x2009, 0x8b73,
0x210c, 0xd184, 0x1110, 0xa085, 0x0002, 0x20a2, 0x20a2, 0x20a2,
- 0x60c3, 0x0014, 0x080c, 0x6f0b, 0x00de, 0x0005, 0x20a1, 0x020b,
- 0x080c, 0x68a0, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0000,
+ 0x60c3, 0x0014, 0x080c, 0x66e4, 0x00de, 0x0005, 0x20a1, 0x020b,
+ 0x080c, 0x612f, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0000,
0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
- 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x6f0b, 0x0005, 0x20a1,
- 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0200, 0x0804, 0x65fb, 0x20a1,
- 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3,
- 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x6f0b, 0x0005,
- 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, 0x020b, 0x080c, 0x68a0,
+ 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x66e4, 0x0005, 0x20a1,
+ 0x020b, 0x080c, 0x612f, 0x20a3, 0x0200, 0x0804, 0x5e83, 0x20a1,
+ 0x020b, 0x080c, 0x612f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3,
+ 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x66e4, 0x0005,
+ 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, 0x020b, 0x080c, 0x612f,
0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3, 0x0000,
- 0x60c3, 0x0008, 0x080c, 0x6f0b, 0x0005, 0x0026, 0x20e1, 0x9080,
+ 0x60c3, 0x0008, 0x080c, 0x66e4, 0x0005, 0x0026, 0x20e1, 0x9080,
0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e,
0x1198, 0x20a3, 0x22ff, 0x20a3, 0xfffe, 0x20a3, 0x0000, 0x2011,
- 0x9214, 0x2214, 0x2001, 0x94d7, 0x2004, 0xa005, 0x0118, 0x2011,
- 0x921c, 0x2214, 0x22a2, 0x0498, 0xa286, 0x007f, 0x1130, 0x00d6,
- 0x20a3, 0x22ff, 0x20a3, 0xfffd, 0x00c8, 0x2001, 0x9232, 0x2004,
+ 0x8b14, 0x2214, 0x2001, 0x8d9c, 0x2004, 0xa005, 0x0118, 0x2011,
+ 0x8b1c, 0x2214, 0x22a2, 0x04d0, 0xa286, 0x007f, 0x1130, 0x00d6,
+ 0x20a3, 0x22ff, 0x20a3, 0xfffd, 0x00c8, 0x2001, 0x8b32, 0x2004,
0xd0ac, 0x1110, 0xd2bc, 0x01c8, 0xa286, 0x0080, 0x00d6, 0x1128,
- 0x20a3, 0x22ff, 0x20a3, 0xfffc, 0x0048, 0xa2e8, 0x936e, 0x2d6c,
- 0x6810, 0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x921b,
- 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0050, 0x20a3, 0x2200, 0x6298,
- 0x22a2, 0x20a3, 0x0000, 0x2011, 0x9214, 0x2214, 0x22a2, 0x20a3,
- 0x0129, 0x20a3, 0x0000, 0x080c, 0x6efa, 0x22a2, 0x20a3, 0x0000,
- 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e,
- 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff,
- 0x2011, 0xfffc, 0x22a2, 0x00d6, 0x2069, 0x921b, 0x2da6, 0x8d68,
- 0x2da6, 0x00de, 0x20a3, 0x2029, 0x20a3, 0x0000, 0x08e0, 0x20a3,
- 0x0100, 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x0005,
- 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
- 0x2004, 0x2011, 0x9232, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e,
- 0x02e0, 0x00d6, 0xa0e8, 0x936e, 0x2d6c, 0x6810, 0xa085, 0x2300,
- 0x20a2, 0x6814, 0x20a2, 0x6810, 0xa005, 0x1140, 0x6814, 0xa005,
- 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0028, 0x2069, 0x921b,
- 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0050, 0x20a3, 0x2300, 0x6298,
- 0x22a2, 0x20a3, 0x0000, 0x2011, 0x9214, 0x2214, 0x22a2, 0x20a3,
- 0x0198, 0x20a3, 0x0000, 0x080c, 0x6efa, 0x22a2, 0x20a3, 0x0000,
- 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e,
- 0x0005, 0x080c, 0x6efa, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2,
- 0x7810, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005,
- 0x00c6, 0x00f6, 0x6004, 0xa08a, 0x0085, 0x0a0c, 0x13fe, 0xa08a,
- 0x008c, 0x1a0c, 0x13fe, 0x6118, 0x2178, 0x79a0, 0x2011, 0x9232,
- 0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120,
- 0x7914, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8,
- 0x2719, 0x2f0d, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a,
- 0xa082, 0x0085, 0x001b, 0x00fe, 0x00ce, 0x0005, 0x692f, 0x6939,
- 0x6954, 0x692d, 0x692d, 0x692d, 0x692f, 0x080c, 0x13fe, 0x0146,
- 0x20a1, 0x020b, 0x04a1, 0x60c3, 0x0000, 0x080c, 0x6f0b, 0x014e,
- 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6999, 0x20a3, 0x0000,
- 0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000,
- 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
- 0x080c, 0x6f0b, 0x014e, 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c,
- 0x69d1, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3,
- 0x0000, 0x60c3, 0x0004, 0x080c, 0x6f0b, 0x014e, 0x0005, 0x0026,
+ 0x20a3, 0x22ff, 0x20a3, 0xfffc, 0x0048, 0xa2e8, 0x8c34, 0x2d6c,
+ 0x6810, 0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x8b1b,
+ 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa2e8, 0x8c34,
+ 0x2d6c, 0x6810, 0xa085, 0x2200, 0x20a2, 0x6814, 0x20a2, 0x00de,
+ 0x20a3, 0x0000, 0x2011, 0x8b14, 0x2214, 0x22a2, 0x20a3, 0x0129,
+ 0x20a3, 0x0000, 0x080c, 0x66d3, 0x22a2, 0x20a3, 0x0000, 0x2fa2,
+ 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005,
+ 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, 0x2011,
+ 0xfffc, 0x22a2, 0x00d6, 0x2069, 0x8b1b, 0x2da6, 0x8d68, 0x2da6,
+ 0x00de, 0x20a3, 0x2029, 0x20a3, 0x0000, 0x08e0, 0x20a3, 0x0100,
+ 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x0005, 0x0026,
0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
- 0x2011, 0x9232, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288,
- 0x00d6, 0xa0e8, 0x936e, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2,
- 0x6814, 0x20a2, 0x2069, 0x921b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
- 0x0050, 0x20a3, 0x8100, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x2011,
- 0x9214, 0x2214, 0x22a2, 0x20a3, 0x0009, 0x20a3, 0x0000, 0x0804,
- 0x6873, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080,
- 0x0028, 0x2004, 0x2011, 0x9232, 0x2214, 0xd2ac, 0x1118, 0xa092,
- 0x007e, 0x0288, 0x00d6, 0xa0e8, 0x936e, 0x2d6c, 0x6810, 0xa085,
- 0x8400, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x921b, 0x2da6, 0x8d68,
- 0x2da6, 0x00de, 0x0050, 0x20a3, 0x8400, 0x6298, 0x22a2, 0x20a3,
- 0x0000, 0x2011, 0x9214, 0x2214, 0x22a2, 0x080c, 0x4dc5, 0x1118,
- 0x20a3, 0x0099, 0x0010, 0x20a3, 0x00d1, 0x20a3, 0x0000, 0x0804,
- 0x68e9, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080,
- 0x0028, 0x2004, 0x2011, 0x9232, 0x2214, 0xd2ac, 0x1118, 0xa092,
- 0x007e, 0x0288, 0x00d6, 0xa0e8, 0x936e, 0x2d6c, 0x6810, 0xa085,
- 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x921b, 0x2da6, 0x8d68,
- 0x2da6, 0x00de, 0x0050, 0x20a3, 0x8500, 0x6298, 0x22a2, 0x20a3,
- 0x0000, 0x2011, 0x9214, 0x2214, 0x22a2, 0x20a3, 0x0099, 0x20a3,
- 0x0000, 0x0804, 0x68e9, 0x00c6, 0x00f6, 0x2c78, 0x7804, 0xa08a,
- 0x0040, 0x0a0c, 0x13fe, 0xa08a, 0x0053, 0x1a0c, 0x13fe, 0x7918,
- 0x2160, 0x61a0, 0x2011, 0x9232, 0x2214, 0xd2ac, 0x1110, 0xd1bc,
- 0x0150, 0x6100, 0xd1f4, 0x0120, 0x6114, 0xa18c, 0x00ff, 0x0040,
- 0x2009, 0x0000, 0x0028, 0xa1e0, 0x2719, 0x2c0d, 0xa18c, 0x00ff,
- 0x2061, 0x0100, 0x619a, 0xa082, 0x0040, 0x001b, 0x00fe, 0x00ce,
- 0x0005, 0x6a46, 0x6b3a, 0x6ade, 0x6c75, 0x6a44, 0x6a44, 0x6a44,
- 0x6a44, 0x6a44, 0x6a44, 0x6a44, 0x71f1, 0x7201, 0x7211, 0x7221,
- 0x6a44, 0x6a44, 0x6a44, 0x71e0, 0x080c, 0x13fe, 0x00d6, 0x0156,
- 0x0146, 0x20a1, 0x020b, 0x080c, 0x6a9c, 0x7910, 0x2168, 0x6948,
- 0x7922, 0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184,
- 0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184, 0x0118, 0x2001,
- 0x0004, 0x0018, 0xa084, 0x0006, 0x8004, 0x20a2, 0xd1ac, 0x0118,
- 0x20a3, 0x0002, 0x0048, 0xd1b4, 0x0118, 0x20a3, 0x0001, 0x0020,
- 0x20a3, 0x0000, 0x2230, 0x0010, 0x6a80, 0x6e7c, 0x20a9, 0x0008,
- 0x0136, 0xad88, 0x0017, 0x2198, 0x20a1, 0x021b, 0x53a6, 0x013e,
- 0x20a1, 0x020b, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080,
- 0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0x9501,
- 0x2003, 0x07d0, 0x2001, 0x9500, 0x2003, 0x0009, 0x080c, 0x165a,
- 0x014e, 0x015e, 0x00de, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000,
- 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202,
- 0x8217, 0x7818, 0xa080, 0x0028, 0x2004, 0x2019, 0x9232, 0x231c,
- 0xd3ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0x936e, 0x2d6c,
- 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x921b,
- 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0050, 0x20a3, 0x0600, 0x6198,
- 0x21a2, 0x20a3, 0x0000, 0x2009, 0x9214, 0x210c, 0x21a2, 0x20a3,
- 0x0829, 0x20a3, 0x0000, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3,
- 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x0005, 0x00d6, 0x0156,
- 0x0136, 0x0146, 0x20a1, 0x020b, 0x00c1, 0x7810, 0x2068, 0x6860,
- 0x20a2, 0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006,
- 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c, 0x080c, 0x6f0b,
- 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0026, 0x20e1, 0x9080,
- 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0x9232,
- 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0x936e,
- 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2, 0x2069,
- 0x921b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0050, 0x20a3, 0x0500,
- 0x6298, 0x22a2, 0x20a3, 0x0000, 0x2011, 0x9214, 0x2214, 0x22a2,
- 0x20a3, 0x0889, 0x20a3, 0x0000, 0x080c, 0x6efa, 0x22a2, 0x20a3,
- 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000,
- 0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x20a1, 0x020b,
- 0x080c, 0x6c38, 0x7810, 0x2068, 0xa016, 0x22a2, 0x22a2, 0x22a2,
- 0x22a2, 0x22a2, 0x7810, 0xa084, 0xf000, 0x1130, 0x7810, 0xa084,
- 0x0700, 0x8007, 0x0043, 0x0010, 0xa006, 0x002b, 0x014e, 0x013e,
- 0x015e, 0x00de, 0x0005, 0x6b65, 0x6bde, 0x6be1, 0x6c04, 0x6c11,
- 0x6c23, 0x6c26, 0x6b63, 0x080c, 0x13fe, 0x0016, 0x0036, 0x694c,
- 0xa18c, 0x0003, 0xa186, 0x0000, 0x1150, 0x6b78, 0x23a2, 0x6868,
- 0x20a2, 0x6864, 0x20a2, 0x003e, 0x001e, 0x0804, 0x6c08, 0xa186,
- 0x0001, 0x1904, 0x6bd9, 0x6b78, 0x23a2, 0x6868, 0x20a2, 0x6864,
- 0x20a2, 0x22a2, 0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009,
- 0x0018, 0xa384, 0x0300, 0x0904, 0x6bd8, 0xd3c4, 0x0110, 0x687c,
- 0xa108, 0xd3cc, 0x0110, 0x6874, 0xa108, 0x0156, 0x20a9, 0x000d,
- 0xad80, 0x0020, 0x201c, 0x831f, 0x23a2, 0x8000, 0x1f04, 0x6b9a,
- 0x015e, 0x22a2, 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0588, 0x20a1,
- 0x020b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x0006, 0x7818, 0xa080,
- 0x0028, 0x2004, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0x936e, 0x2d6c,
- 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x921b,
- 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0050, 0x20a3, 0x0700, 0x6298,
- 0x22a2, 0x20a3, 0x0000, 0x2011, 0x9214, 0x2214, 0x22a2, 0x000e,
- 0x20a3, 0x0898, 0x20a2, 0x080c, 0x6efa, 0x22a2, 0x20a3, 0x0000,
- 0x61c2, 0x003e, 0x001e, 0x080c, 0x6f0b, 0x0005, 0x20a3, 0x0008,
+ 0x2011, 0x8b32, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x02e0,
+ 0x00d6, 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x2300, 0x20a2,
+ 0x6814, 0x20a2, 0x6810, 0xa005, 0x1140, 0x6814, 0xa005, 0x1128,
+ 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0028, 0x2069, 0x8b1b, 0x2da6,
+ 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0x8c34, 0x2d6c,
+ 0x6810, 0xa085, 0x2300, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3,
+ 0x0000, 0x2011, 0x8b14, 0x2214, 0x22a2, 0x20a3, 0x0198, 0x20a3,
+ 0x0000, 0x080c, 0x66d3, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2,
+ 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x080c,
+ 0x66d3, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x7810, 0x20a2,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00c6, 0x00f6,
+ 0x6004, 0xa08a, 0x0085, 0x0a0c, 0x1410, 0xa08a, 0x008c, 0x1a0c,
+ 0x1410, 0x6118, 0x2178, 0x79a0, 0x2011, 0x8b32, 0x2214, 0xd2ac,
+ 0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c,
+ 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8, 0x263d, 0x2f0d,
+ 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082, 0x0085,
+ 0x001b, 0x00fe, 0x00ce, 0x0005, 0x61c5, 0x61cf, 0x61ea, 0x61c3,
+ 0x61c3, 0x61c3, 0x61c5, 0x080c, 0x1410, 0x0146, 0x20a1, 0x020b,
+ 0x04a1, 0x60c3, 0x0000, 0x080c, 0x66e4, 0x014e, 0x0005, 0x0146,
+ 0x20a1, 0x020b, 0x080c, 0x6236, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0xffff,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c, 0x080c, 0x66e4,
+ 0x014e, 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6275, 0x20a3,
+ 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+ 0x0004, 0x080c, 0x66e4, 0x014e, 0x0005, 0x0026, 0x20e1, 0x9080,
+ 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0x8b32,
+ 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8,
+ 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2,
+ 0x2069, 0x8b1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6,
+ 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814,
+ 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0x8b14, 0x2214, 0x22a2,
+ 0x20a3, 0x0009, 0x20a3, 0x0000, 0x0804, 0x6102, 0x0026, 0x20e1,
+ 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011,
+ 0x8b32, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, 0x00d6,
+ 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2, 0x6814,
+ 0x20a2, 0x2069, 0x8b1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088,
+ 0x00d6, 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2,
+ 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0x8b14, 0x2214,
+ 0x22a2, 0x080c, 0x4c42, 0x1118, 0x20a3, 0x0099, 0x0010, 0x20a3,
+ 0x00d1, 0x20a3, 0x0000, 0x0804, 0x617f, 0x0026, 0x20e1, 0x9080,
+ 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0x8b32,
+ 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8,
+ 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2,
+ 0x2069, 0x8b1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6,
+ 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814,
+ 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0x8b14, 0x2214, 0x22a2,
+ 0x20a3, 0x0099, 0x20a3, 0x0000, 0x0804, 0x617f, 0x00c6, 0x00f6,
+ 0x2c78, 0x7804, 0xa08a, 0x0040, 0x0a0c, 0x1410, 0xa08a, 0x0053,
+ 0x1a0c, 0x1410, 0x7918, 0x2160, 0x61a0, 0x2011, 0x8b32, 0x2214,
+ 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x6100, 0xd1f4, 0x0120, 0x6114,
+ 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1e0, 0x263d,
+ 0x2c0d, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0xa082, 0x0040,
+ 0x001b, 0x00fe, 0x00ce, 0x0005, 0x62f1, 0x63f3, 0x6390, 0x653f,
+ 0x62ef, 0x62ef, 0x62ef, 0x62ef, 0x62ef, 0x62ef, 0x62ef, 0x69be,
+ 0x69ce, 0x69de, 0x69ee, 0x62ef, 0x62ef, 0x62ef, 0x69ad, 0x080c,
+ 0x1410, 0x00d6, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6347,
+ 0x7910, 0x2168, 0x6948, 0x7922, 0x21a2, 0xa016, 0x22a2, 0x22a2,
+ 0x22a2, 0x694c, 0xa184, 0x000f, 0x1118, 0x2001, 0x0005, 0x0040,
+ 0xd184, 0x0118, 0x2001, 0x0004, 0x0018, 0xa084, 0x0006, 0x8004,
+ 0x20a2, 0xd1ac, 0x0118, 0x20a3, 0x0002, 0x0048, 0xd1b4, 0x0118,
+ 0x20a3, 0x0001, 0x0020, 0x20a3, 0x0000, 0x2230, 0x0010, 0x6a80,
+ 0x6e7c, 0x20a9, 0x0008, 0x0136, 0xad88, 0x0017, 0x2198, 0x20a1,
+ 0x021b, 0x53a6, 0x013e, 0x20a1, 0x020b, 0x22a2, 0x26a2, 0x60c3,
+ 0x0020, 0x20e1, 0x9080, 0x6014, 0xa084, 0x0004, 0xa085, 0x0009,
+ 0x6016, 0x2001, 0x8dc6, 0x2003, 0x07d0, 0x2001, 0x8dc5, 0x2003,
+ 0x0009, 0x080c, 0x166c, 0x014e, 0x015e, 0x00de, 0x0005, 0x20e1,
+ 0x9080, 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210,
+ 0xa294, 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004,
+ 0x2019, 0x8b32, 0x231c, 0xd3ac, 0x1110, 0xd0bc, 0x0188, 0x00d6,
+ 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814,
+ 0x20a2, 0x2069, 0x8b1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088,
+ 0x00d6, 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2,
+ 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2009, 0x8b14, 0x210c,
+ 0x21a2, 0x20a3, 0x0829, 0x20a3, 0x0000, 0x22a2, 0x20a3, 0x0000,
+ 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x0005,
+ 0x00d6, 0x0156, 0x0136, 0x0146, 0x20a1, 0x020b, 0x00c1, 0x7810,
+ 0x2068, 0x6860, 0x20a2, 0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c,
+ 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c,
+ 0x080c, 0x66e4, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0026,
+ 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+ 0x2011, 0x8b32, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6,
+ 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814,
+ 0x20a2, 0x2069, 0x8b1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088,
+ 0x00d6, 0xa0e8, 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2,
+ 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0x8b14, 0x2214,
+ 0x22a2, 0x20a3, 0x0889, 0x20a3, 0x0000, 0x080c, 0x66d3, 0x22a2,
+ 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x20a1,
+ 0x020b, 0x080c, 0x64fb, 0x7810, 0x2068, 0xa016, 0x22a2, 0x22a2,
+ 0x22a2, 0x22a2, 0x22a2, 0x7810, 0xa084, 0xf000, 0x1130, 0x7810,
+ 0xa084, 0x0700, 0x8007, 0x0043, 0x0010, 0xa006, 0x002b, 0x014e,
+ 0x013e, 0x015e, 0x00de, 0x0005, 0x641e, 0x649e, 0x64a1, 0x64c4,
+ 0x64d1, 0x64e6, 0x64e9, 0x641c, 0x080c, 0x1410, 0x0016, 0x0036,
+ 0x694c, 0xa18c, 0x0003, 0xa186, 0x0000, 0x1150, 0x6b78, 0x23a2,
+ 0x6868, 0x20a2, 0x6864, 0x20a2, 0x003e, 0x001e, 0x0804, 0x64c8,
+ 0xa186, 0x0001, 0x1904, 0x6499, 0x6b78, 0x23a2, 0x6868, 0x20a2,
+ 0x6864, 0x20a2, 0x22a2, 0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2,
+ 0x2009, 0x0018, 0xa384, 0x0300, 0x0904, 0x6498, 0xd3c4, 0x0110,
+ 0x687c, 0xa108, 0xd3cc, 0x0110, 0x6874, 0xa108, 0x0156, 0x20a9,
+ 0x000d, 0xad80, 0x0020, 0x201c, 0x831f, 0x23a2, 0x8000, 0x1f04,
+ 0x6453, 0x015e, 0x22a2, 0x22a2, 0x22a2, 0xa184, 0x0003, 0x05c0,
+ 0x20a1, 0x020b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x0006, 0x7818,
+ 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0x8c34,
+ 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069,
+ 0x8b1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8,
+ 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
+ 0x00de, 0x20a3, 0x0000, 0x2011, 0x8b14, 0x2214, 0x22a2, 0x000e,
+ 0x20a3, 0x0898, 0x20a2, 0x080c, 0x66d3, 0x22a2, 0x20a3, 0x0000,
+ 0x61c2, 0x003e, 0x001e, 0x080c, 0x66e4, 0x0005, 0x20a3, 0x0008,
0x0428, 0x20a3, 0x0302, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012,
0x22a2, 0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3,
0x7000, 0x20a3, 0x0500, 0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2,
0x20a3, 0x2500, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3,
- 0x0032, 0x080c, 0x6f0b, 0x0005, 0x20a3, 0x0028, 0x22a2, 0x22a2,
- 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0018, 0x080c, 0x6f0b,
+ 0x0032, 0x080c, 0x66e4, 0x0005, 0x20a3, 0x0028, 0x22a2, 0x22a2,
+ 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0018, 0x080c, 0x66e4,
0x0005, 0x20a3, 0x0100, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
- 0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0020,
- 0x080c, 0x6f0b, 0x0005, 0x20a3, 0x0008, 0x0c00, 0x0036, 0x7b10,
- 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001, 0x1118, 0x22a2,
- 0x003e, 0x08a0, 0x20a3, 0x0800, 0x22a2, 0x20a2, 0x003e, 0x0880,
- 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
- 0x2004, 0x2011, 0x9232, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
- 0x00d6, 0xa0e8, 0x936e, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
- 0x6814, 0x20a2, 0x2069, 0x921b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
- 0x0050, 0x20a3, 0x0700, 0x6298, 0x22a2, 0x20a3, 0x0000, 0x2011,
- 0x9214, 0x2214, 0x22a2, 0x20a3, 0x0898, 0x20a3, 0x0000, 0x080c,
- 0x6efa, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00d6, 0x0156, 0x0136,
- 0x0146, 0x0016, 0x0036, 0x7810, 0xa084, 0x0700, 0x8007, 0x003b,
- 0x003e, 0x001e, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x6c8f,
- 0x6c8f, 0x6c91, 0x6c8f, 0x6c8f, 0x6c8f, 0x6cb3, 0x6c8f, 0x080c,
- 0x13fe, 0x7910, 0xa18c, 0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1,
- 0x020b, 0x2009, 0x0003, 0x00f9, 0x00d6, 0x2069, 0x9251, 0x6804,
- 0xd0bc, 0x0130, 0x682c, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0010,
- 0x20a3, 0x3f00, 0x00de, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001,
- 0x080c, 0x6f0b, 0x0005, 0x20a1, 0x020b, 0x2009, 0x0003, 0x0019,
- 0x20a3, 0x7f00, 0x0c80, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000,
- 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0x9232, 0x2214, 0xd2ac,
- 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0x936e, 0x2d6c, 0x6810,
- 0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x921b, 0x2da6,
- 0x8d68, 0x2da6, 0x00de, 0x0050, 0x20a3, 0x0100, 0x6298, 0x22a2,
- 0x20a3, 0x0000, 0x2011, 0x9214, 0x2214, 0x22a2, 0x20a3, 0x0888,
- 0xa18d, 0x0008, 0x21a2, 0x080c, 0x6efa, 0x22a2, 0x20a3, 0x0000,
- 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e,
- 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036,
- 0x2061, 0x0100, 0x2071, 0x9200, 0x2009, 0x9214, 0x210c, 0x7818,
- 0x2068, 0x2031, 0x9232, 0x2634, 0xa6b4, 0x0028, 0x0110, 0x736c,
- 0x7470, 0x2500, 0x2031, 0x9232, 0x2634, 0xa6b4, 0x0028, 0x0140,
- 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, 0x636a, 0x646e, 0x0050,
- 0x2001, 0x00ff, 0xa085, 0x0400, 0x6062, 0x6067, 0xffff, 0x606b,
- 0x0000, 0x616e, 0x68b8, 0x6072, 0x6077, 0x0008, 0x688c, 0x8000,
- 0xa084, 0x00ff, 0x688e, 0x8007, 0xa085, 0x0020, 0x607a, 0x68b4,
- 0x607f, 0x0000, 0x2d00, 0x6082, 0x6087, 0xffff, 0x7810, 0x2070,
- 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca,
- 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000,
- 0x2001, 0x9232, 0x2004, 0xd09c, 0x0128, 0x609f, 0x0000, 0x2001,
- 0x0012, 0x0048, 0x6028, 0xc0bd, 0x602a, 0x609f, 0x00ff, 0x6027,
- 0xffff, 0x2001, 0x0032, 0x6016, 0x2009, 0x07d0, 0x080c, 0x57a6,
- 0x2001, 0x9295, 0x200c, 0xc185, 0x2102, 0x003e, 0x004e, 0x005e,
- 0x006e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x00e6, 0x00d6, 0x00c6,
- 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x9200,
- 0x2009, 0x9214, 0x210c, 0x7818, 0x2068, 0x68a0, 0x2028, 0x2031,
- 0x9232, 0x2634, 0xd6ac, 0x1140, 0xd0bc, 0x1130, 0xa080, 0x2719,
- 0x2015, 0xa294, 0x00ff, 0x0020, 0x6910, 0x6a14, 0x736c, 0x7470,
- 0x2001, 0x9232, 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138, 0xa185,
- 0x0400, 0x6062, 0x6266, 0x636a, 0x646e, 0x0030, 0x6063, 0x0400,
- 0x6266, 0x606b, 0x0000, 0x616e, 0x68b8, 0x6072, 0x6077, 0x0008,
- 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0xa085, 0x0020,
- 0x607a, 0x68b4, 0x607f, 0x0000, 0x2d00, 0x6082, 0x6087, 0xffff,
- 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6,
- 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5,
- 0x60d7, 0x0000, 0xa582, 0x0080, 0x0210, 0x2011, 0x0000, 0x629e,
- 0x00f6, 0x2079, 0x0140, 0x7803, 0x0000, 0x00fe, 0x6017, 0x0012,
- 0x2009, 0x07d0, 0x080c, 0x57a6, 0x003e, 0x004e, 0x005e, 0x006e,
- 0x00ce, 0x00de, 0x00ee, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0056,
- 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x9200, 0x7150, 0x7818,
- 0x2068, 0x68a0, 0x2028, 0x76c8, 0xd6ac, 0x1140, 0xd0bc, 0x1130,
- 0xa080, 0x2719, 0x2015, 0xa294, 0x00ff, 0x0020, 0x6910, 0x6a14,
- 0x736c, 0x7470, 0x781c, 0xa086, 0x0006, 0x0904, 0x6e65, 0x70c8,
- 0xd0ac, 0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266,
- 0x636a, 0x646e, 0x0030, 0x6063, 0x0100, 0x6266, 0x606b, 0x0000,
- 0x616e, 0x6073, 0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084,
- 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082,
- 0x7808, 0x6086, 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e,
- 0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036,
- 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0248, 0x6a00,
- 0xd2f4, 0x0120, 0x6a14, 0xa294, 0x00ff, 0x0010, 0x2011, 0x0000,
- 0x629e, 0x6017, 0x0016, 0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0,
- 0xa005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x57a6, 0x003e, 0x004e,
- 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7810, 0x2070, 0x704c,
- 0xa084, 0x0003, 0xa086, 0x0002, 0x0904, 0x6eb4, 0x2001, 0x9232,
- 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062,
- 0x6266, 0x636a, 0x646e, 0x0030, 0x6063, 0x0100, 0x6266, 0x606b,
- 0x0000, 0x616e, 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000,
- 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00,
- 0x6086, 0x7808, 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080,
- 0x60c6, 0x707c, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af,
- 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4,
- 0x0120, 0x6a14, 0xa294, 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e,
- 0x6017, 0x0012, 0x0804, 0x6e53, 0x2001, 0x9232, 0x2004, 0xd0ac,
- 0x1110, 0xd5bc, 0x0138, 0xa185, 0x0700, 0x6062, 0x6266, 0x636a,
- 0x646e, 0x0030, 0x6063, 0x0700, 0x6266, 0x606b, 0x0000, 0x616e,
- 0x6073, 0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff,
- 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808,
- 0x6082, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008,
- 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7,
- 0x0000, 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14,
- 0xa294, 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x6017, 0x0016,
- 0x0804, 0x6e53, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294,
- 0x00ff, 0x2202, 0x8217, 0x0005, 0x00d6, 0x2069, 0x94e5, 0x6843,
- 0x0001, 0x00de, 0x0005, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7,
- 0x9575, 0x0019, 0x080c, 0x5798, 0x0005, 0x0006, 0x6014, 0xa084,
- 0x0004, 0xa085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0006, 0x00c6,
- 0x2061, 0x0100, 0x6014, 0xa084, 0x0004, 0xa085, 0x0008, 0x6016,
- 0x00ce, 0x000e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x080c,
- 0x57a1, 0x2061, 0x0100, 0x2069, 0x0140, 0x6904, 0xa194, 0x4000,
- 0x0538, 0x0c21, 0x6803, 0x1000, 0x6803, 0x0000, 0x00c6, 0x2061,
- 0x94e5, 0x6128, 0xa192, 0x0002, 0x1250, 0x8108, 0x612a, 0x6124,
- 0x00ce, 0x81ff, 0x0180, 0x080c, 0x5798, 0x0839, 0x0060, 0x6124,
- 0xa1e5, 0x0000, 0x0130, 0x080c, 0x91a0, 0x2009, 0x0014, 0x080c,
- 0x7518, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005,
- 0x080c, 0x4dc5, 0x1118, 0x080c, 0x6f1e, 0x08c0, 0x080c, 0x4105,
- 0x0c90, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, 0x57ae,
- 0x2071, 0x94e5, 0x713c, 0x81ff, 0x0578, 0x2061, 0x0100, 0x2069,
- 0x0140, 0x6904, 0xa194, 0x4000, 0x0568, 0x6803, 0x1000, 0x6803,
- 0x0000, 0x0036, 0x2019, 0x0001, 0x080c, 0x7110, 0x003e, 0x713c,
- 0x2160, 0x080c, 0x91a0, 0x2009, 0x004a, 0x621c, 0xa296, 0x0009,
- 0x1110, 0x2009, 0x0104, 0x080c, 0x7518, 0x080c, 0x4dc5, 0x1160,
- 0x0006, 0x2001, 0x94d8, 0x2003, 0x0002, 0x2001, 0x9200, 0x2003,
- 0x0001, 0x080c, 0x4d10, 0x000e, 0x002e, 0x001e, 0x00ee, 0x00de,
- 0x00ce, 0x0005, 0x08b0, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056,
- 0x0046, 0x0006, 0x0126, 0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0,
- 0x2071, 0x94e5, 0x7018, 0x2068, 0x8dff, 0x0198, 0x68a0, 0xa406,
- 0x0118, 0x6854, 0x2068, 0x0cc0, 0x6010, 0x2060, 0x643c, 0x6540,
- 0x6e48, 0x2d60, 0x080c, 0x457f, 0x0120, 0x080c, 0x7238, 0xa085,
- 0x0001, 0x012e, 0x000e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de,
- 0x00ee, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x681d,
- 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2,
- 0x60c3, 0x0008, 0x080c, 0x6f0b, 0x014e, 0x015e, 0x0005, 0x0156,
- 0x0146, 0x20a1, 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0200, 0x20a3,
- 0x0000, 0x20a9, 0x0006, 0x2011, 0x9240, 0x2019, 0x9241, 0x23a6,
- 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x1f04, 0x6fff, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x6f0b, 0x014e,
- 0x015e, 0x0005, 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b,
- 0x080c, 0x6881, 0x080c, 0x6897, 0x7810, 0x0006, 0xa080, 0x0015,
- 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6, 0xa080, 0x0004,
+ 0x20a3, 0x0008, 0x22a2, 0x7824, 0xa084, 0x00ff, 0x20a2, 0x22a2,
+ 0x22a2, 0x60c3, 0x0020, 0x080c, 0x66e4, 0x0005, 0x20a3, 0x0008,
+ 0x08e8, 0x0036, 0x7b10, 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff,
+ 0x8001, 0x1118, 0x22a2, 0x003e, 0x0888, 0x20a3, 0x0800, 0x22a2,
+ 0x20a2, 0x003e, 0x0868, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000,
+ 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0x8b32, 0x2214, 0xd2ac,
+ 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0x8c34, 0x2d6c, 0x6810,
+ 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, 0x8b1b, 0x2da6,
+ 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0x8c34, 0x2d6c,
+ 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3,
+ 0x0000, 0x2011, 0x8b14, 0x2214, 0x22a2, 0x20a3, 0x0898, 0x20a3,
+ 0x0000, 0x080c, 0x66d3, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2,
+ 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00d6,
+ 0x0156, 0x0136, 0x0146, 0x0016, 0x0036, 0x7810, 0xa084, 0x0700,
+ 0x8007, 0x003b, 0x003e, 0x001e, 0x014e, 0x013e, 0x015e, 0x00de,
+ 0x0005, 0x6559, 0x6559, 0x655b, 0x6559, 0x6559, 0x6559, 0x657d,
+ 0x6559, 0x080c, 0x1410, 0x7910, 0xa18c, 0xf8ff, 0xa18d, 0x0600,
+ 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003, 0x00f9, 0x00d6, 0x2069,
+ 0x8b51, 0x6804, 0xd0bc, 0x0130, 0x682c, 0xa084, 0x00ff, 0x8007,
+ 0x20a2, 0x0010, 0x20a3, 0x3f00, 0x00de, 0x22a2, 0x22a2, 0x22a2,
+ 0x60c3, 0x0001, 0x080c, 0x66e4, 0x0005, 0x20a1, 0x020b, 0x2009,
+ 0x0003, 0x0019, 0x20a3, 0x7f00, 0x0c80, 0x0026, 0x20e1, 0x9080,
+ 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0x8b32,
+ 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0x8c34,
+ 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2, 0x2069,
+ 0x8b1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8,
+ 0x8c34, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2,
+ 0x00de, 0x20a3, 0x0000, 0x2011, 0x8b14, 0x2214, 0x22a2, 0x20a3,
+ 0x0888, 0xa18d, 0x0008, 0x21a2, 0x080c, 0x66d3, 0x22a2, 0x20a3,
+ 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x002e, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0056, 0x0046, 0x0036,
+ 0x2061, 0x0100, 0x2071, 0x8b00, 0x7150, 0x7818, 0x2068, 0x68a0,
+ 0x2028, 0x76c8, 0xd6ac, 0x1130, 0xd0bc, 0x1120, 0x6910, 0x6a14,
+ 0x7450, 0x0020, 0x6910, 0x6a14, 0x736c, 0x7470, 0x781c, 0xa086,
+ 0x0006, 0x0904, 0x6640, 0x70c8, 0xd0ac, 0x1110, 0xd5bc, 0x0138,
+ 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0038, 0xa185,
+ 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x6073, 0x0809,
+ 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007,
+ 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7810,
+ 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008,
+ 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582,
+ 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294, 0x00ff,
+ 0x0010, 0x2011, 0x0000, 0x629e, 0x080c, 0x6cb4, 0x2009, 0x07d0,
+ 0x60c4, 0xa084, 0xfff0, 0xa005, 0x0110, 0x2009, 0x1b58, 0x080c,
+ 0x567f, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005,
+ 0x7810, 0x2070, 0x704c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0904,
+ 0x668e, 0x2001, 0x8b32, 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138,
+ 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0038, 0xa185,
+ 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x6073, 0x0880,
+ 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007,
+ 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, 0x7060,
+ 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6, 0x707c, 0x60ca, 0x686c,
+ 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0248,
+ 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294, 0x00ff, 0x0010, 0x2011,
+ 0x0000, 0x629e, 0x080c, 0x6cb1, 0x0804, 0x662e, 0x2001, 0x8b32,
+ 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138, 0xa185, 0x0700, 0x6062,
+ 0x6266, 0x636a, 0x646e, 0x0038, 0xa185, 0x0700, 0x6062, 0x6266,
+ 0x606b, 0x0000, 0x646e, 0x6073, 0x0898, 0x6077, 0x0000, 0x688c,
+ 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000,
+ 0x2f00, 0x6086, 0x7808, 0x6082, 0x7014, 0x608a, 0x7010, 0x608e,
+ 0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5,
+ 0x60d7, 0x0000, 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120,
+ 0x6a14, 0xa294, 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c,
+ 0x6cb4, 0x0804, 0x662e, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210,
+ 0xa294, 0x00ff, 0x2202, 0x8217, 0x0005, 0x00d6, 0x2069, 0x8daa,
+ 0x6843, 0x0001, 0x00de, 0x0005, 0x20e1, 0x9080, 0x60a3, 0x0056,
+ 0x60a7, 0x9575, 0x0019, 0x080c, 0x5671, 0x0005, 0x0006, 0x6014,
+ 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0006,
+ 0x00c6, 0x2061, 0x0100, 0x6014, 0xa084, 0x0004, 0xa085, 0x0008,
+ 0x6016, 0x00ce, 0x000e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026,
+ 0x080c, 0x567a, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x4c42,
+ 0x1128, 0x0c29, 0x080c, 0x4cbf, 0x0150, 0x0438, 0x6904, 0xa194,
+ 0x4000, 0x0540, 0x08e1, 0x6803, 0x1000, 0x6803, 0x0000, 0x00c6,
+ 0x2061, 0x8daa, 0x6128, 0xa192, 0x0002, 0x1258, 0x8108, 0x612a,
+ 0x6124, 0x00ce, 0x81ff, 0x0188, 0x080c, 0x5671, 0x080c, 0x66ee,
+ 0x0060, 0x6124, 0xa1e5, 0x0000, 0x0130, 0x080c, 0x8a4b, 0x2009,
+ 0x0014, 0x080c, 0x6d3f, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de,
+ 0x00ce, 0x0005, 0x080c, 0x403d, 0x0cc0, 0x00c6, 0x00d6, 0x00e6,
+ 0x0016, 0x0026, 0x080c, 0x5687, 0x2071, 0x8daa, 0x713c, 0x81ff,
+ 0x0530, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x4c42, 0x1148,
+ 0x0036, 0x2019, 0x0001, 0x080c, 0x68e5, 0x003e, 0x080c, 0x4cbf,
+ 0x00b0, 0x6904, 0xa194, 0x4000, 0x01c0, 0x6803, 0x1000, 0x6803,
+ 0x0000, 0x0036, 0x2019, 0x0001, 0x080c, 0x68e5, 0x003e, 0x713c,
+ 0x2160, 0x080c, 0x8a4b, 0x2009, 0x004a, 0x080c, 0x6d3f, 0x002e,
+ 0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0c58, 0x00e6, 0x00d6,
+ 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000,
+ 0x6018, 0x2068, 0x6ca0, 0x2071, 0x8daa, 0x7018, 0x2068, 0x8dff,
+ 0x0198, 0x68a0, 0xa406, 0x0118, 0x6854, 0x2068, 0x0cc0, 0x6010,
+ 0x2060, 0x643c, 0x6540, 0x6e48, 0x2d60, 0x080c, 0x4458, 0x0120,
+ 0x080c, 0x6a05, 0xa085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e,
+ 0x006e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x0156, 0x0146, 0x20a1,
+ 0x020b, 0x080c, 0x60a5, 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x7808, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x66e4, 0x014e,
+ 0x015e, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x612f,
+ 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a9, 0x0006, 0x2011, 0x8b40,
+ 0x2019, 0x8b41, 0x23a6, 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002,
+ 0x1f04, 0x67d2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c,
+ 0x080c, 0x66e4, 0x014e, 0x015e, 0x0005, 0x0156, 0x0146, 0x0016,
+ 0x0026, 0x20a1, 0x020b, 0x080c, 0x6110, 0x080c, 0x6126, 0x7810,
+ 0x0006, 0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8,
+ 0x53a6, 0xa080, 0x0004, 0x8003, 0x60c2, 0x000e, 0xa080, 0x0001,
+ 0x2004, 0x7812, 0x080c, 0x66e4, 0x002e, 0x001e, 0x014e, 0x015e,
+ 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x60a5, 0x20a3,
+ 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x60c3,
+ 0x0008, 0x080c, 0x66e4, 0x014e, 0x015e, 0x0005, 0x0156, 0x0146,
+ 0x0016, 0x0026, 0x20a1, 0x020b, 0x080c, 0x60a5, 0x7810, 0x0006,
+ 0xa080, 0x0017, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6,
0x8003, 0x60c2, 0x000e, 0xa080, 0x0001, 0x2004, 0x7812, 0x080c,
- 0x6f0b, 0x002e, 0x001e, 0x014e, 0x015e, 0x0005, 0x0156, 0x0146,
- 0x20a1, 0x020b, 0x080c, 0x681d, 0x20a3, 0x6200, 0x20a3, 0x0000,
- 0x20a3, 0x0000, 0x7808, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x6f0b,
- 0x014e, 0x015e, 0x0005, 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1,
- 0x020b, 0x080c, 0x681d, 0x7810, 0x0006, 0xa080, 0x0017, 0x2098,
- 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x000e,
- 0xa080, 0x0001, 0x2004, 0x7812, 0x080c, 0x6f0b, 0x002e, 0x001e,
- 0x014e, 0x015e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091,
- 0x8000, 0x2071, 0x94e5, 0x700c, 0x2060, 0x8cff, 0x0168, 0x080c,
- 0x84c8, 0x1110, 0x080c, 0x7776, 0x600c, 0x0006, 0x080c, 0x74f2,
- 0x080c, 0x7238, 0x00ce, 0x0c88, 0x700f, 0x0000, 0x700b, 0x0000,
- 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156, 0x00f6,
- 0x00e6, 0x00d6, 0x00c6, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000,
- 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x94e5, 0x7024, 0x2060,
- 0x8cff, 0x05a0, 0x080c, 0x6f1e, 0x68c3, 0x0000, 0x080c, 0x57a1,
- 0x2009, 0x0013, 0x080c, 0x7518, 0x20a9, 0x01f4, 0x6824, 0xd094,
+ 0x66e4, 0x002e, 0x001e, 0x014e, 0x015e, 0x0005, 0x00e6, 0x00c6,
+ 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x8daa, 0x700c, 0x2060,
+ 0x8cff, 0x0178, 0x080c, 0x7d69, 0x1110, 0x080c, 0x6fb6, 0x600c,
+ 0x0006, 0x080c, 0x7df6, 0x080c, 0x6d18, 0x080c, 0x6a05, 0x00ce,
+ 0x0c78, 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x000e, 0x00ce,
+ 0x00ee, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
+ 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079,
+ 0x0140, 0x2071, 0x8daa, 0x7024, 0x2060, 0x8cff, 0x05a0, 0x080c,
+ 0x66f7, 0x68c3, 0x0000, 0x080c, 0x567a, 0x2009, 0x0013, 0x080c,
+ 0x6d3f, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827, 0x0004,
+ 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, 0x0000,
+ 0x0078, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x6883,
+ 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000,
+ 0x6824, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe,
+ 0x015e, 0x012e, 0x0005, 0x2001, 0x8b00, 0x2004, 0xa096, 0x0001,
+ 0x0550, 0xa096, 0x0004, 0x0538, 0x6817, 0x0008, 0x68c3, 0x0000,
+ 0x2011, 0x3fe7, 0x080c, 0x560d, 0x20a9, 0x01f4, 0x6824, 0xd094,
0x0158, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803,
0x1000, 0x7803, 0x0000, 0x0078, 0xd084, 0x0118, 0x6827, 0x0001,
- 0x0010, 0x1f04, 0x70ae, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803,
- 0x0100, 0x7803, 0x0000, 0x6824, 0x000e, 0x001e, 0x002e, 0x00ce,
- 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x9200,
- 0x2004, 0xa096, 0x0001, 0x0550, 0xa096, 0x0004, 0x0538, 0x6817,
- 0x0008, 0x68c3, 0x0000, 0x2011, 0x40af, 0x080c, 0x5731, 0x20a9,
- 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827, 0x0004, 0x7804, 0xa084,
- 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0xd084,
- 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x70e9, 0x7804, 0xa084,
- 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x000e, 0x001e,
- 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005,
- 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0026, 0x0016,
- 0x0006, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071,
- 0x94e5, 0x703c, 0x2060, 0x8cff, 0x0904, 0x7185, 0x6817, 0x0010,
- 0x68c7, 0x0000, 0x68cb, 0x0000, 0x080c, 0x57ae, 0x080c, 0x1ef8,
- 0x0046, 0x0056, 0x2009, 0x017f, 0x212c, 0x200b, 0x00a5, 0x2021,
- 0x0169, 0x2404, 0xa084, 0x000f, 0xa086, 0x0004, 0x11b0, 0x68c7,
- 0x0000, 0x68cb, 0x0008, 0x00e6, 0x00f6, 0x2079, 0x0020, 0x2071,
- 0x953b, 0x6814, 0xa084, 0x0004, 0xa085, 0x0012, 0x6816, 0x7803,
- 0x0008, 0x7003, 0x0000, 0x00fe, 0x00ee, 0x250a, 0x005e, 0x004e,
- 0xa39d, 0x0000, 0x1150, 0x2009, 0x0049, 0x601c, 0xa086, 0x0009,
- 0x1110, 0x2009, 0x0103, 0x080c, 0x7518, 0x20a9, 0x03e8, 0x6824,
- 0xd094, 0x0158, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0,
- 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0xd094, 0x0118, 0x6827,
- 0x0002, 0x0010, 0x1f04, 0x7167, 0x7804, 0xa084, 0x1000, 0x0120,
- 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x000e, 0x001e, 0x002e,
- 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6,
- 0x0126, 0x2091, 0x8000, 0x2069, 0x94e5, 0x6a06, 0x012e, 0x00de,
- 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x94e5, 0x6a32,
- 0x012e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0006,
- 0x0126, 0x2071, 0x94e5, 0x7614, 0x2660, 0x2678, 0x2091, 0x8000,
- 0x8cff, 0x0538, 0x601c, 0xa206, 0x1500, 0x7014, 0xac36, 0x1110,
- 0x660c, 0x7616, 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118,
- 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00,
- 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c,
- 0x849b, 0x080c, 0x7238, 0x00ce, 0x08d8, 0x2c78, 0x600c, 0x2060,
- 0x08b8, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
- 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6a9c, 0x7810, 0x20a2,
- 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0804,
- 0x7230, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6a9c, 0x7810,
- 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000,
- 0x0478, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6a9c, 0x7810,
- 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000,
- 0x00f8, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6a9c, 0x7810,
- 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400,
- 0x0078, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x6a9c, 0x7810,
- 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200,
- 0x0089, 0x60c3, 0x0020, 0x080c, 0x6f0b, 0x014e, 0x015e, 0x0005,
- 0x00e6, 0x2071, 0x94e5, 0x7020, 0xa005, 0x0110, 0x8001, 0x7022,
- 0x00ee, 0x0005, 0x20a9, 0x0008, 0x20a2, 0x1f04, 0x7244, 0x20a2,
- 0x20a2, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066,
- 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x94e5, 0x7614, 0x2660,
- 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0x72d2, 0x8cff, 0x0904,
- 0x72d2, 0x601c, 0xa086, 0x0006, 0x1904, 0x72cd, 0x88ff, 0x0138,
- 0x2800, 0xac06, 0x1904, 0x72cd, 0x2039, 0x0000, 0x0050, 0x6018,
- 0xa206, 0x1904, 0x72cd, 0x85ff, 0x0120, 0x6020, 0xa106, 0x1904,
- 0x72cd, 0x7024, 0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005,
- 0x01f0, 0x080c, 0x57a1, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c,
- 0x7356, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384,
- 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
- 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003,
- 0x0009, 0x630a, 0x0450, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616,
- 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012,
- 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110,
- 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c,
- 0x82ee, 0x0110, 0x080c, 0x9097, 0x080c, 0x849b, 0x080c, 0x7238,
- 0x88ff, 0x1190, 0x00ce, 0x0804, 0x725b, 0x2c78, 0x600c, 0x2060,
- 0x0804, 0x725b, 0xa006, 0x012e, 0x000e, 0x006e, 0x007e, 0x00ce,
- 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6017, 0x0000, 0x00ce, 0xa8c5,
- 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026,
- 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x94e5, 0x7638, 0x2660,
- 0x2678, 0x8cff, 0x0904, 0x7346, 0x601c, 0xa086, 0x0006, 0x1904,
- 0x7341, 0x88ff, 0x0128, 0x2800, 0xac06, 0x1904, 0x7341, 0x0040,
- 0x6018, 0xa206, 0x15f0, 0x85ff, 0x0118, 0x6020, 0xa106, 0x15c8,
- 0x703c, 0xac06, 0x1170, 0x0036, 0x2019, 0x0001, 0x080c, 0x7110,
- 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047, 0x0000,
- 0x003e, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a, 0x7034, 0xac36,
- 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037,
- 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008,
- 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, 0x82ee, 0x0110,
- 0x080c, 0x9097, 0x080c, 0x849b, 0x88ff, 0x1190, 0x00ce, 0x0804,
- 0x72f1, 0x2c78, 0x600c, 0x2060, 0x0804, 0x72f1, 0xa006, 0x012e,
- 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005,
- 0x6017, 0x0000, 0x00ce, 0xa8c5, 0x0001, 0x0c88, 0x00e6, 0x2071,
- 0x94e5, 0x2001, 0x9200, 0x2004, 0xa086, 0x0002, 0x1118, 0x7007,
- 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6,
- 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071,
- 0x94e5, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0518, 0x2200,
- 0xac06, 0x11e0, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a, 0x7034,
- 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010,
- 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008,
- 0x2678, 0x600f, 0x0000, 0xa085, 0x0001, 0x0020, 0x2c78, 0x600c,
- 0x2060, 0x08d8, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee,
- 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0006,
- 0x0126, 0x2091, 0x8000, 0x2071, 0x94e5, 0x760c, 0x2660, 0x2678,
- 0x8cff, 0x0904, 0x7423, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206,
- 0x1904, 0x741e, 0x7024, 0xac06, 0x1500, 0x2069, 0x0100, 0x68c0,
- 0xa005, 0x01d8, 0x080c, 0x6f1e, 0x68c3, 0x0000, 0x080c, 0x7356,
- 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
- 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824,
- 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0xac36, 0x1110,
- 0x660c, 0x760e, 0x7008, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118,
- 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00,
- 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c,
- 0x84b7, 0x1118, 0x080c, 0x2692, 0x00c0, 0x080c, 0x84c8, 0x1118,
- 0x080c, 0x7776, 0x0090, 0x6010, 0x2068, 0x080c, 0x82ee, 0x0168,
- 0x601c, 0xa086, 0x0003, 0x11f8, 0x6837, 0x0103, 0x6b4a, 0x6847,
- 0x0000, 0x080c, 0x4809, 0x080c, 0x848f, 0x6003, 0x0000, 0x080c,
- 0x849b, 0x080c, 0x7238, 0x00ce, 0x0804, 0x73b0, 0x2c78, 0x600c,
- 0x2060, 0x0804, 0x73b0, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00de,
- 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19e8, 0x080c,
- 0x9097, 0x0c18, 0x0036, 0x0156, 0x0136, 0x0146, 0x3908, 0xa006,
- 0xa190, 0x0020, 0x221c, 0xa39e, 0x251b, 0x1118, 0x8210, 0x8000,
- 0x0cc8, 0xa005, 0x0138, 0x20a9, 0x0020, 0x2198, 0xa110, 0x22a0,
- 0x22c8, 0x53a3, 0x014e, 0x013e, 0x015e, 0x003e, 0x0005, 0x00d6,
- 0x20a1, 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0200, 0x20a3, 0x0014,
- 0x60c3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2099, 0x94df,
- 0x20a9, 0x0004, 0x53a6, 0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x080c, 0x6f0b, 0x00de, 0x0005, 0x20a1,
- 0x020b, 0x080c, 0x68a0, 0x20a3, 0x0210, 0x20a3, 0x0018, 0x20a3,
- 0x0800, 0x7810, 0xa084, 0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3,
- 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7810,
- 0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
- 0x0018, 0x080c, 0x6f0b, 0x0005, 0x2061, 0x9900, 0x2a70, 0x7064,
- 0x7046, 0x704b, 0x9900, 0x0005, 0x00e6, 0x0126, 0x2071, 0x9200,
- 0x2091, 0x8000, 0x7544, 0xa582, 0x0001, 0x0608, 0x7048, 0x2060,
+ 0x0010, 0x1f04, 0x68be, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803,
+ 0x0100, 0x7803, 0x0000, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de,
+ 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x0126, 0x0156, 0x00f6,
+ 0x00e6, 0x00d6, 0x00c6, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000,
+ 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x8daa, 0x703c, 0x2060,
+ 0x8cff, 0x0904, 0x6952, 0x6817, 0x0010, 0x68c7, 0x0000, 0x68cb,
+ 0x0000, 0x080c, 0x5687, 0x080c, 0x1e15, 0x0046, 0x2009, 0x017f,
+ 0x200b, 0x00a5, 0x2021, 0x0169, 0x2404, 0xa084, 0x000f, 0xa086,
+ 0x0004, 0x11b0, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x00e6, 0x00f6,
+ 0x2079, 0x0020, 0x2071, 0x8dff, 0x6814, 0xa084, 0x0184, 0xa085,
+ 0x0012, 0x6816, 0x7803, 0x0008, 0x7003, 0x0000, 0x00fe, 0x00ee,
+ 0x200b, 0x0000, 0x004e, 0xa39d, 0x0000, 0x1120, 0x2009, 0x0049,
+ 0x080c, 0x6d3f, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0158, 0x6827,
+ 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803,
+ 0x0000, 0x0078, 0xd094, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04,
+ 0x6934, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803,
+ 0x0000, 0x6824, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee,
+ 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000,
+ 0x2069, 0x8daa, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126,
+ 0x2091, 0x8000, 0x2069, 0x8daa, 0x6a32, 0x012e, 0x00de, 0x0005,
+ 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0006, 0x0126, 0x2071, 0x8daa,
+ 0x7614, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0538, 0x601c,
+ 0xa206, 0x1500, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010,
+ 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010,
+ 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e,
+ 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0x7d3c, 0x080c, 0x6a05,
+ 0x00ce, 0x08d8, 0x2c78, 0x600c, 0x2060, 0x08b8, 0x012e, 0x000e,
+ 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0156, 0x0146, 0x20a1,
+ 0x020b, 0x080c, 0x6347, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2,
+ 0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0804, 0x69fd, 0x0156, 0x0146,
+ 0x20a1, 0x020b, 0x080c, 0x6347, 0x7810, 0x20a2, 0xa006, 0x20a2,
+ 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000, 0x0478, 0x0156, 0x0146,
+ 0x20a1, 0x020b, 0x080c, 0x6347, 0x7810, 0x20a2, 0xa006, 0x20a2,
+ 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000, 0x00f8, 0x0156, 0x0146,
+ 0x20a1, 0x020b, 0x080c, 0x6347, 0x7810, 0x20a2, 0xa006, 0x20a2,
+ 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078, 0x0156, 0x0146,
+ 0x20a1, 0x020b, 0x080c, 0x6347, 0x7810, 0x20a2, 0xa006, 0x20a2,
+ 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, 0x0089, 0x60c3, 0x0020,
+ 0x080c, 0x66e4, 0x014e, 0x015e, 0x0005, 0x00e6, 0x2071, 0x8daa,
+ 0x7020, 0xa005, 0x0110, 0x8001, 0x7022, 0x00ee, 0x0005, 0x20a9,
+ 0x0008, 0x20a2, 0x1f04, 0x6a11, 0x20a2, 0x20a2, 0x0005, 0x00f6,
+ 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126, 0x2091,
+ 0x8000, 0x2071, 0x8daa, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001,
+ 0x87ff, 0x0904, 0x6a9f, 0x8cff, 0x0904, 0x6a9f, 0x601c, 0xa086,
+ 0x0006, 0x1904, 0x6a9a, 0x88ff, 0x0138, 0x2800, 0xac06, 0x1904,
+ 0x6a9a, 0x2039, 0x0000, 0x0050, 0x6018, 0xa206, 0x1904, 0x6a9a,
+ 0x85ff, 0x0120, 0x6020, 0xa106, 0x1904, 0x6a9a, 0x7024, 0xac06,
+ 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, 0x567a,
+ 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0x6b23, 0x7027, 0x0000,
+ 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803,
+ 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110,
+ 0x6827, 0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a, 0x0450,
+ 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, 0xac36, 0x1140,
+ 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000,
+ 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678,
+ 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0110, 0x080c,
+ 0x8942, 0x080c, 0x7d3c, 0x080c, 0x6a05, 0x88ff, 0x1190, 0x00ce,
+ 0x0804, 0x6a28, 0x2c78, 0x600c, 0x2060, 0x0804, 0x6a28, 0xa006,
+ 0x012e, 0x000e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe,
+ 0x0005, 0x6017, 0x0000, 0x00ce, 0xa8c5, 0x0001, 0x0c88, 0x00f6,
+ 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091,
+ 0x8000, 0x2071, 0x8daa, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904,
+ 0x6b13, 0x601c, 0xa086, 0x0006, 0x1904, 0x6b0e, 0x88ff, 0x0128,
+ 0x2800, 0xac06, 0x1904, 0x6b0e, 0x0040, 0x6018, 0xa206, 0x15f0,
+ 0x85ff, 0x0118, 0x6020, 0xa106, 0x15c8, 0x703c, 0xac06, 0x1170,
+ 0x0036, 0x2019, 0x0001, 0x080c, 0x68e5, 0x7033, 0x0000, 0x703f,
+ 0x0000, 0x7043, 0x0000, 0x7047, 0x0000, 0x003e, 0x7038, 0xac36,
+ 0x1110, 0x660c, 0x763a, 0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36,
+ 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066,
+ 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000,
+ 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0110, 0x080c, 0x8942, 0x080c,
+ 0x7d3c, 0x88ff, 0x1190, 0x00ce, 0x0804, 0x6abe, 0x2c78, 0x600c,
+ 0x2060, 0x0804, 0x6abe, 0xa006, 0x012e, 0x000e, 0x002e, 0x006e,
+ 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6017, 0x0000, 0x00ce,
+ 0xa8c5, 0x0001, 0x0c88, 0x00e6, 0x2071, 0x8daa, 0x2001, 0x8b00,
+ 0x2004, 0xa086, 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, 0x7007,
+ 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026,
+ 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x8daa, 0x2c10, 0x7638,
+ 0x2660, 0x2678, 0x8cff, 0x0518, 0x2200, 0xac06, 0x11e0, 0x7038,
+ 0xac36, 0x1110, 0x660c, 0x763a, 0x7034, 0xac36, 0x1140, 0x2c00,
+ 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c,
+ 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000,
+ 0xa085, 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060, 0x08d8, 0x012e,
+ 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00f6,
+ 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0006, 0x0126, 0x2091, 0x8000,
+ 0x2071, 0x8daa, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0x6bf2,
+ 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x6bed, 0x7024,
+ 0xac06, 0x1500, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01d8, 0x080c,
+ 0x66f7, 0x68c3, 0x0000, 0x080c, 0x6b23, 0x7027, 0x0000, 0x0036,
+ 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100,
+ 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
+ 0x0001, 0x003e, 0x700c, 0xac36, 0x1110, 0x660c, 0x760e, 0x7008,
+ 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x700a, 0x0010,
+ 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e,
+ 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0x7d58, 0x1118, 0x080c,
+ 0x2589, 0x00c0, 0x080c, 0x7d69, 0x1118, 0x080c, 0x6fb6, 0x0090,
+ 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0168, 0x601c, 0xa086, 0x0003,
+ 0x1508, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x46a1,
+ 0x080c, 0x7d30, 0x6003, 0x0000, 0x080c, 0x7df6, 0x080c, 0x7d3c,
+ 0x080c, 0x6a05, 0x00ce, 0x0804, 0x6b7d, 0x2c78, 0x600c, 0x2060,
+ 0x0804, 0x6b7d, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00de, 0x00ee,
+ 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19d8, 0x080c, 0x8942,
+ 0x0c08, 0x0036, 0x0156, 0x0136, 0x0146, 0x3908, 0xa006, 0xa190,
+ 0x0020, 0x221c, 0xa39e, 0x23f9, 0x1118, 0x8210, 0x8000, 0x0cc8,
+ 0xa005, 0x0138, 0x20a9, 0x0020, 0x2198, 0xa110, 0x22a0, 0x22c8,
+ 0x53a3, 0x014e, 0x013e, 0x015e, 0x003e, 0x0005, 0x00d6, 0x20a1,
+ 0x020b, 0x080c, 0x612f, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3,
+ 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2099, 0x8da4, 0x20a9,
+ 0x0004, 0x53a6, 0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x080c, 0x66e4, 0x00de, 0x0005, 0x20a1, 0x020b,
+ 0x080c, 0x612f, 0x20a3, 0x0210, 0x20a3, 0x0018, 0x20a3, 0x0800,
+ 0x7810, 0xa084, 0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7810, 0xa084,
+ 0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018,
+ 0x080c, 0x66e4, 0x0005, 0x20a1, 0x020b, 0x0079, 0x7910, 0x21a2,
+ 0x20a3, 0x0000, 0x60c3, 0x0000, 0x20e1, 0x9080, 0x60a7, 0x9575,
+ 0x080c, 0x66ee, 0x080c, 0x5671, 0x0005, 0x0156, 0x0136, 0x0036,
+ 0x00d6, 0x00e6, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7824, 0x2068,
+ 0xadf0, 0x000f, 0x7210, 0xa296, 0x00c0, 0xa294, 0xfffd, 0x7212,
+ 0x7214, 0xa294, 0x0300, 0x7216, 0x7100, 0xa194, 0x00ff, 0x7308,
+ 0xa384, 0x00ff, 0xa08d, 0xc200, 0x7102, 0xa384, 0xff00, 0xa215,
+ 0x720a, 0x7004, 0x720c, 0x700e, 0x7206, 0x20a9, 0x000a, 0x2e98,
+ 0x53a6, 0x60a3, 0x0035, 0x6a38, 0xa294, 0x7000, 0xa286, 0x3000,
+ 0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x003e, 0x013e, 0x015e,
+ 0x0005, 0x2009, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036,
+ 0x6116, 0x0005, 0x2061, 0x9200, 0x2a70, 0x7064, 0x7046, 0x704b,
+ 0x9200, 0x0005, 0x00e6, 0x0126, 0x2071, 0x8b00, 0x2091, 0x8000,
+ 0x7544, 0xa582, 0x0001, 0x0608, 0x7048, 0x2060, 0x6000, 0xa086,
+ 0x0000, 0x0148, 0xace0, 0x000c, 0x7058, 0xac02, 0x1208, 0x0cb0,
+ 0x2061, 0x9200, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8,
+ 0x000c, 0x7058, 0xa502, 0x1230, 0x754a, 0xa085, 0x0001, 0x012e,
+ 0x00ee, 0x0005, 0x704b, 0x9200, 0x0cc0, 0xa006, 0x0cc0, 0x00e6,
+ 0x2071, 0x8b00, 0x7544, 0xa582, 0x0001, 0x0600, 0x7048, 0x2060,
0x6000, 0xa086, 0x0000, 0x0148, 0xace0, 0x000c, 0x7058, 0xac02,
- 0x1208, 0x0cb0, 0x2061, 0x9900, 0x0c98, 0x6003, 0x0008, 0x8529,
- 0x7546, 0xaca8, 0x000c, 0x7058, 0xa502, 0x1230, 0x754a, 0xa085,
- 0x0001, 0x012e, 0x00ee, 0x0005, 0x704b, 0x9900, 0x0cc0, 0xa006,
- 0x0cc0, 0x00e6, 0x2071, 0x9200, 0x7544, 0xa582, 0x0001, 0x0600,
- 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148, 0xace0, 0x000c,
- 0x7058, 0xac02, 0x1208, 0x0cb0, 0x2061, 0x9900, 0x0c98, 0x6003,
- 0x0008, 0x8529, 0x7546, 0xaca8, 0x000c, 0x7058, 0xa502, 0x1228,
- 0x754a, 0xa085, 0x0001, 0x00ee, 0x0005, 0x704b, 0x9900, 0x0cc8,
- 0xa006, 0x0cc8, 0xac82, 0x9900, 0x0a0c, 0x13fe, 0x2001, 0x9216,
- 0x2004, 0xac02, 0x1a0c, 0x13fe, 0xa006, 0x6006, 0x600a, 0x600e,
- 0x6012, 0x6016, 0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x6022,
- 0x2061, 0x9200, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0108,
- 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x6462, 0x012e, 0x0cc0,
- 0x601c, 0xa084, 0x000f, 0x0002, 0x7526, 0x752d, 0x7548, 0x7563,
- 0x8555, 0x8570, 0x858b, 0x7526, 0x752d, 0x5d3d, 0xa18e, 0x0047,
- 0x1118, 0xa016, 0x080c, 0x16c6, 0x0005, 0x0066, 0x6000, 0xa0b2,
- 0x0010, 0x1a0c, 0x13fe, 0x0013, 0x006e, 0x0005, 0x7546, 0x7654,
- 0x779c, 0x7546, 0x77eb, 0x7546, 0x7546, 0x7546, 0x75f6, 0x7b03,
- 0x7546, 0x7546, 0x7546, 0x7546, 0x7546, 0x7546, 0x080c, 0x13fe,
- 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x13fe, 0x0013, 0x006e,
- 0x0005, 0x7561, 0x7fa1, 0x7561, 0x7561, 0x7561, 0x7561, 0x7561,
- 0x7561, 0x7f89, 0x8078, 0x7561, 0x7fce, 0x8023, 0x7fce, 0x8023,
- 0x7561, 0x080c, 0x13fe, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c,
- 0x13fe, 0x0013, 0x006e, 0x0005, 0x757c, 0x7b3f, 0x7bf0, 0x7cb4,
- 0x7df4, 0x757c, 0x757c, 0x757c, 0x7b1b, 0x7f40, 0x7f43, 0x757c,
- 0x757c, 0x757c, 0x757c, 0x7f66, 0x080c, 0x13fe, 0x20a9, 0x000e,
- 0x2e98, 0x6010, 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420,
- 0x9398, 0x94a0, 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002,
- 0xa5a8, 0x0002, 0xa398, 0x0002, 0xa4a0, 0x0002, 0x1f04, 0x758c,
- 0x00e6, 0x080c, 0x82ee, 0x0130, 0x6010, 0x2070, 0x7007, 0x0000,
- 0x7037, 0x0103, 0x00ee, 0x080c, 0x74f2, 0x0005, 0x00d6, 0x0036,
- 0x7330, 0xa386, 0x0200, 0x1130, 0x6018, 0x2068, 0x6813, 0x00ff,
- 0x6817, 0xfffd, 0x6010, 0xa005, 0x0130, 0x2068, 0x6807, 0x0000,
- 0x6837, 0x0103, 0x6b32, 0x080c, 0x74f2, 0x003e, 0x00de, 0x0005,
- 0x0016, 0x20a9, 0x002a, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080,
- 0x0002, 0x20a0, 0x53a3, 0x20a9, 0x002a, 0x6010, 0xa080, 0x0001,
- 0x2004, 0xa080, 0x0002, 0x20a0, 0x53a3, 0x00e6, 0x6010, 0x2004,
- 0x2070, 0x7037, 0x0103, 0x00ee, 0x080c, 0x74f2, 0x001e, 0x0005,
- 0x00d6, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0, 0x53a3, 0xa1b6,
- 0x0015, 0x1148, 0x6018, 0x2068, 0x7038, 0x680a, 0x703c, 0x680e,
- 0x6800, 0xc08d, 0x6802, 0x00de, 0x0804, 0x7598, 0x2100, 0xa1b2,
- 0x003e, 0x1a0c, 0x13fe, 0x0002, 0x763c, 0x7648, 0x763c, 0x763c,
- 0x763c, 0x763c, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a,
- 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a,
- 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a,
- 0x763a, 0x763a, 0x763a, 0x763c, 0x763a, 0x763c, 0x763c, 0x763a,
- 0x763a, 0x763a, 0x763a, 0x763a, 0x763c, 0x763a, 0x763a, 0x763a,
- 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763c, 0x763a,
- 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a, 0x763a,
- 0x763a, 0x763c, 0x080c, 0x13fe, 0x6003, 0x0001, 0x6106, 0x080c,
- 0x603e, 0x0126, 0x2091, 0x8000, 0x080c, 0x6462, 0x012e, 0x0005,
- 0x6003, 0x0001, 0x6106, 0x080c, 0x603e, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x6462, 0x012e, 0x0005, 0x6004, 0xa0b2, 0x003e, 0x1a0c,
- 0x13fe, 0xa1b6, 0x0013, 0x0904, 0x76f0, 0xa1b6, 0x0027, 0x1904,
- 0x76b6, 0x080c, 0x6389, 0x6004, 0x080c, 0x84b7, 0x0178, 0x080c,
- 0x84c8, 0x0904, 0x76b0, 0xa08e, 0x0021, 0x0904, 0x76b3, 0xa08e,
- 0x0022, 0x05f0, 0xa08e, 0x003d, 0x05f0, 0x04a8, 0x080c, 0x2692,
- 0x2001, 0x0007, 0x080c, 0x43e3, 0x6018, 0xa080, 0x0028, 0x200c,
- 0x080c, 0x7776, 0xa186, 0x007e, 0x1148, 0x2001, 0x9232, 0x2014,
- 0xc285, 0x080c, 0x4dc5, 0x1108, 0xc2ad, 0x2202, 0x0016, 0x0026,
- 0x0036, 0x2110, 0x2019, 0x0028, 0x080c, 0x6127, 0x0086, 0x2041,
- 0x0000, 0x080c, 0x606d, 0x00c6, 0x6018, 0xa065, 0x0110, 0x080c,
- 0x460d, 0x00ce, 0x2c08, 0x080c, 0x8ee4, 0x008e, 0x003e, 0x002e,
- 0x001e, 0x080c, 0x441f, 0x080c, 0x74f2, 0x080c, 0x6462, 0x0005,
- 0x080c, 0x7776, 0x0cc0, 0x080c, 0x7790, 0x0ca8, 0xa186, 0x0014,
- 0x1db0, 0x080c, 0x6389, 0x080c, 0x266c, 0x080c, 0x84b7, 0x1188,
- 0x080c, 0x2692, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x7776,
- 0xa186, 0x007e, 0x1128, 0x2001, 0x9232, 0x200c, 0xc185, 0x2102,
- 0x08d0, 0x080c, 0x84c8, 0x1118, 0x080c, 0x7776, 0x08a0, 0x6004,
- 0xa08e, 0x0032, 0x1158, 0x00e6, 0x00f6, 0x2071, 0x9296, 0x2079,
- 0x0000, 0x080c, 0x2924, 0x00fe, 0x00ee, 0x0828, 0x6004, 0xa08e,
- 0x0021, 0x0d50, 0xa08e, 0x0022, 0x090c, 0x7790, 0x0804, 0x76ab,
- 0x2008, 0x0002, 0x7732, 0x7733, 0x7736, 0x7739, 0x773c, 0x773f,
- 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730,
- 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730,
- 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730,
- 0x7742, 0x7747, 0x7730, 0x7750, 0x7747, 0x7730, 0x7730, 0x7730,
- 0x7730, 0x7730, 0x7747, 0x7747, 0x7730, 0x7730, 0x7730, 0x7730,
- 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730,
- 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7730, 0x7747,
- 0x080c, 0x13fe, 0x00a0, 0x2001, 0x000b, 0x0418, 0x2001, 0x0003,
- 0x0400, 0x2001, 0x0005, 0x00e8, 0x2001, 0x0001, 0x00d0, 0x2001,
- 0x0009, 0x00b8, 0x080c, 0x13fe, 0x0098, 0x080c, 0x43e3, 0x080c,
- 0x6389, 0x6003, 0x0002, 0x6017, 0x0028, 0x080c, 0x6462, 0x0040,
- 0x080c, 0x6389, 0x6003, 0x0004, 0x6017, 0x0028, 0x080c, 0x6462,
- 0x0005, 0x080c, 0x43e3, 0x080c, 0x6389, 0x6003, 0x0002, 0x0036,
- 0x2019, 0x925c, 0x2304, 0xa084, 0xff00, 0x1118, 0x2019, 0x0028,
- 0x0040, 0x8007, 0xa09a, 0x0004, 0x0ec8, 0x8003, 0x801b, 0x831b,
- 0xa318, 0x6316, 0x003e, 0x080c, 0x6462, 0x0c10, 0x00e6, 0x080c,
- 0x82ee, 0x0188, 0x6010, 0x2070, 0x7007, 0x0000, 0x0016, 0x6004,
- 0xa08e, 0x0021, 0x0150, 0xa08e, 0x003d, 0x0138, 0x001e, 0x7037,
- 0x0103, 0x7033, 0x0100, 0x00ee, 0x0005, 0x001e, 0x0009, 0x0cd8,
- 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103,
- 0x7023, 0x8001, 0x00ee, 0x0005, 0x00d6, 0x6618, 0x2668, 0x6804,
- 0xa084, 0x00ff, 0x00de, 0xa0b2, 0x000c, 0x1a0c, 0x13fe, 0x6604,
- 0xa6b6, 0x0028, 0x1118, 0x080c, 0x84f2, 0x0468, 0x6604, 0xa6b6,
- 0x0029, 0x1118, 0x080c, 0x8509, 0x0430, 0x6604, 0xa6b6, 0x001f,
- 0x1118, 0x080c, 0x757e, 0x00f8, 0x6604, 0xa6b6, 0x0000, 0x1118,
- 0x080c, 0x75e0, 0x00c0, 0x6604, 0xa6b6, 0x0022, 0x1118, 0x080c,
- 0x75a6, 0x0088, 0x6604, 0xa6b6, 0x003d, 0x1118, 0x080c, 0x75c0,
- 0x0050, 0xa1b6, 0x0015, 0x1110, 0x0053, 0x0028, 0xa1b6, 0x0016,
- 0x1118, 0x0804, 0x7983, 0x0005, 0x080c, 0x7526, 0x0ce0, 0x7805,
- 0x7808, 0x7805, 0x7844, 0x7805, 0x7923, 0x7805, 0x7805, 0x7805,
- 0x795b, 0x7805, 0x7971, 0xa1b6, 0x0048, 0x0140, 0x20e1, 0x0005,
- 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x16c6, 0x0005, 0x00e6, 0xacf0,
- 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x00ee, 0x080c,
- 0x74f2, 0x0005, 0x080c, 0x74f2, 0x0005, 0xe000, 0xe000, 0x0005,
- 0x00e6, 0x2071, 0x9200, 0x7080, 0xa086, 0x0074, 0x11f0, 0x080c,
- 0x8ebb, 0x1170, 0x00d6, 0x6018, 0x2068, 0x00e9, 0x00de, 0x2001,
- 0x0006, 0x080c, 0x43e3, 0x080c, 0x2692, 0x080c, 0x74f2, 0x0088,
- 0x2001, 0x000a, 0x080c, 0x43e3, 0x080c, 0x2692, 0x6003, 0x0001,
- 0x6007, 0x0001, 0x080c, 0x603e, 0x0020, 0x2001, 0x0001, 0x080c,
- 0x7910, 0x00ee, 0x0005, 0x6800, 0xd084, 0x0168, 0x2001, 0x0000,
- 0x080c, 0x43d1, 0x2069, 0x9251, 0x6804, 0xd0a4, 0x0120, 0x2001,
- 0x0006, 0x080c, 0x43f1, 0x0005, 0x00d6, 0x2011, 0x9220, 0x2204,
- 0xa086, 0x0074, 0x1904, 0x790b, 0x080c, 0x7a64, 0x6018, 0x2068,
- 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x0198, 0xa286, 0x0080,
- 0x1904, 0x789c, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005,
- 0x0588, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833, 0x0200,
- 0x0448, 0x00d6, 0x00e6, 0x00f6, 0x6813, 0x00ff, 0x6817, 0xfffe,
- 0x2071, 0x9232, 0x2e04, 0xa085, 0x0003, 0x2072, 0x2071, 0x9780,
- 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0x921b, 0x206a,
- 0x78e6, 0x8e70, 0x2e04, 0x2069, 0x921c, 0x206a, 0x78ea, 0x7832,
- 0x7836, 0xa084, 0x00ff, 0x2008, 0x080c, 0x2435, 0x00fe, 0x00ee,
- 0x00de, 0x00f8, 0x2001, 0x0006, 0x080c, 0x43e3, 0x080c, 0x2692,
- 0x080c, 0x74f2, 0x0804, 0x790e, 0x6010, 0xa005, 0x0130, 0x2068,
- 0x6838, 0xd0f4, 0x0110, 0x0804, 0x7862, 0x2001, 0x0004, 0x080c,
- 0x43e3, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x603e, 0x0804,
- 0x790e, 0x685c, 0xd0e4, 0x01c8, 0x080c, 0x8531, 0x080c, 0x4dc5,
- 0x0110, 0xd0dc, 0x19b8, 0x2011, 0x9232, 0x2204, 0xc0ad, 0x2012,
- 0x2001, 0x94c8, 0x2004, 0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000,
- 0x080c, 0x2460, 0x78e2, 0x00fe, 0x0828, 0x080c, 0x854a, 0x2011,
- 0x9232, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0x8fa4, 0x000e,
- 0x1904, 0x7892, 0xc0b5, 0x2012, 0x2001, 0x0000, 0x080c, 0x43d1,
- 0x00c6, 0x2009, 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932,
- 0x7936, 0x00fe, 0x080c, 0x2435, 0x2001, 0x9214, 0x2004, 0x2009,
- 0x0000, 0x080c, 0x240b, 0x2001, 0x9213, 0x2102, 0x8108, 0x080c,
- 0x4400, 0x2c00, 0x00ce, 0x1904, 0x7892, 0x601a, 0x2001, 0x0002,
- 0x080c, 0x43e3, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002,
- 0x080c, 0x603e, 0x0018, 0x2001, 0x0001, 0x0011, 0x00de, 0x0005,
- 0x0006, 0x2001, 0x9200, 0x2004, 0xa086, 0x0003, 0x000e, 0x0130,
- 0xa005, 0x0120, 0x2001, 0x0007, 0x080c, 0x43e3, 0x080c, 0x2692,
- 0x080c, 0x74f2, 0x0005, 0x00e6, 0x2071, 0x9200, 0x7080, 0xa086,
- 0x0014, 0x1548, 0x7000, 0xa086, 0x0003, 0x1128, 0x6010, 0xa005,
- 0x1110, 0x080c, 0x370a, 0x00d6, 0x6018, 0x2068, 0x080c, 0x44c7,
- 0x080c, 0x7833, 0x00de, 0x080c, 0x7a6e, 0x11a8, 0x2001, 0x0006,
- 0x080c, 0x43e3, 0x00e6, 0x6010, 0xa005, 0x0138, 0x2070, 0x7007,
- 0x0000, 0x7037, 0x0103, 0x7033, 0x0200, 0x00ee, 0x080c, 0x2692,
- 0x080c, 0x74f2, 0x0030, 0x080c, 0x7776, 0x2001, 0x0000, 0x080c,
- 0x7910, 0x00ee, 0x0005, 0x2011, 0x9220, 0x2204, 0xa086, 0x0014,
- 0x1158, 0x2001, 0x0002, 0x080c, 0x43e3, 0x6003, 0x0001, 0x6007,
- 0x0001, 0x080c, 0x603e, 0x0020, 0x2001, 0x0001, 0x080c, 0x7910,
- 0x0005, 0x2011, 0x9220, 0x2204, 0xa086, 0x0004, 0x1138, 0x2001,
- 0x0007, 0x080c, 0x43e3, 0x080c, 0x74f2, 0x0020, 0x2001, 0x0001,
- 0x080c, 0x7910, 0x0005, 0x000b, 0x0005, 0x7805, 0x7991, 0x7805,
- 0x79b5, 0x7805, 0x7a1a, 0x7805, 0x7802, 0x7805, 0x7a2f, 0x7805,
- 0x7a41, 0x00c6, 0x080c, 0x7a53, 0x1178, 0x2001, 0x0000, 0x080c,
- 0x43d1, 0x2001, 0x0002, 0x080c, 0x43e3, 0x6003, 0x0001, 0x6007,
- 0x0002, 0x080c, 0x603e, 0x0078, 0x2009, 0x978f, 0x2104, 0xa084,
- 0xff00, 0xa086, 0x1900, 0x1118, 0x080c, 0x74f2, 0x0020, 0x2001,
- 0x0001, 0x080c, 0x7910, 0x00ce, 0x0005, 0x080c, 0x7a61, 0x00d6,
- 0x2069, 0x94d7, 0x2d04, 0xa005, 0x0168, 0x6018, 0x2068, 0x68a0,
- 0xa086, 0x007e, 0x1138, 0x2069, 0x921c, 0x2d04, 0x8000, 0x206a,
- 0x00de, 0x0010, 0x00de, 0x0078, 0x2001, 0x0000, 0x080c, 0x43d1,
- 0x2001, 0x0002, 0x080c, 0x43e3, 0x6003, 0x0001, 0x6007, 0x0002,
- 0x080c, 0x603e, 0x0400, 0x080c, 0x7776, 0x2009, 0x978e, 0x2134,
- 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x01b8, 0x2009, 0x978f, 0x2104,
- 0xa084, 0xff00, 0xa086, 0x1900, 0x1150, 0xa686, 0x0009, 0x0160,
- 0x2001, 0x0004, 0x080c, 0x43e3, 0x080c, 0x74f2, 0x0020, 0x2001,
- 0x0001, 0x080c, 0x7910, 0x0005, 0x00d6, 0x6010, 0x2068, 0x080c,
- 0x82ee, 0x0128, 0x6838, 0xd0fc, 0x0110, 0x00de, 0x0c80, 0x6018,
- 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0140, 0x8001, 0x6842,
- 0x6017, 0x000a, 0x6007, 0x0016, 0x00de, 0x0c28, 0x080c, 0x266c,
- 0x00de, 0x08e8, 0x080c, 0x7a61, 0x1158, 0x2001, 0x0004, 0x080c,
- 0x43e3, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x603e, 0x0030,
- 0x080c, 0x7776, 0x2001, 0x0000, 0x080c, 0x7910, 0x0005, 0x0489,
- 0x1158, 0x2001, 0x0008, 0x080c, 0x43e3, 0x6003, 0x0001, 0x6007,
- 0x0005, 0x080c, 0x603e, 0x0020, 0x2001, 0x0001, 0x080c, 0x7910,
- 0x0005, 0x00f9, 0x1158, 0x2001, 0x000a, 0x080c, 0x43e3, 0x6003,
- 0x0001, 0x6007, 0x0001, 0x080c, 0x603e, 0x0020, 0x2001, 0x0001,
- 0x080c, 0x7910, 0x0005, 0x2009, 0x978e, 0x2104, 0xa086, 0x0003,
- 0x1138, 0x2009, 0x978f, 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00,
+ 0x1208, 0x0cb0, 0x2061, 0x9200, 0x0c98, 0x6003, 0x0008, 0x8529,
+ 0x7546, 0xaca8, 0x000c, 0x7058, 0xa502, 0x1228, 0x754a, 0xa085,
+ 0x0001, 0x00ee, 0x0005, 0x704b, 0x9200, 0x0cc8, 0xa006, 0x0cc8,
+ 0xac82, 0x9200, 0x0a0c, 0x1410, 0x2001, 0x8b16, 0x2004, 0xac02,
+ 0x1a0c, 0x1410, 0xa006, 0x6006, 0x600a, 0x600e, 0x6012, 0x6016,
+ 0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x6022, 0x6026, 0x2061,
+ 0x8b00, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0108, 0x0005,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x5d10, 0x012e, 0x0cc0, 0x601c,
+ 0xa084, 0x000f, 0x0002, 0x6d4d, 0x6d5c, 0x6d77, 0x6d92, 0x7dfe,
+ 0x7e19, 0x7e34, 0x6d4d, 0x6d5c, 0x6d4d, 0xa186, 0x0013, 0x1128,
+ 0x080c, 0x5c37, 0x080c, 0x5d10, 0x0005, 0xa18e, 0x0047, 0x1118,
+ 0xa016, 0x080c, 0x16d1, 0x0005, 0x0066, 0x6000, 0xa0b2, 0x0010,
+ 0x1a0c, 0x1410, 0x0013, 0x006e, 0x0005, 0x6d75, 0x6e85, 0x6fdf,
+ 0x6d75, 0x702e, 0x6d75, 0x6d75, 0x6d75, 0x6e25, 0x733b, 0x6d75,
+ 0x6d75, 0x6d75, 0x6d75, 0x6d75, 0x6d75, 0x080c, 0x1410, 0x0066,
+ 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x1410, 0x0013, 0x006e, 0x0005,
+ 0x6d90, 0x77f2, 0x6d90, 0x6d90, 0x6d90, 0x6d90, 0x6d90, 0x6d90,
+ 0x77da, 0x78d0, 0x6d90, 0x781f, 0x7877, 0x781f, 0x7877, 0x6d90,
+ 0x080c, 0x1410, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x1410,
+ 0x0013, 0x006e, 0x0005, 0x6dab, 0x7377, 0x742b, 0x74ef, 0x762f,
+ 0x6dab, 0x6dab, 0x6dab, 0x7353, 0x778f, 0x7792, 0x6dab, 0x6dab,
+ 0x6dab, 0x6dab, 0x77b7, 0x080c, 0x1410, 0x20a9, 0x000e, 0x2e98,
+ 0x6010, 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, 0x9398,
+ 0x94a0, 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002, 0xa5a8,
+ 0x0002, 0xa398, 0x0002, 0xa4a0, 0x0002, 0x1f04, 0x6dbb, 0x00e6,
+ 0x080c, 0x7b8f, 0x0130, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037,
+ 0x0103, 0x00ee, 0x080c, 0x6d18, 0x0005, 0x00d6, 0x0036, 0x7330,
+ 0xa386, 0x0200, 0x1130, 0x6018, 0x2068, 0x6813, 0x00ff, 0x6817,
+ 0xfffd, 0x6010, 0xa005, 0x0130, 0x2068, 0x6807, 0x0000, 0x6837,
+ 0x0103, 0x6b32, 0x080c, 0x6d18, 0x003e, 0x00de, 0x0005, 0x0016,
+ 0x20a9, 0x002a, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080, 0x0002,
+ 0x20a0, 0x53a3, 0x20a9, 0x002a, 0x6010, 0xa080, 0x0001, 0x2004,
+ 0xa080, 0x0002, 0x20a0, 0x53a3, 0x00e6, 0x6010, 0x2004, 0x2070,
+ 0x7037, 0x0103, 0x00ee, 0x080c, 0x6d18, 0x001e, 0x0005, 0x00d6,
+ 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015,
+ 0x1148, 0x6018, 0x2068, 0x7038, 0x680a, 0x703c, 0x680e, 0x6800,
+ 0xc08d, 0x6802, 0x00de, 0x0804, 0x6dc7, 0x2100, 0xa1b2, 0x0040,
+ 0x1a0c, 0x1410, 0x0002, 0x6e6d, 0x6e79, 0x6e6d, 0x6e6d, 0x6e6d,
+ 0x6e6d, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b,
+ 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b,
+ 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b,
+ 0x6e6b, 0x6e6b, 0x6e6d, 0x6e6b, 0x6e6d, 0x6e6d, 0x6e6b, 0x6e6b,
+ 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6d, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b,
+ 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6d, 0x6e6b, 0x6e6b,
+ 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b, 0x6e6b,
+ 0x6e6d, 0x6e6b, 0x6e6b, 0x080c, 0x1410, 0x6003, 0x0001, 0x6106,
+ 0x080c, 0x58e2, 0x0126, 0x2091, 0x8000, 0x080c, 0x5d10, 0x012e,
+ 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x58e2, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x5d10, 0x012e, 0x0005, 0x6004, 0xa0b2, 0x0040,
+ 0x1a0c, 0x1410, 0xa1b6, 0x0013, 0x0904, 0x6f25, 0xa1b6, 0x0027,
+ 0x1904, 0x6eeb, 0x080c, 0x5c37, 0x6004, 0x080c, 0x7d58, 0x0188,
+ 0x080c, 0x7d69, 0x0904, 0x6ee5, 0xa08e, 0x0021, 0x0904, 0x6ee8,
+ 0xa08e, 0x0022, 0x0904, 0x6ee5, 0xa08e, 0x003d, 0x0904, 0x6ee8,
+ 0x04a8, 0x080c, 0x2589, 0x2001, 0x0007, 0x080c, 0x42b9, 0x6018,
+ 0xa080, 0x0028, 0x200c, 0x080c, 0x6fb6, 0xa186, 0x007e, 0x1148,
+ 0x2001, 0x8b32, 0x2014, 0xc285, 0x080c, 0x4c42, 0x1108, 0xc2ad,
+ 0x2202, 0x0016, 0x0026, 0x0036, 0x2110, 0x2019, 0x0028, 0x080c,
+ 0x59d5, 0x0086, 0x2041, 0x0000, 0x080c, 0x5911, 0x00c6, 0x6018,
+ 0xa065, 0x0110, 0x080c, 0x44e6, 0x00ce, 0x2c08, 0x080c, 0x878f,
+ 0x008e, 0x003e, 0x002e, 0x001e, 0x080c, 0x42f5, 0x080c, 0x7df6,
+ 0x080c, 0x6d18, 0x080c, 0x5d10, 0x0005, 0x080c, 0x6fb6, 0x0cb0,
+ 0x080c, 0x6fd3, 0x0c98, 0xa186, 0x0014, 0x1db0, 0x080c, 0x5c37,
+ 0x080c, 0x2563, 0x080c, 0x7d58, 0x1188, 0x080c, 0x2589, 0x6018,
+ 0xa080, 0x0028, 0x200c, 0x080c, 0x6fb6, 0xa186, 0x007e, 0x1128,
+ 0x2001, 0x8b32, 0x200c, 0xc185, 0x2102, 0x08c0, 0x080c, 0x7d69,
+ 0x1118, 0x080c, 0x6fb6, 0x0890, 0x6004, 0xa08e, 0x0032, 0x1158,
+ 0x00e6, 0x00f6, 0x2071, 0x8b81, 0x2079, 0x0000, 0x080c, 0x2848,
+ 0x00fe, 0x00ee, 0x0818, 0x6004, 0xa08e, 0x0021, 0x0d50, 0xa08e,
+ 0x0022, 0x090c, 0x6fd3, 0x0804, 0x6ede, 0x2008, 0x0002, 0x6f69,
+ 0x6f6a, 0x6f6d, 0x6f70, 0x6f73, 0x6f76, 0x6f67, 0x6f67, 0x6f67,
+ 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67,
+ 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67,
+ 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f79, 0x6f7e, 0x6f67,
+ 0x6f87, 0x6f7e, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f7e,
+ 0x6f7e, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67,
+ 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f67,
+ 0x6f67, 0x6f67, 0x6f67, 0x6f67, 0x6f7e, 0x6fad, 0x6f67, 0x080c,
+ 0x1410, 0x00a0, 0x2001, 0x000b, 0x0418, 0x2001, 0x0003, 0x0400,
+ 0x2001, 0x0005, 0x00e8, 0x2001, 0x0001, 0x00d0, 0x2001, 0x0009,
+ 0x00b8, 0x080c, 0x1410, 0x0098, 0x080c, 0x42b9, 0x080c, 0x5c37,
+ 0x6003, 0x0002, 0x6017, 0x0028, 0x080c, 0x5d10, 0x0040, 0x080c,
+ 0x5c37, 0x6003, 0x0004, 0x6017, 0x0028, 0x080c, 0x5d10, 0x0005,
+ 0x080c, 0x42b9, 0x080c, 0x5c37, 0x6003, 0x0002, 0x0036, 0x2019,
+ 0x8b5c, 0x2304, 0xa084, 0xff00, 0x1118, 0x2019, 0x0028, 0x0040,
+ 0x8007, 0xa09a, 0x0004, 0x0ec8, 0x8003, 0x801b, 0x831b, 0xa318,
+ 0x6316, 0x003e, 0x080c, 0x5d10, 0x0c10, 0x080c, 0x5c37, 0x080c,
+ 0x7df6, 0x080c, 0x6d18, 0x080c, 0x5d10, 0x08c8, 0x00e6, 0x080c,
+ 0x7b8f, 0x01a0, 0x6010, 0x2070, 0x7038, 0xd0fc, 0x0178, 0x7007,
+ 0x0000, 0x0016, 0x6004, 0xa08e, 0x0021, 0x0150, 0xa08e, 0x003d,
+ 0x0138, 0x001e, 0x7037, 0x0103, 0x7033, 0x0100, 0x00ee, 0x0005,
+ 0x001e, 0x0009, 0x0cd8, 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000,
+ 0x2070, 0x7037, 0x0103, 0x7023, 0x8001, 0x00ee, 0x0005, 0x00d6,
+ 0x6618, 0x2668, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa0b2, 0x000c,
+ 0x1a0c, 0x1410, 0x6604, 0xa6b6, 0x0028, 0x1118, 0x080c, 0x7d93,
+ 0x0468, 0x6604, 0xa6b6, 0x0029, 0x1118, 0x080c, 0x7daa, 0x0430,
+ 0x6604, 0xa6b6, 0x001f, 0x1118, 0x080c, 0x6dad, 0x00f8, 0x6604,
+ 0xa6b6, 0x0000, 0x1118, 0x080c, 0x6e0f, 0x00c0, 0x6604, 0xa6b6,
+ 0x0022, 0x1118, 0x080c, 0x6dd5, 0x0088, 0x6604, 0xa6b6, 0x003d,
+ 0x1118, 0x080c, 0x6def, 0x0050, 0xa1b6, 0x0015, 0x1110, 0x0053,
+ 0x0028, 0xa1b6, 0x0016, 0x1118, 0x0804, 0x71c6, 0x0005, 0x080c,
+ 0x6d55, 0x0ce0, 0x7045, 0x7048, 0x7045, 0x7082, 0x7045, 0x716c,
+ 0x7045, 0x7045, 0x7045, 0x71a2, 0x7045, 0x71b6, 0xa1b6, 0x0048,
+ 0x0140, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x16d1,
+ 0x0005, 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037,
+ 0x0103, 0x00ee, 0x080c, 0x6d18, 0x0005, 0xe000, 0xe000, 0x0005,
+ 0x00e6, 0x2071, 0x8b00, 0x7080, 0xa086, 0x0074, 0x11f0, 0x080c,
+ 0x8766, 0x1170, 0x00d6, 0x6018, 0x2068, 0x00d9, 0x00de, 0x2001,
+ 0x0006, 0x080c, 0x42b9, 0x080c, 0x2589, 0x080c, 0x6d18, 0x0078,
+ 0x2001, 0x000a, 0x080c, 0x42b9, 0x080c, 0x2589, 0x6003, 0x0001,
+ 0x6007, 0x0001, 0x080c, 0x58e2, 0x0010, 0x080c, 0x715d, 0x00ee,
+ 0x0005, 0x6800, 0xd084, 0x0168, 0x2001, 0x0000, 0x080c, 0x42a7,
+ 0x2069, 0x8b51, 0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c,
+ 0x42c7, 0x0005, 0x00d6, 0x2011, 0x8b20, 0x2204, 0xa086, 0x0074,
+ 0x1904, 0x715a, 0x080c, 0x72a4, 0x6018, 0x2068, 0xa080, 0x0028,
+ 0x2014, 0xa286, 0x007e, 0x0198, 0xa286, 0x0080, 0x1904, 0x70da,
+ 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005, 0x0588, 0x2068,
+ 0x6807, 0x0000, 0x6837, 0x0103, 0x6833, 0x0200, 0x0448, 0x00d6,
+ 0x00e6, 0x00f6, 0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071, 0x8b32,
+ 0x2e04, 0xa085, 0x0003, 0x2072, 0x2071, 0x9080, 0x2079, 0x0100,
+ 0x2e04, 0xa084, 0x00ff, 0x2069, 0x8b1b, 0x206a, 0x78e6, 0x8e70,
+ 0x2e04, 0x2069, 0x8b1c, 0x206a, 0x78ea, 0x7832, 0x7836, 0xa084,
+ 0x00ff, 0x2008, 0x080c, 0x2313, 0x00fe, 0x00ee, 0x00de, 0x0470,
+ 0x2001, 0x0006, 0x080c, 0x42b9, 0x080c, 0x2589, 0x080c, 0x6d18,
+ 0x0804, 0x715b, 0x00e6, 0x2071, 0x8b32, 0x2e04, 0xd09c, 0x0188,
+ 0x2071, 0x9080, 0x7108, 0x720c, 0xa18c, 0x00ff, 0x1118, 0xa284,
+ 0xff00, 0x0138, 0x6018, 0x2070, 0x70a0, 0xd0bc, 0x1110, 0x7112,
+ 0x7216, 0x00ee, 0x2001, 0x0004, 0x080c, 0x42b9, 0x6003, 0x0001,
+ 0x6007, 0x0003, 0x080c, 0x58e2, 0x0804, 0x715b, 0x685c, 0xd0e4,
+ 0x01d0, 0x080c, 0x7dd2, 0x080c, 0x4c42, 0x0110, 0xd0dc, 0x1940,
+ 0x2011, 0x8b32, 0x2204, 0xc0ad, 0x2012, 0x2001, 0x8d8d, 0x2004,
+ 0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c, 0x233e, 0x78e2,
+ 0x00fe, 0x0804, 0x70d0, 0x080c, 0x7deb, 0x2011, 0x8b32, 0x2204,
+ 0xc0a5, 0x2012, 0x0006, 0x080c, 0x884f, 0x000e, 0x1904, 0x70d0,
+ 0xc0b5, 0x2012, 0x2001, 0x0000, 0x080c, 0x42a7, 0x00c6, 0x2009,
+ 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932, 0x7936, 0x00fe,
+ 0x080c, 0x2313, 0x00f6, 0x2079, 0x8b00, 0x7972, 0x2100, 0x2009,
+ 0x0000, 0x080c, 0x22e9, 0x794e, 0x00fe, 0x8108, 0x080c, 0x42d6,
+ 0x2c00, 0x00ce, 0x1904, 0x70d0, 0x601a, 0x2001, 0x0002, 0x080c,
+ 0x42b9, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
+ 0x58e2, 0x0008, 0x0011, 0x00de, 0x0005, 0x2001, 0x8b00, 0x2004,
+ 0xa086, 0x0003, 0x0120, 0x2001, 0x0007, 0x080c, 0x42b9, 0x080c,
+ 0x2589, 0x080c, 0x6d18, 0x0005, 0x00e6, 0x2071, 0x8b00, 0x7080,
+ 0xa086, 0x0014, 0x1548, 0x7000, 0xa086, 0x0003, 0x1128, 0x6010,
+ 0xa005, 0x1110, 0x080c, 0x3689, 0x00d6, 0x6018, 0x2068, 0x080c,
+ 0x43a0, 0x080c, 0x7071, 0x00de, 0x080c, 0x72ae, 0x11a8, 0x2001,
+ 0x0006, 0x080c, 0x42b9, 0x00e6, 0x6010, 0xa005, 0x0138, 0x2070,
+ 0x7007, 0x0000, 0x7037, 0x0103, 0x7033, 0x0200, 0x00ee, 0x080c,
+ 0x2589, 0x080c, 0x6d18, 0x0020, 0x080c, 0x6fb6, 0x080c, 0x715d,
+ 0x00ee, 0x0005, 0x2011, 0x8b20, 0x2204, 0xa086, 0x0014, 0x1158,
+ 0x2001, 0x0002, 0x080c, 0x42b9, 0x6003, 0x0001, 0x6007, 0x0001,
+ 0x080c, 0x58e2, 0x0010, 0x080c, 0x715d, 0x0005, 0x2011, 0x8b20,
+ 0x2204, 0xa086, 0x0004, 0x1138, 0x2001, 0x0007, 0x080c, 0x42b9,
+ 0x080c, 0x6d18, 0x0010, 0x080c, 0x715d, 0x0005, 0x000b, 0x0005,
+ 0x7045, 0x71d4, 0x7045, 0x71f6, 0x7045, 0x7260, 0x7045, 0x7045,
+ 0x7045, 0x7273, 0x7045, 0x7283, 0x00c6, 0x080c, 0x7293, 0x1178,
+ 0x2001, 0x0000, 0x080c, 0x42a7, 0x2001, 0x0002, 0x080c, 0x42b9,
+ 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x58e2, 0x0068, 0x2009,
+ 0x908f, 0x2104, 0xa084, 0xff00, 0xa086, 0x1900, 0x1118, 0x080c,
+ 0x6d18, 0x0010, 0x080c, 0x715d, 0x00ce, 0x0005, 0x080c, 0x72a1,
+ 0x00d6, 0x2069, 0x8d9c, 0x2d04, 0xa005, 0x0168, 0x6018, 0x2068,
+ 0x68a0, 0xa086, 0x007e, 0x1138, 0x2069, 0x8b1c, 0x2d04, 0x8000,
+ 0x206a, 0x00de, 0x0010, 0x00de, 0x0078, 0x2001, 0x0000, 0x080c,
+ 0x42a7, 0x2001, 0x0002, 0x080c, 0x42b9, 0x6003, 0x0001, 0x6007,
+ 0x0002, 0x080c, 0x58e2, 0x0428, 0x080c, 0x6fb6, 0x2009, 0x908e,
+ 0x2134, 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x01e0, 0xa686, 0x000b,
+ 0x01b0, 0x2009, 0x908f, 0x2104, 0xa084, 0xff00, 0x1118, 0xa686,
+ 0x0009, 0x0180, 0xa086, 0x1900, 0x1150, 0xa686, 0x0009, 0x0150,
+ 0x2001, 0x0004, 0x080c, 0x42b9, 0x080c, 0x6d18, 0x0010, 0x080c,
+ 0x715d, 0x0005, 0x00d6, 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0128,
+ 0x6838, 0xd0fc, 0x0110, 0x00de, 0x0c90, 0x6018, 0x2068, 0x6840,
+ 0xa084, 0x00ff, 0xa005, 0x0140, 0x8001, 0x6842, 0x6017, 0x000a,
+ 0x6007, 0x0016, 0x00de, 0x0c28, 0x080c, 0x2563, 0x00de, 0x08f8,
+ 0x080c, 0x72a1, 0x1158, 0x2001, 0x0004, 0x080c, 0x42b9, 0x6003,
+ 0x0001, 0x6007, 0x0003, 0x080c, 0x58e2, 0x0020, 0x080c, 0x6fb6,
+ 0x080c, 0x715d, 0x0005, 0x0469, 0x1158, 0x2001, 0x0008, 0x080c,
+ 0x42b9, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x58e2, 0x0010,
+ 0x080c, 0x715d, 0x0005, 0x00e9, 0x1158, 0x2001, 0x000a, 0x080c,
+ 0x42b9, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x58e2, 0x0010,
+ 0x080c, 0x715d, 0x0005, 0x2009, 0x908e, 0x2104, 0xa086, 0x0003,
+ 0x1138, 0x2009, 0x908f, 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00,
0x0005, 0xa085, 0x0001, 0x0005, 0x00c6, 0x0016, 0xac88, 0x0006,
- 0x2164, 0x080c, 0x4443, 0x001e, 0x00ce, 0x0005, 0x00e6, 0x2071,
- 0x978c, 0x7004, 0xa086, 0x0014, 0x11a8, 0x7008, 0xa086, 0x0800,
+ 0x2164, 0x080c, 0x4319, 0x001e, 0x00ce, 0x0005, 0x00e6, 0x2071,
+ 0x908c, 0x7004, 0xa086, 0x0014, 0x11a8, 0x7008, 0xa086, 0x0800,
0x1188, 0x700c, 0xd0ec, 0x0160, 0xa084, 0x0f00, 0xa086, 0x0100,
0x1138, 0x7024, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0xa006, 0x0010,
0xa085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0076,
0x0056, 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2029,
- 0x94ee, 0x252c, 0x2021, 0x94f4, 0x2424, 0x2061, 0x9900, 0x2071,
- 0x9200, 0x7244, 0x7064, 0xa202, 0x1688, 0x080c, 0x90ee, 0x0540,
+ 0x8db3, 0x252c, 0x2021, 0x8db9, 0x2424, 0x2061, 0x9200, 0x2071,
+ 0x8b00, 0x7244, 0x7064, 0xa202, 0x1688, 0x080c, 0x8999, 0x0540,
0x671c, 0xa786, 0x0001, 0x0520, 0xa786, 0x0007, 0x0508, 0x2500,
0xac06, 0x01f0, 0x2400, 0xac06, 0x01d8, 0x00c6, 0x6000, 0xa086,
- 0x0004, 0x1110, 0x080c, 0x1788, 0x6010, 0x2068, 0x080c, 0x82ee,
+ 0x0004, 0x1110, 0x080c, 0x179e, 0x6010, 0x2068, 0x080c, 0x7b8f,
0x0160, 0xa786, 0x0003, 0x11e0, 0x6837, 0x0103, 0x6b4a, 0x6847,
- 0x0000, 0x080c, 0x4809, 0x080c, 0x848f, 0x080c, 0x849b, 0x00ce,
+ 0x0000, 0x080c, 0x46a1, 0x080c, 0x7d30, 0x080c, 0x7d3c, 0x00ce,
0xace0, 0x000c, 0x7058, 0xac02, 0x1208, 0x0858, 0x012e, 0x000e,
0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005,
- 0xa786, 0x0006, 0x1118, 0x080c, 0x9097, 0x0c38, 0xa786, 0x0009,
- 0x19d8, 0x2009, 0x0106, 0x080c, 0x7518, 0x0c08, 0x220c, 0x2304,
- 0xa106, 0x1130, 0x8210, 0x8318, 0x1f04, 0x7aee, 0xa006, 0x0005,
+ 0xa786, 0x0006, 0x1d08, 0x080c, 0x8942, 0x0c38, 0x220c, 0x2304,
+ 0xa106, 0x1130, 0x8210, 0x8318, 0x1f04, 0x7326, 0xa006, 0x0005,
0x2304, 0xa102, 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000,
- 0xa18d, 0x0001, 0x0005, 0x6004, 0xa08a, 0x003e, 0x1a0c, 0x13fe,
- 0x080c, 0x84b7, 0x0120, 0x080c, 0x84c8, 0x0150, 0x0010, 0x080c,
- 0x2692, 0x080c, 0x6389, 0x080c, 0x74f2, 0x080c, 0x6462, 0x0005,
- 0x080c, 0x7776, 0x0cb0, 0xa182, 0x0040, 0x0002, 0x7b31, 0x7b31,
- 0x7b31, 0x7b31, 0x7b31, 0x7b31, 0x7b31, 0x7b31, 0x7b31, 0x7b31,
- 0x7b31, 0x7b33, 0x7b33, 0x7b33, 0x7b33, 0x7b31, 0x7b31, 0x7b31,
- 0x7b33, 0x080c, 0x13fe, 0x6003, 0x0001, 0x6106, 0x080c, 0x5ff8,
- 0x0126, 0x2091, 0x8000, 0x080c, 0x6462, 0x012e, 0x0005, 0xa186,
- 0x0013, 0x1128, 0x6004, 0xa082, 0x0040, 0x0804, 0x7bc5, 0xa186,
- 0x0027, 0x11d0, 0x080c, 0x6389, 0x080c, 0x266c, 0x00d6, 0x6110,
- 0x2168, 0x080c, 0x82ee, 0x0150, 0x6837, 0x0103, 0x684b, 0x0029,
- 0x6847, 0x0000, 0x080c, 0x4809, 0x080c, 0x848f, 0x00de, 0x080c,
- 0x74f2, 0x080c, 0x6462, 0x0005, 0xa186, 0x0014, 0x1120, 0x6004,
+ 0xa18d, 0x0001, 0x0005, 0x6004, 0xa08a, 0x0040, 0x1a0c, 0x1410,
+ 0x080c, 0x7d58, 0x0120, 0x080c, 0x7d69, 0x0150, 0x0010, 0x080c,
+ 0x2589, 0x080c, 0x5c37, 0x080c, 0x6d18, 0x080c, 0x5d10, 0x0005,
+ 0x080c, 0x6fb6, 0x0cb0, 0xa182, 0x0040, 0x0002, 0x7369, 0x7369,
+ 0x7369, 0x7369, 0x7369, 0x7369, 0x7369, 0x7369, 0x7369, 0x7369,
+ 0x7369, 0x736b, 0x736b, 0x736b, 0x736b, 0x7369, 0x7369, 0x7369,
+ 0x736b, 0x080c, 0x1410, 0x6003, 0x0001, 0x6106, 0x080c, 0x589c,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x5d10, 0x012e, 0x0005, 0xa186,
+ 0x0013, 0x1128, 0x6004, 0xa082, 0x0040, 0x0804, 0x7400, 0xa186,
+ 0x0027, 0x11d0, 0x080c, 0x5c37, 0x080c, 0x2563, 0x00d6, 0x6110,
+ 0x2168, 0x080c, 0x7b8f, 0x0150, 0x6837, 0x0103, 0x684b, 0x0029,
+ 0x6847, 0x0000, 0x080c, 0x46a1, 0x080c, 0x7d30, 0x00de, 0x080c,
+ 0x6d18, 0x080c, 0x5d10, 0x0005, 0xa186, 0x0014, 0x1120, 0x6004,
0xa082, 0x0040, 0x0428, 0xa186, 0x0046, 0x0138, 0xa186, 0x0045,
- 0x0120, 0xa186, 0x0047, 0x190c, 0x13fe, 0x2001, 0x0109, 0x2004,
+ 0x0120, 0xa186, 0x0047, 0x190c, 0x1410, 0x2001, 0x0109, 0x2004,
0xd084, 0x0198, 0x0126, 0x2091, 0x2400, 0x0006, 0x0016, 0x0026,
- 0x080c, 0x5ee3, 0x002e, 0x001e, 0x000e, 0x012e, 0xe000, 0x6000,
- 0xa086, 0x0002, 0x1110, 0x0804, 0x7bf0, 0x080c, 0x7526, 0x0005,
- 0x0002, 0x7ba6, 0x7ba4, 0x7ba4, 0x7ba4, 0x7ba4, 0x7ba4, 0x7ba4,
- 0x7ba4, 0x7ba4, 0x7ba4, 0x7ba4, 0x7bbe, 0x7bbe, 0x7bbe, 0x7bbe,
- 0x7ba4, 0x7ba4, 0x7ba4, 0x7bbe, 0x080c, 0x13fe, 0x080c, 0x6389,
- 0x00d6, 0x6110, 0x2168, 0x080c, 0x82ee, 0x0150, 0x6837, 0x0103,
- 0x684b, 0x0006, 0x6847, 0x0000, 0x080c, 0x4809, 0x080c, 0x848f,
- 0x00de, 0x080c, 0x74f2, 0x080c, 0x6462, 0x0005, 0x080c, 0x6389,
- 0x080c, 0x74f2, 0x080c, 0x6462, 0x0005, 0x0002, 0x7bdb, 0x7bd9,
- 0x7bd9, 0x7bd9, 0x7bd9, 0x7bd9, 0x7bd9, 0x7bd9, 0x7bd9, 0x7bd9,
- 0x7bd9, 0x7be9, 0x7be9, 0x7be9, 0x7be9, 0x7bd9, 0x7bd9, 0x7bd9,
- 0x7be9, 0x080c, 0x13fe, 0x080c, 0x6389, 0x6003, 0x0002, 0x080c,
- 0x6462, 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a,
- 0x0005, 0x080c, 0x6389, 0x6003, 0x000f, 0x080c, 0x6462, 0x0005,
- 0xa182, 0x0040, 0x0002, 0x7c06, 0x7c06, 0x7c06, 0x7c06, 0x7c06,
- 0x7c08, 0x7c8a, 0x7ca9, 0x7c06, 0x7c06, 0x7c06, 0x7c06, 0x7c06,
- 0x7c06, 0x7c06, 0x7c06, 0x7c06, 0x7c06, 0x7c06, 0x080c, 0x13fe,
- 0x00e6, 0x00d6, 0x2071, 0x978c, 0x6110, 0x2168, 0x7614, 0xa6b4,
- 0x0fff, 0x86ff, 0x0904, 0x7c70, 0xa68c, 0x0c00, 0x0120, 0x7318,
- 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0190,
- 0xa186, 0x0028, 0x1128, 0x080c, 0x84a6, 0x684b, 0x001c, 0x0060,
- 0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b,
- 0x0007, 0x0010, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0xa01e,
- 0xd6c4, 0x01b0, 0xa686, 0x0100, 0x1138, 0x2001, 0x9799, 0x2004,
- 0xa005, 0x1110, 0xc6c4, 0x0868, 0x7328, 0x732c, 0x6b56, 0x0036,
- 0x2308, 0x2019, 0x9798, 0xad90, 0x0019, 0x080c, 0x80e6, 0x003e,
- 0xd6cc, 0x0560, 0x7124, 0x695a, 0xa192, 0x0021, 0x1250, 0x2071,
- 0x9798, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x80e6,
- 0x00e8, 0x6838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78,
- 0x00f6, 0x2d78, 0x080c, 0x808b, 0x00fe, 0x080c, 0x80d6, 0x0080,
- 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0130,
- 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x7de6, 0x080c, 0x4809,
- 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x00de, 0x00ee, 0x080c,
- 0x74f2, 0x0005, 0x00f6, 0x6003, 0x0003, 0x2079, 0x978c, 0x7c04,
- 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x784c, 0xd0ac, 0x0120,
- 0x6003, 0x0002, 0x00fe, 0x0005, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e,
- 0x00fe, 0x2c10, 0x080c, 0x1c88, 0x080c, 0x605b, 0x080c, 0x651c,
- 0x0005, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20,
- 0x2c10, 0x080c, 0x16c6, 0x0005, 0xa182, 0x0040, 0x0002, 0x7cca,
- 0x7cca, 0x7cca, 0x7cca, 0x7cca, 0x7ccc, 0x7d54, 0x7cca, 0x7cca,
- 0x7d6a, 0x7dc1, 0x7cca, 0x7cca, 0x7cca, 0x7cca, 0x7dcc, 0x7cca,
- 0x7cca, 0x7cca, 0x080c, 0x13fe, 0x0076, 0x00f6, 0x00e6, 0x00d6,
- 0x2071, 0x978c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46,
- 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e,
- 0x86ff, 0x0904, 0x7d4f, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0120,
- 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0904, 0x7d4f,
- 0x080c, 0x147c, 0x090c, 0x13fe, 0x2d00, 0x784a, 0x7f4c, 0xc7cd,
- 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840,
- 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0120, 0x7318, 0x6b62, 0x731c,
- 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0180, 0xa186, 0x0028,
- 0x1118, 0x684b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0x684b, 0x0015,
- 0x0038, 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010, 0x684b, 0x0000,
- 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0160,
- 0x7328, 0x732c, 0x6b56, 0x0036, 0x2308, 0x2019, 0x9798, 0xad90,
- 0x0019, 0x080c, 0x80e6, 0x003e, 0xd6cc, 0x01c8, 0x7124, 0x695a,
- 0xa192, 0x0021, 0x1250, 0x2071, 0x9798, 0x831c, 0x2300, 0xae18,
- 0xad90, 0x001d, 0x080c, 0x80e6, 0x0050, 0x7838, 0xd0fc, 0x0120,
- 0x2009, 0x0020, 0x695a, 0x0c78, 0x2d78, 0x080c, 0x808b, 0x00de,
- 0x00ee, 0x00fe, 0x007e, 0x0005, 0x00f6, 0x6003, 0x0003, 0x2079,
- 0x978c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12,
- 0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x2c10, 0x080c, 0x1c88, 0x080c,
- 0x6f04, 0x0005, 0x00d6, 0x6003, 0x0002, 0x080c, 0x641b, 0x080c,
- 0x651c, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0904, 0x7dbf, 0xd1cc,
- 0x0540, 0x6948, 0x6838, 0xd0fc, 0x01e8, 0x0016, 0x684c, 0x0006,
- 0x6850, 0x0006, 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0023,
- 0x0156, 0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x1f04, 0x7d8a,
- 0x015e, 0x000e, 0x6852, 0x000e, 0x684e, 0x001e, 0x2168, 0x080c,
- 0x14a3, 0x0418, 0x0016, 0x080c, 0x14a3, 0x00de, 0x080c, 0x80d6,
- 0x00e0, 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002,
- 0x0180, 0xa086, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd1dc,
- 0x0118, 0x684b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0x684b, 0x0007,
- 0x0010, 0x684b, 0x0000, 0x080c, 0x4809, 0x080c, 0x74f2, 0x00de,
- 0x0005, 0x2019, 0x0001, 0x080c, 0x7110, 0x6003, 0x0002, 0x080c,
- 0x641b, 0x080c, 0x651c, 0x0005, 0x080c, 0x641b, 0x080c, 0x266c,
- 0x00d6, 0x6110, 0x2168, 0x080c, 0x82ee, 0x0150, 0x6837, 0x0103,
- 0x684b, 0x0029, 0x6847, 0x0000, 0x080c, 0x4809, 0x080c, 0x848f,
- 0x00de, 0x080c, 0x74f2, 0x080c, 0x651c, 0x0005, 0x684b, 0x0015,
- 0xd1fc, 0x0138, 0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189,
- 0x0000, 0x6962, 0x685e, 0x0005, 0xa182, 0x0040, 0x0002, 0x7e0a,
- 0x7e0a, 0x7e0a, 0x7e0a, 0x7e0a, 0x7e0c, 0x7e0a, 0x7eac, 0x7eb4,
- 0x7e0a, 0x7e0a, 0x7e0a, 0x7e0a, 0x7e0a, 0x7e0a, 0x7e0a, 0x7e0a,
- 0x7e0a, 0x7e0a, 0x080c, 0x13fe, 0x0076, 0x00f6, 0x00e6, 0x00d6,
- 0x2071, 0x978c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46,
- 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e,
- 0x86ff, 0x0904, 0x7e9d, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0120,
- 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0904, 0x7e9b,
- 0xa686, 0x0100, 0x1140, 0x2001, 0x9799, 0x2004, 0xa005, 0x1118,
- 0xc6c4, 0x7e46, 0x0c28, 0x080c, 0x147c, 0x090c, 0x13fe, 0x2d00,
- 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838,
- 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00,
- 0x0120, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186,
- 0x0002, 0x0180, 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060,
- 0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b,
- 0x0007, 0x0010, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854,
- 0x6856, 0xa01e, 0xd6c4, 0x0160, 0x7328, 0x732c, 0x6b56, 0x0036,
- 0x2308, 0x2019, 0x9798, 0xad90, 0x0019, 0x080c, 0x80e6, 0x003e,
- 0xd6cc, 0x01c8, 0x7124, 0x695a, 0xa192, 0x0021, 0x1250, 0x2071,
- 0x9798, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x80e6,
- 0x0050, 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78,
- 0x2d78, 0x080c, 0x808b, 0xd6dc, 0x1110, 0xa006, 0x0030, 0x2001,
- 0x0001, 0x2071, 0x978c, 0x7218, 0x731c, 0x080c, 0x1700, 0x00de,
- 0x00ee, 0x00fe, 0x007e, 0x0005, 0x20e1, 0x0005, 0x3d18, 0x3e20,
- 0x2c10, 0x080c, 0x16c6, 0x0005, 0x00d6, 0x6003, 0x0002, 0x6110,
- 0x2168, 0x694c, 0xd1e4, 0x0904, 0x7f3e, 0xd1cc, 0x0904, 0x7f17,
- 0x6948, 0x6838, 0xd0fc, 0x0590, 0x0016, 0x684c, 0x0006, 0x6850,
- 0x0006, 0x684c, 0xd0ac, 0x0180, 0x6810, 0x6914, 0xa115, 0x0160,
- 0x080c, 0x7de6, 0x00f6, 0x6948, 0x2178, 0x6848, 0x784a, 0x6860,
- 0x7862, 0x685c, 0x785e, 0x00fe, 0x6948, 0xad90, 0x000d, 0xa198,
+ 0x080c, 0x578e, 0x002e, 0x001e, 0x000e, 0x012e, 0xe000, 0x6000,
+ 0xa086, 0x0002, 0x1110, 0x0804, 0x742b, 0x080c, 0x6d55, 0x0005,
+ 0x0002, 0x73de, 0x73dc, 0x73dc, 0x73dc, 0x73dc, 0x73dc, 0x73dc,
+ 0x73dc, 0x73dc, 0x73dc, 0x73dc, 0x73f9, 0x73f9, 0x73f9, 0x73f9,
+ 0x73dc, 0x73dc, 0x73dc, 0x73f9, 0x080c, 0x1410, 0x080c, 0x5c37,
+ 0x00d6, 0x6110, 0x2168, 0x080c, 0x7b8f, 0x0168, 0x6837, 0x0103,
+ 0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x080c,
+ 0x46a1, 0x080c, 0x7d30, 0x00de, 0x080c, 0x6d18, 0x080c, 0x5d10,
+ 0x0005, 0x080c, 0x5c37, 0x080c, 0x6d18, 0x080c, 0x5d10, 0x0005,
+ 0x0002, 0x7416, 0x7414, 0x7414, 0x7414, 0x7414, 0x7414, 0x7414,
+ 0x7414, 0x7414, 0x7414, 0x7414, 0x7424, 0x7424, 0x7424, 0x7424,
+ 0x7414, 0x7414, 0x7414, 0x7424, 0x080c, 0x1410, 0x080c, 0x5c37,
+ 0x6003, 0x0002, 0x080c, 0x5d10, 0x6010, 0xa088, 0x0013, 0x2104,
+ 0xa085, 0x0400, 0x200a, 0x0005, 0x080c, 0x5c37, 0x6003, 0x000f,
+ 0x080c, 0x5d10, 0x0005, 0xa182, 0x0040, 0x0002, 0x7441, 0x7441,
+ 0x7441, 0x7441, 0x7441, 0x7443, 0x74c5, 0x74e4, 0x7441, 0x7441,
+ 0x7441, 0x7441, 0x7441, 0x7441, 0x7441, 0x7441, 0x7441, 0x7441,
+ 0x7441, 0x080c, 0x1410, 0x00e6, 0x00d6, 0x2071, 0x908c, 0x6110,
+ 0x2168, 0x7614, 0xa6b4, 0x0fff, 0x86ff, 0x0904, 0x74ab, 0xa68c,
+ 0x0c00, 0x0120, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff,
+ 0xa186, 0x0002, 0x0190, 0xa186, 0x0028, 0x1128, 0x080c, 0x7d47,
+ 0x684b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038,
+ 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010, 0x684b, 0x0000, 0x6837,
+ 0x0103, 0x6e46, 0xa01e, 0xd6c4, 0x01b0, 0xa686, 0x0100, 0x1138,
+ 0x2001, 0x9099, 0x2004, 0xa005, 0x1110, 0xc6c4, 0x0868, 0x7328,
+ 0x732c, 0x6b56, 0x0036, 0x2308, 0x2019, 0x9098, 0xad90, 0x0019,
+ 0x080c, 0x794f, 0x003e, 0xd6cc, 0x0560, 0x7124, 0x695a, 0xa192,
+ 0x0021, 0x1250, 0x2071, 0x9098, 0x831c, 0x2300, 0xae18, 0xad90,
+ 0x001d, 0x080c, 0x794f, 0x00e8, 0x6838, 0xd0fc, 0x0120, 0x2009,
+ 0x0020, 0x695a, 0x0c78, 0x00f6, 0x2d78, 0x080c, 0x78f4, 0x00fe,
+ 0x080c, 0x793f, 0x0080, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46,
+ 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c,
+ 0x7621, 0x080c, 0x46a1, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e,
+ 0x00de, 0x00ee, 0x080c, 0x6d18, 0x0005, 0x00f6, 0x6003, 0x0003,
+ 0x2079, 0x908c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078,
+ 0x784c, 0xd0ac, 0x0120, 0x6003, 0x0002, 0x00fe, 0x0005, 0x7c12,
+ 0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x2c10, 0x080c, 0x1bc8, 0x080c,
+ 0x58ff, 0x080c, 0x5dc2, 0x0005, 0x6003, 0x0004, 0x6110, 0x20e1,
+ 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x16d1, 0x0005, 0xa182,
+ 0x0040, 0x0002, 0x7505, 0x7505, 0x7505, 0x7505, 0x7505, 0x7507,
+ 0x758f, 0x7505, 0x7505, 0x75a5, 0x75fc, 0x7505, 0x7505, 0x7505,
+ 0x7505, 0x7607, 0x7505, 0x7505, 0x7505, 0x080c, 0x1410, 0x0076,
+ 0x00f6, 0x00e6, 0x00d6, 0x2071, 0x908c, 0x6110, 0x2178, 0x7614,
+ 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268,
+ 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0904, 0x758a, 0xa694, 0xff00,
+ 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284,
+ 0x0300, 0x0904, 0x758a, 0x080c, 0x1488, 0x090c, 0x1410, 0x2d00,
+ 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a,
+ 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0120,
+ 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002,
+ 0x0180, 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd6dc,
+ 0x0118, 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b, 0x0007,
+ 0x0010, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856,
+ 0xa01e, 0xd6c4, 0x0160, 0x7328, 0x732c, 0x6b56, 0x0036, 0x2308,
+ 0x2019, 0x9098, 0xad90, 0x0019, 0x080c, 0x794f, 0x003e, 0xd6cc,
+ 0x01c8, 0x7124, 0x695a, 0xa192, 0x0021, 0x1250, 0x2071, 0x9098,
+ 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x794f, 0x0050,
+ 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78, 0x2d78,
+ 0x080c, 0x78f4, 0x00de, 0x00ee, 0x00fe, 0x007e, 0x0005, 0x00f6,
+ 0x6003, 0x0003, 0x2079, 0x908c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08,
+ 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x2c10,
+ 0x080c, 0x1bc8, 0x080c, 0x66dd, 0x0005, 0x00d6, 0x6003, 0x0002,
+ 0x080c, 0x5cc9, 0x080c, 0x5dc2, 0x6110, 0x2168, 0x694c, 0xd1e4,
+ 0x0904, 0x75fa, 0xd1cc, 0x0540, 0x6948, 0x6838, 0xd0fc, 0x01e8,
+ 0x0016, 0x684c, 0x0006, 0x6850, 0x0006, 0xad90, 0x000d, 0xa198,
0x000d, 0x2009, 0x0023, 0x0156, 0x21a8, 0x2304, 0x2012, 0x8318,
- 0x8210, 0x1f04, 0x7ee5, 0x015e, 0x000e, 0x6852, 0x000e, 0x684e,
- 0x001e, 0x2168, 0x080c, 0x14a3, 0x0804, 0x7f3c, 0x0016, 0x684c,
- 0xd0ac, 0x0190, 0x6810, 0x6914, 0xa115, 0x0170, 0x080c, 0x7de6,
- 0x00f6, 0x6948, 0x2178, 0x6848, 0x784a, 0x6860, 0x7862, 0x685c,
- 0x785e, 0x684c, 0x784e, 0x00fe, 0x6948, 0xa188, 0x0013, 0x684c,
- 0x200a, 0x080c, 0x14a3, 0x00de, 0x080c, 0x80d6, 0x0428, 0x6837,
- 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0180, 0xa086,
- 0x0028, 0x1118, 0x684b, 0x001c, 0x00a8, 0xd1dc, 0x0118, 0x684b,
- 0x0015, 0x0080, 0xd1d4, 0x0118, 0x684b, 0x0007, 0x0058, 0x684b,
- 0x0000, 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110,
- 0x080c, 0x7de6, 0x080c, 0x4809, 0x080c, 0x74f2, 0x00de, 0x0005,
- 0x080c, 0x6389, 0x0010, 0x080c, 0x641b, 0x080c, 0x82ee, 0x0198,
- 0x00d6, 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0x920c, 0x210c,
- 0xd18c, 0x1188, 0xd184, 0x1160, 0x6108, 0x694a, 0x6847, 0x0000,
- 0x080c, 0x4809, 0x00de, 0x080c, 0x74f2, 0x080c, 0x6462, 0x0005,
- 0x684b, 0x0004, 0x0c98, 0x684b, 0x0004, 0x0c80, 0xa182, 0x0040,
- 0x0002, 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7e, 0x7f7c,
- 0x7f81, 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7c,
- 0x7f7c, 0x7f7c, 0x7f7c, 0x7f7c, 0x080c, 0x13fe, 0x080c, 0x74f2,
- 0x0005, 0x0006, 0x0026, 0xa016, 0x080c, 0x16c6, 0x002e, 0x000e,
- 0x0005, 0xa182, 0x0085, 0x0002, 0x7f95, 0x7f93, 0x7f93, 0x7f93,
- 0x7f93, 0x7f93, 0x7f93, 0x080c, 0x13fe, 0x6003, 0x000b, 0x6106,
- 0x080c, 0x5ff8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6462, 0x012e,
- 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a, 0x0085, 0x0a0c,
- 0x13fe, 0xa08a, 0x008c, 0x1a0c, 0x13fe, 0xa082, 0x0085, 0x0072,
- 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c, 0x13fe, 0x080c,
- 0x6389, 0x080c, 0x849b, 0x080c, 0x6462, 0x0005, 0x7fc5, 0x7fc7,
- 0x7fc7, 0x7fc5, 0x7fc5, 0x7fc5, 0x7fc5, 0x080c, 0x13fe, 0x080c,
- 0x6389, 0x080c, 0x849b, 0x080c, 0x6462, 0x0005, 0xa186, 0x0013,
- 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x0492, 0xa186, 0x0027,
- 0x11e8, 0x080c, 0x6389, 0x080c, 0x266c, 0x00d6, 0x6010, 0x2068,
- 0x080c, 0x82ee, 0x0150, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b,
- 0x0029, 0x080c, 0x4809, 0x080c, 0x848f, 0x00de, 0x080c, 0x74f2,
- 0x080c, 0x6462, 0x0005, 0x080c, 0x7526, 0x0ce0, 0xa186, 0x0014,
- 0x1dd0, 0x080c, 0x6389, 0x00d6, 0x6010, 0x2068, 0x080c, 0x82ee,
- 0x0d60, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b, 0x0006, 0x0c08,
- 0x8011, 0x800f, 0x800f, 0x800f, 0x800f, 0x800f, 0x801a, 0x080c,
- 0x13fe, 0x080c, 0x6389, 0x6017, 0x0014, 0x6003, 0x000c, 0x080c,
- 0x6462, 0x0005, 0x080c, 0x6389, 0x6017, 0x0014, 0x6003, 0x000e,
- 0x080c, 0x6462, 0x0005, 0xa182, 0x008c, 0x1220, 0xa182, 0x0085,
- 0x0208, 0x001a, 0x080c, 0x7526, 0x0005, 0x8034, 0x8034, 0x8034,
- 0x8034, 0x8036, 0x8057, 0x8034, 0x080c, 0x13fe, 0x00d6, 0x080c,
- 0x848f, 0x080c, 0x82ee, 0x01b8, 0x6010, 0x2068, 0x6837, 0x0103,
- 0x6850, 0xd0b4, 0x0118, 0x684b, 0x0006, 0x0048, 0xd0bc, 0x0118,
- 0x684b, 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x852d, 0x6847,
- 0x0000, 0x080c, 0x4809, 0x080c, 0x74f2, 0x00de, 0x0005, 0x00d6,
- 0x6010, 0x2068, 0x080c, 0x82ee, 0x01b8, 0x6837, 0x0103, 0x6850,
- 0xd0b4, 0x0118, 0x684b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0x684b,
- 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x852d, 0x6847, 0x0000,
- 0x080c, 0x4809, 0x080c, 0x848f, 0x00de, 0x080c, 0x74f2, 0x0005,
- 0xa186, 0x0013, 0x0148, 0xa186, 0x0014, 0x0130, 0xa186, 0x0027,
- 0x0118, 0x080c, 0x7526, 0x0030, 0x080c, 0x6389, 0x080c, 0x849b,
- 0x080c, 0x6462, 0x0005, 0x0056, 0x0066, 0x00d6, 0x00f6, 0x2029,
- 0x0001, 0xa182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130,
- 0x2069, 0x9798, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, 0xaf90,
- 0x001d, 0x080c, 0x80e6, 0xa6b2, 0x0020, 0x7804, 0xa06d, 0x0110,
- 0x080c, 0x14a3, 0x080c, 0x147c, 0x0500, 0x8528, 0x6837, 0x0110,
- 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d, 0x1228, 0x2608,
- 0xad90, 0x000f, 0x0459, 0x0088, 0xa6b2, 0x003c, 0x2009, 0x003c,
- 0x2d78, 0xad90, 0x000f, 0x0411, 0x0c28, 0x00fe, 0x852f, 0xa5ad,
- 0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0028, 0x00fe, 0x852f, 0xa5ad,
- 0x0003, 0x7d36, 0x00de, 0x006e, 0x005e, 0x0005, 0x00f6, 0x8dff,
- 0x0158, 0x6804, 0xa07d, 0x0130, 0x6807, 0x0000, 0x080c, 0x4809,
- 0x2f68, 0x0cb8, 0x080c, 0x4809, 0x00fe, 0x0005, 0x0156, 0xa184,
- 0x0001, 0x0108, 0x8108, 0x810c, 0x21a8, 0x2304, 0x8007, 0x2012,
- 0x8318, 0x8210, 0x1f04, 0x80ed, 0x015e, 0x0005, 0x0126, 0x2091,
- 0x8000, 0x601c, 0xa084, 0x000f, 0x0013, 0x012e, 0x0005, 0x8117,
- 0x8109, 0x8112, 0x812e, 0x8109, 0x8112, 0x810b, 0x8112, 0x8109,
- 0x5e80, 0x080c, 0x13fe, 0x0036, 0x2019, 0x0010, 0x080c, 0x8d4e,
- 0x003e, 0x0005, 0xa006, 0x0005, 0xa085, 0x0001, 0x0005, 0x00d6,
- 0x6010, 0x2068, 0x080c, 0x82ee, 0x0178, 0xa00e, 0x2001, 0x0005,
- 0x080c, 0x492c, 0x080c, 0x852d, 0x080c, 0x4809, 0x080c, 0x74f2,
- 0xa085, 0x0001, 0x00de, 0x0005, 0xa006, 0x0ce0, 0x6000, 0xa08a,
- 0x0010, 0x1a0c, 0x13fe, 0x000b, 0x0005, 0x8145, 0x8160, 0x8147,
- 0x816f, 0x815d, 0x8145, 0x8112, 0x8117, 0x8117, 0x8112, 0x8112,
- 0x8112, 0x8112, 0x8112, 0x8112, 0x8112, 0x080c, 0x13fe, 0x00d6,
- 0x6010, 0x2068, 0x080c, 0x82ee, 0x0110, 0x080c, 0x852d, 0x00de,
- 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x5ff8,
- 0x080c, 0x6462, 0xa085, 0x0001, 0x0005, 0x080c, 0x1788, 0x0c38,
- 0x00e6, 0x2071, 0x94e5, 0x7024, 0xac06, 0x1110, 0x080c, 0x708d,
- 0x080c, 0x6fab, 0x00ee, 0x19d8, 0x080c, 0x8112, 0x0005, 0x0036,
- 0x00e6, 0x2071, 0x94e5, 0x703c, 0xac06, 0x1138, 0x2019, 0x0000,
- 0x080c, 0x7110, 0x00ee, 0x003e, 0x0850, 0x080c, 0x7366, 0x00ee,
- 0x003e, 0x1928, 0x080c, 0x8112, 0x0005, 0x00c6, 0x601c, 0xa084,
- 0x000f, 0x0013, 0x00ce, 0x0005, 0x819a, 0x81f7, 0x829a, 0x819e,
- 0x819a, 0x819a, 0x8d44, 0x74f2, 0x81f7, 0x080c, 0x84c8, 0x1110,
- 0x080c, 0x7776, 0x0005, 0x6017, 0x0001, 0x0005, 0x6000, 0xa08a,
- 0x0010, 0x1a0c, 0x13fe, 0x000b, 0x0005, 0x81b5, 0x81b7, 0x81d5,
- 0x81e7, 0x81f4, 0x81b5, 0x819a, 0x819a, 0x819a, 0x81e7, 0x81e7,
- 0x81b5, 0x81b5, 0x81b5, 0x81b5, 0x81f1, 0x080c, 0x13fe, 0x00e6,
- 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071, 0x94e5, 0x7024,
- 0xac06, 0x0180, 0x080c, 0x6fab, 0x6007, 0x0085, 0x6003, 0x000b,
- 0x601f, 0x0002, 0x6017, 0x0014, 0x080c, 0x5ff8, 0x080c, 0x6462,
- 0x00ee, 0x0005, 0x6017, 0x0001, 0x0cd8, 0x00d6, 0x6010, 0x2068,
- 0x6850, 0xc0b5, 0x6852, 0x00de, 0x6007, 0x0085, 0x6003, 0x000b,
- 0x601f, 0x0002, 0x080c, 0x5ff8, 0x080c, 0x6462, 0x0005, 0x00d6,
- 0x6017, 0x0001, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x00de,
- 0x0005, 0x080c, 0x74f2, 0x0005, 0x080c, 0x1788, 0x08f0, 0x6000,
- 0xa08a, 0x0010, 0x1a0c, 0x13fe, 0x000b, 0x0005, 0x820e, 0x819b,
- 0x8210, 0x820e, 0x8210, 0x820e, 0x820e, 0x820e, 0x8195, 0x8195,
- 0x820e, 0x820e, 0x820e, 0x820e, 0x820e, 0x820e, 0x080c, 0x13fe,
- 0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa08a,
- 0x000c, 0x1a0c, 0x13fe, 0x000b, 0x0005, 0x8229, 0x824a, 0x8229,
- 0x824a, 0x8229, 0x824a, 0x822b, 0x8232, 0x8229, 0x824a, 0x8229,
- 0x8243, 0x080c, 0x13fe, 0x6004, 0xa08e, 0x0004, 0x01b0, 0xa08e,
- 0x0002, 0x0198, 0x6004, 0x080c, 0x84c8, 0x0904, 0x8292, 0xa08e,
- 0x0021, 0x0904, 0x8296, 0xa08e, 0x0022, 0x0904, 0x8292, 0xa08e,
- 0x003d, 0x0904, 0x8296, 0x080c, 0x266c, 0x080c, 0x7776, 0x080c,
- 0x74f2, 0x0005, 0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016, 0x0598,
- 0xa186, 0x0002, 0x11f8, 0x6018, 0x2068, 0x2001, 0x9232, 0x2004,
- 0xd0ac, 0x11c0, 0x68a0, 0xd0bc, 0x11a8, 0x6840, 0xa084, 0x00ff,
- 0xa005, 0x0180, 0x8001, 0x6842, 0x6013, 0x0000, 0x601f, 0x0007,
- 0x6017, 0x0398, 0x080c, 0x749c, 0x0128, 0x2d00, 0x601a, 0x601f,
- 0x0001, 0x0088, 0x00de, 0x00ce, 0x080c, 0x7776, 0x080c, 0x266c,
- 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2692, 0x012e, 0x00ee,
- 0x080c, 0x74f2, 0x0005, 0x2001, 0x0002, 0x080c, 0x43e3, 0x6003,
- 0x0001, 0x6007, 0x0002, 0x080c, 0x603e, 0x080c, 0x6462, 0x00de,
- 0x00ce, 0x0c80, 0x080c, 0x7776, 0x0804, 0x8247, 0x080c, 0x7790,
- 0x0804, 0x8247, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x13fe, 0x000b,
- 0x0005, 0x82b1, 0x82b1, 0x82b1, 0x82b1, 0x82b1, 0x82b1, 0x82b1,
- 0x82b1, 0x82b1, 0x819a, 0x82b1, 0x819b, 0x82b3, 0x819b, 0x82bc,
- 0x82b1, 0x080c, 0x13fe, 0x6007, 0x008b, 0x6003, 0x000d, 0x080c,
- 0x5ff8, 0x080c, 0x6462, 0x0005, 0x080c, 0x848f, 0x0479, 0x01d8,
- 0x080c, 0x266c, 0x00d6, 0x0451, 0x0150, 0x6010, 0x2068, 0x6837,
- 0x0103, 0x684b, 0x0006, 0x6847, 0x0000, 0x080c, 0x4809, 0x00de,
- 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x603e,
- 0x080c, 0x6462, 0x0010, 0x080c, 0x74f2, 0x0005, 0xa284, 0x0003,
- 0x1158, 0xa282, 0x9900, 0x0240, 0x2001, 0x9216, 0x2004, 0xa202,
- 0x1218, 0xa085, 0x0001, 0x0005, 0xa006, 0x0ce8, 0x0026, 0x6210,
- 0x82ff, 0x002e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126,
- 0x2091, 0x8000, 0x2061, 0x9900, 0x2071, 0x9200, 0x7344, 0x7064,
- 0xa302, 0x1290, 0x601c, 0xa206, 0x1148, 0x080c, 0x84c8, 0x1110,
- 0x080c, 0x7776, 0x00c6, 0x080c, 0x74f2, 0x00ce, 0xace0, 0x000c,
- 0x7058, 0xac02, 0x1208, 0x0c50, 0x012e, 0x000e, 0x003e, 0x00ce,
- 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0xa188, 0x936e, 0x210c,
- 0x81ff, 0x0170, 0x2061, 0x9900, 0x2071, 0x9200, 0x0016, 0x080c,
- 0x749c, 0x001e, 0x0138, 0x611a, 0x080c, 0x266c, 0x080c, 0x74f2,
- 0xa006, 0x0010, 0xa085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005,
- 0x00c6, 0x0056, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x749c,
- 0x005e, 0x0170, 0x6612, 0x651a, 0x601f, 0x0003, 0x2009, 0x004b,
- 0x080c, 0x7518, 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005,
- 0xa006, 0x0cd0, 0x00c6, 0x0056, 0x0126, 0x2091, 0x8000, 0x62a0,
- 0x00c6, 0x080c, 0x749c, 0x005e, 0x01f8, 0x6013, 0x0000, 0x651a,
- 0x601f, 0x0003, 0x00c6, 0x2560, 0x080c, 0x460d, 0x00ce, 0x080c,
- 0x6127, 0x0086, 0x2041, 0x0000, 0x080c, 0x606d, 0x2c08, 0x080c,
- 0x8ee4, 0x008e, 0x2009, 0x004c, 0x080c, 0x7518, 0xa085, 0x0001,
- 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00c6, 0x0056,
- 0x0126, 0x2091, 0x8000, 0x62a0, 0x00c6, 0x080c, 0x749c, 0x005e,
- 0x0500, 0x6612, 0x651a, 0x601f, 0x0003, 0x2019, 0x0005, 0x00c6,
- 0x2560, 0x080c, 0x460d, 0x00ce, 0x080c, 0x6127, 0x0086, 0x2041,
- 0x0000, 0x080c, 0x606d, 0x2c08, 0x080c, 0x8ee4, 0x008e, 0x2009,
- 0x004d, 0x080c, 0x7518, 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce,
+ 0x8210, 0x1f04, 0x75c5, 0x015e, 0x000e, 0x6852, 0x000e, 0x684e,
+ 0x001e, 0x2168, 0x080c, 0x14af, 0x0418, 0x0016, 0x080c, 0x14af,
+ 0x00de, 0x080c, 0x793f, 0x00e0, 0x6837, 0x0103, 0x6944, 0xa184,
+ 0x00ff, 0xa0b6, 0x0002, 0x0180, 0xa086, 0x0028, 0x1118, 0x684b,
+ 0x001c, 0x0060, 0xd1dc, 0x0118, 0x684b, 0x0015, 0x0038, 0xd1d4,
+ 0x0118, 0x684b, 0x0007, 0x0010, 0x684b, 0x0000, 0x080c, 0x46a1,
+ 0x080c, 0x6d18, 0x00de, 0x0005, 0x2019, 0x0001, 0x080c, 0x68e5,
+ 0x6003, 0x0002, 0x080c, 0x5cc9, 0x080c, 0x5dc2, 0x0005, 0x080c,
+ 0x5cc9, 0x080c, 0x2563, 0x00d6, 0x6110, 0x2168, 0x080c, 0x7b8f,
+ 0x0150, 0x6837, 0x0103, 0x684b, 0x0029, 0x6847, 0x0000, 0x080c,
+ 0x46a1, 0x080c, 0x7d30, 0x00de, 0x080c, 0x6d18, 0x080c, 0x5dc2,
+ 0x0005, 0x684b, 0x0015, 0xd1fc, 0x0138, 0x684b, 0x0007, 0x8002,
+ 0x8000, 0x810a, 0xa189, 0x0000, 0x6962, 0x685e, 0x0005, 0xa182,
+ 0x0040, 0x0002, 0x7645, 0x7645, 0x7645, 0x7645, 0x7645, 0x7647,
+ 0x7645, 0x76e7, 0x76ef, 0x7645, 0x7645, 0x7645, 0x7645, 0x7645,
+ 0x7645, 0x7645, 0x7645, 0x7645, 0x7645, 0x080c, 0x1410, 0x0076,
+ 0x00f6, 0x00e6, 0x00d6, 0x2071, 0x908c, 0x6110, 0x2178, 0x7614,
+ 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268,
+ 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0904, 0x76d8, 0xa694, 0xff00,
+ 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284,
+ 0x0300, 0x0904, 0x76d6, 0xa686, 0x0100, 0x1140, 0x2001, 0x9099,
+ 0x2004, 0xa005, 0x1118, 0xc6c4, 0x7e46, 0x0c28, 0x080c, 0x1488,
+ 0x090c, 0x1410, 0x2d00, 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e,
+ 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842,
+ 0x6e46, 0xa68c, 0x0c00, 0x0120, 0x7318, 0x6b62, 0x731c, 0x6b5e,
+ 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0180, 0xa186, 0x0028, 0x1118,
+ 0x684b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038,
+ 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010, 0x684b, 0x0000, 0x6f4e,
+ 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0160, 0x7328,
+ 0x732c, 0x6b56, 0x0036, 0x2308, 0x2019, 0x9098, 0xad90, 0x0019,
+ 0x080c, 0x794f, 0x003e, 0xd6cc, 0x01c8, 0x7124, 0x695a, 0xa192,
+ 0x0021, 0x1250, 0x2071, 0x9098, 0x831c, 0x2300, 0xae18, 0xad90,
+ 0x001d, 0x080c, 0x794f, 0x0050, 0x7838, 0xd0fc, 0x0120, 0x2009,
+ 0x0020, 0x695a, 0x0c78, 0x2d78, 0x080c, 0x78f4, 0xd6dc, 0x1110,
+ 0xa006, 0x0030, 0x2001, 0x0001, 0x2071, 0x908c, 0x7218, 0x731c,
+ 0x080c, 0x1716, 0x00de, 0x00ee, 0x00fe, 0x007e, 0x0005, 0x20e1,
+ 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x16d1, 0x0005, 0x00d6,
+ 0x6003, 0x0002, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0904, 0x778d,
+ 0xd1cc, 0x0904, 0x7766, 0x6948, 0x6838, 0xd0fc, 0x0590, 0x0016,
+ 0x684c, 0x0006, 0x6850, 0x0006, 0x684c, 0xd0ac, 0x0180, 0x6810,
+ 0x6914, 0xa115, 0x0160, 0x080c, 0x7621, 0x00f6, 0x6948, 0x2178,
+ 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0x00fe, 0x6948,
+ 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0023, 0x0156, 0x21a8,
+ 0x2304, 0x2012, 0x8318, 0x8210, 0x1f04, 0x7720, 0x015e, 0x000e,
+ 0x6852, 0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x14af, 0x0804,
+ 0x778b, 0x0016, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6,
+ 0x0002, 0x01b0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c, 0x784b,
+ 0x001c, 0x00b8, 0xd1dc, 0x0128, 0x684b, 0x0015, 0x784b, 0x0015,
+ 0x0080, 0xd1d4, 0x0128, 0x684b, 0x0007, 0x784b, 0x0007, 0x0048,
+ 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c,
+ 0x7621, 0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e, 0x00fe,
+ 0x080c, 0x14af, 0x00de, 0x080c, 0x793f, 0x0428, 0x6837, 0x0103,
+ 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0180, 0xa086, 0x0028,
+ 0x1118, 0x684b, 0x001c, 0x00a8, 0xd1dc, 0x0118, 0x684b, 0x0015,
+ 0x0080, 0xd1d4, 0x0118, 0x684b, 0x0007, 0x0058, 0x684b, 0x0000,
+ 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c,
+ 0x7621, 0x080c, 0x46a1, 0x080c, 0x6d18, 0x00de, 0x0005, 0x080c,
+ 0x5c37, 0x0010, 0x080c, 0x5cc9, 0x080c, 0x7b8f, 0x0198, 0x00d6,
+ 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0x8b0c, 0x210c, 0xd18c,
+ 0x1198, 0xd184, 0x1170, 0x6108, 0x694a, 0x6847, 0x0000, 0x080c,
+ 0x46a1, 0x00de, 0x080c, 0x6d18, 0x080c, 0x5d10, 0x080c, 0x5dc2,
+ 0x0005, 0x684b, 0x0004, 0x0c88, 0x684b, 0x0004, 0x0c70, 0xa182,
+ 0x0040, 0x0002, 0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x77cf,
+ 0x77cd, 0x77d2, 0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x77cd,
+ 0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x080c, 0x1410, 0x080c,
+ 0x6d18, 0x0005, 0x0006, 0x0026, 0xa016, 0x080c, 0x16d1, 0x002e,
+ 0x000e, 0x0005, 0xa182, 0x0085, 0x0002, 0x77e6, 0x77e4, 0x77e4,
+ 0x77e4, 0x77e4, 0x77e4, 0x77e4, 0x080c, 0x1410, 0x6003, 0x000b,
+ 0x6106, 0x080c, 0x589c, 0x0126, 0x2091, 0x8000, 0x080c, 0x5d10,
+ 0x012e, 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a, 0x0085,
+ 0x0a0c, 0x1410, 0xa08a, 0x008c, 0x1a0c, 0x1410, 0xa082, 0x0085,
+ 0x0072, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c, 0x1410,
+ 0x080c, 0x5c37, 0x080c, 0x7d3c, 0x080c, 0x5d10, 0x0005, 0x7816,
+ 0x7818, 0x7818, 0x7816, 0x7816, 0x7816, 0x7816, 0x080c, 0x1410,
+ 0x080c, 0x5c37, 0x080c, 0x7d3c, 0x080c, 0x5d10, 0x0005, 0xa186,
+ 0x0013, 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x04aa, 0xa186,
+ 0x0027, 0x11e8, 0x080c, 0x5c37, 0x080c, 0x2563, 0x00d6, 0x6010,
+ 0x2068, 0x080c, 0x7b8f, 0x0150, 0x6837, 0x0103, 0x6847, 0x0000,
+ 0x684b, 0x0029, 0x080c, 0x46a1, 0x080c, 0x7d30, 0x00de, 0x080c,
+ 0x6d18, 0x080c, 0x5d10, 0x0005, 0x080c, 0x6d55, 0x0ce0, 0xa186,
+ 0x0014, 0x1dd0, 0x080c, 0x5c37, 0x00d6, 0x6010, 0x2068, 0x080c,
+ 0x7b8f, 0x0d60, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b, 0x0006,
+ 0x6850, 0xc0ec, 0x6852, 0x08f0, 0x7865, 0x7863, 0x7863, 0x7863,
+ 0x7863, 0x7863, 0x786e, 0x080c, 0x1410, 0x080c, 0x5c37, 0x6017,
+ 0x0014, 0x6003, 0x000c, 0x080c, 0x5d10, 0x0005, 0x080c, 0x5c37,
+ 0x6017, 0x0014, 0x6003, 0x000e, 0x080c, 0x5d10, 0x0005, 0xa182,
+ 0x008c, 0x1220, 0xa182, 0x0085, 0x0208, 0x001a, 0x080c, 0x6d55,
+ 0x0005, 0x7888, 0x7888, 0x7888, 0x7888, 0x788a, 0x78ad, 0x7888,
+ 0x080c, 0x1410, 0x00d6, 0x080c, 0x7d30, 0x080c, 0x7b8f, 0x01c8,
+ 0x6010, 0x2068, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0128, 0x684b,
+ 0x0006, 0xc0ec, 0x6852, 0x0048, 0xd0bc, 0x0118, 0x684b, 0x0002,
+ 0x0020, 0x684b, 0x0005, 0x080c, 0x7dce, 0x6847, 0x0000, 0x080c,
+ 0x46a1, 0x080c, 0x6d18, 0x00de, 0x0005, 0x00d6, 0x6010, 0x2068,
+ 0x080c, 0x7b8f, 0x01c8, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0128,
+ 0xc0ec, 0x6852, 0x684b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0x684b,
+ 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x7dce, 0x6847, 0x0000,
+ 0x080c, 0x46a1, 0x080c, 0x7d30, 0x00de, 0x080c, 0x6d18, 0x0005,
+ 0x0016, 0x00d6, 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0140, 0x6837,
+ 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x080c, 0x46a1, 0x00de,
+ 0x001e, 0xa186, 0x0013, 0x0148, 0xa186, 0x0014, 0x0130, 0xa186,
+ 0x0027, 0x0118, 0x080c, 0x6d55, 0x0030, 0x080c, 0x5c37, 0x080c,
+ 0x7d3c, 0x080c, 0x5d10, 0x0005, 0x0056, 0x0066, 0x00d6, 0x00f6,
+ 0x2029, 0x0001, 0xa182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100,
+ 0x2130, 0x2069, 0x9098, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020,
+ 0xaf90, 0x001d, 0x080c, 0x794f, 0xa6b2, 0x0020, 0x7804, 0xa06d,
+ 0x0110, 0x080c, 0x14af, 0x080c, 0x1488, 0x0500, 0x8528, 0x6837,
+ 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d, 0x1228,
+ 0x2608, 0xad90, 0x000f, 0x0459, 0x0088, 0xa6b2, 0x003c, 0x2009,
+ 0x003c, 0x2d78, 0xad90, 0x000f, 0x0411, 0x0c28, 0x00fe, 0x852f,
+ 0xa5ad, 0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0028, 0x00fe, 0x852f,
+ 0xa5ad, 0x0003, 0x7d36, 0x00de, 0x006e, 0x005e, 0x0005, 0x00f6,
+ 0x8dff, 0x0158, 0x6804, 0xa07d, 0x0130, 0x6807, 0x0000, 0x080c,
+ 0x46a1, 0x2f68, 0x0cb8, 0x080c, 0x46a1, 0x00fe, 0x0005, 0x0156,
+ 0xa184, 0x0001, 0x0108, 0x8108, 0x810c, 0x21a8, 0x2304, 0x8007,
+ 0x2012, 0x8318, 0x8210, 0x1f04, 0x7956, 0x015e, 0x0005, 0x0126,
+ 0x2091, 0x8000, 0x601c, 0xa084, 0x000f, 0x0013, 0x012e, 0x0005,
+ 0x797e, 0x7970, 0x7979, 0x7995, 0x7970, 0x7979, 0x7972, 0x7979,
+ 0x080c, 0x1410, 0x0036, 0x2019, 0x0010, 0x080c, 0x85f9, 0x003e,
+ 0x0005, 0xa006, 0x0005, 0xa085, 0x0001, 0x0005, 0x00d6, 0x6010,
+ 0x2068, 0x080c, 0x7b8f, 0x0178, 0xa00e, 0x2001, 0x0005, 0x080c,
+ 0x4773, 0x080c, 0x7dce, 0x080c, 0x46a1, 0x080c, 0x6d18, 0xa085,
+ 0x0001, 0x00de, 0x0005, 0xa006, 0x0ce0, 0x6000, 0xa08a, 0x0010,
+ 0x1a0c, 0x1410, 0x000b, 0x0005, 0x79ac, 0x79c7, 0x79ae, 0x79d6,
+ 0x79c4, 0x79ac, 0x7979, 0x797e, 0x797e, 0x7979, 0x7979, 0x7979,
+ 0x7979, 0x7979, 0x7979, 0x7979, 0x080c, 0x1410, 0x00d6, 0x6010,
+ 0x2068, 0x080c, 0x7b8f, 0x0110, 0x080c, 0x7dce, 0x00de, 0x6007,
+ 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x589c, 0x080c,
+ 0x5d10, 0xa085, 0x0001, 0x0005, 0x080c, 0x179e, 0x0c38, 0x00e6,
+ 0x2071, 0x8daa, 0x7024, 0xac06, 0x1110, 0x080c, 0x6862, 0x080c,
+ 0x677e, 0x00ee, 0x19d8, 0x080c, 0x7979, 0x0005, 0x0036, 0x00e6,
+ 0x2071, 0x8daa, 0x703c, 0xac06, 0x1138, 0x2019, 0x0000, 0x080c,
+ 0x68e5, 0x00ee, 0x003e, 0x0850, 0x080c, 0x6b33, 0x00ee, 0x003e,
+ 0x1928, 0x080c, 0x7979, 0x0005, 0x00c6, 0x601c, 0xa084, 0x000f,
+ 0x0013, 0x00ce, 0x0005, 0x7a01, 0x7a62, 0x7b28, 0x7a05, 0x7a01,
+ 0x7a01, 0x85ef, 0x6d18, 0x7a62, 0x080c, 0x7d69, 0x1110, 0x080c,
+ 0x6fb6, 0x0005, 0x6017, 0x0001, 0x0005, 0x6010, 0xa080, 0x0019,
+ 0x2c02, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x1410, 0x000b, 0x0005,
+ 0x7a20, 0x7a22, 0x7a40, 0x7a52, 0x7a5f, 0x7a20, 0x7a01, 0x7a01,
+ 0x7a01, 0x7a52, 0x7a52, 0x7a20, 0x7a20, 0x7a20, 0x7a20, 0x7a5c,
+ 0x080c, 0x1410, 0x00e6, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052,
+ 0x2071, 0x8daa, 0x7024, 0xac06, 0x0180, 0x080c, 0x677e, 0x6007,
+ 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6017, 0x0014, 0x080c,
+ 0x589c, 0x080c, 0x5d10, 0x00ee, 0x0005, 0x6017, 0x0001, 0x0cd8,
+ 0x00d6, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x00de, 0x6007,
+ 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x589c, 0x080c,
+ 0x5d10, 0x0005, 0x00d6, 0x6017, 0x0001, 0x6010, 0x2068, 0x6850,
+ 0xc0b5, 0x6852, 0x00de, 0x0005, 0x080c, 0x6d18, 0x0005, 0x080c,
+ 0x179e, 0x08f0, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x1410, 0x000b,
+ 0x0005, 0x7a79, 0x7a02, 0x7a7b, 0x7a79, 0x7a7b, 0x7a79, 0x7a79,
+ 0x7a79, 0x79fc, 0x79fc, 0x7a79, 0x7a79, 0x7a79, 0x7a79, 0x7a79,
+ 0x7a79, 0x080c, 0x1410, 0x00d6, 0x6018, 0x2068, 0x6804, 0xa084,
+ 0x00ff, 0x00de, 0xa08a, 0x000c, 0x1a0c, 0x1410, 0x000b, 0x0005,
+ 0x7a94, 0x7ac2, 0x7a94, 0x7ac2, 0x7a94, 0x7ac2, 0x7a96, 0x7a9d,
+ 0x7a94, 0x7ac2, 0x7a94, 0x7aae, 0x080c, 0x1410, 0x6004, 0xa08e,
+ 0x0004, 0x0518, 0xa08e, 0x0002, 0x0500, 0x6004, 0x080c, 0x7d69,
+ 0x0904, 0x7b0b, 0xa08e, 0x0021, 0x0904, 0x7b0f, 0xa08e, 0x0022,
+ 0x0904, 0x7b0b, 0xa08e, 0x003d, 0x0904, 0x7b0f, 0xa08e, 0x0001,
+ 0x1150, 0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x00de,
+ 0xa086, 0x0006, 0x0110, 0x080c, 0x2563, 0x080c, 0x6fb6, 0x080c,
+ 0x7d3c, 0x0005, 0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016, 0x05a0,
+ 0xa186, 0x0002, 0x1500, 0x6018, 0x2068, 0x2001, 0x8b32, 0x2004,
+ 0xd0ac, 0x1904, 0x7b13, 0x68a0, 0xd0bc, 0x15e8, 0x6840, 0xa084,
+ 0x00ff, 0xa005, 0x0180, 0x8001, 0x6842, 0x6013, 0x0000, 0x601f,
+ 0x0007, 0x6017, 0x0398, 0x080c, 0x6cc2, 0x0128, 0x2d00, 0x601a,
+ 0x601f, 0x0001, 0x0088, 0x00de, 0x00ce, 0x080c, 0x6fb6, 0x080c,
+ 0x2563, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2589, 0x012e,
+ 0x00ee, 0x080c, 0x7d3c, 0x0005, 0x2001, 0x0002, 0x080c, 0x42b9,
+ 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x58e2, 0x080c, 0x5d10,
+ 0x00de, 0x00ce, 0x0c80, 0x080c, 0x6fb6, 0x0804, 0x7abf, 0x080c,
+ 0x6fd3, 0x0804, 0x7abf, 0x00de, 0x00ce, 0x080c, 0x6fb6, 0x080c,
+ 0x2563, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2589, 0x6013,
+ 0x0000, 0x601f, 0x0007, 0x6017, 0x0398, 0x012e, 0x00ee, 0x0005,
+ 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x1410, 0x000b, 0x0005, 0x7b3f,
+ 0x7b3f, 0x7b3f, 0x7b3f, 0x7b3f, 0x7b3f, 0x7b3f, 0x7b3f, 0x7b3f,
+ 0x7a01, 0x7b3f, 0x7a02, 0x7b41, 0x7a02, 0x7b4a, 0x7b3f, 0x080c,
+ 0x1410, 0x6007, 0x008b, 0x6003, 0x000d, 0x080c, 0x589c, 0x080c,
+ 0x5d10, 0x0005, 0x080c, 0x7d30, 0x080c, 0x7b8f, 0x0568, 0x080c,
+ 0x2563, 0x00d6, 0x04e1, 0x0168, 0x6010, 0x2068, 0x6837, 0x0103,
+ 0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x080c,
+ 0x46a1, 0x2c68, 0x080c, 0x6cc2, 0x0140, 0x6818, 0x601a, 0x00c6,
+ 0x2d60, 0x080c, 0x7d3c, 0x00ce, 0x0008, 0x2d60, 0x00de, 0x6013,
+ 0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
+ 0x58e2, 0x080c, 0x5d10, 0x0010, 0x080c, 0x7d3c, 0x0005, 0xa284,
+ 0x0003, 0x1158, 0xa282, 0x9200, 0x0240, 0x2001, 0x8b16, 0x2004,
+ 0xa202, 0x1218, 0xa085, 0x0001, 0x0005, 0xa006, 0x0ce8, 0x0026,
+ 0x6210, 0x82ff, 0x002e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006,
+ 0x0126, 0x2091, 0x8000, 0x2061, 0x9200, 0x2071, 0x8b00, 0x7344,
+ 0x7064, 0xa302, 0x1290, 0x601c, 0xa206, 0x1148, 0x080c, 0x7d69,
+ 0x1110, 0x080c, 0x6fb6, 0x00c6, 0x080c, 0x6d18, 0x00ce, 0xace0,
+ 0x000c, 0x7058, 0xac02, 0x1208, 0x0c50, 0x012e, 0x000e, 0x003e,
+ 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0xa188, 0x8c34,
+ 0x210c, 0x81ff, 0x0170, 0x2061, 0x9200, 0x2071, 0x8b00, 0x0016,
+ 0x080c, 0x6cc2, 0x001e, 0x0138, 0x611a, 0x080c, 0x2563, 0x080c,
+ 0x6d18, 0xa006, 0x0010, 0xa085, 0x0001, 0x001e, 0x00ce, 0x00ee,
+ 0x0005, 0x00c6, 0x0056, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c,
+ 0x6cc2, 0x005e, 0x0170, 0x6612, 0x651a, 0x601f, 0x0003, 0x2009,
+ 0x004b, 0x080c, 0x6d3f, 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce,
0x0005, 0xa006, 0x0cd0, 0x00c6, 0x0056, 0x0126, 0x2091, 0x8000,
- 0x62a0, 0x00c6, 0x080c, 0x749c, 0x005e, 0x0500, 0x6612, 0x651a,
- 0x601f, 0x0003, 0x2019, 0x0005, 0x00c6, 0x2560, 0x080c, 0x460d,
- 0x00ce, 0x080c, 0x6127, 0x0086, 0x2041, 0x0000, 0x080c, 0x606d,
- 0x2c08, 0x080c, 0x8ee4, 0x008e, 0x2009, 0x004e, 0x080c, 0x7518,
- 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0,
- 0x00c6, 0x0096, 0x0086, 0x0056, 0x0126, 0x2091, 0x8000, 0x62a0,
- 0x00c6, 0x080c, 0x749c, 0x005e, 0x0904, 0x8426, 0x6612, 0x651a,
- 0x601f, 0x0003, 0x00c6, 0x2560, 0x080c, 0x45af, 0x0118, 0x2001,
- 0x83ec, 0x0028, 0x080c, 0x4581, 0x0160, 0x2001, 0x83f2, 0x0006,
- 0xa00e, 0x2001, 0x0004, 0x080c, 0x492c, 0x080c, 0x4809, 0x000e,
- 0x0807, 0x2019, 0x0004, 0x080c, 0x632b, 0x0036, 0x003e, 0x00ce,
- 0x2041, 0x0001, 0x2608, 0x080c, 0x6140, 0x080c, 0x606d, 0x2c08,
- 0x2648, 0x080c, 0x8ee4, 0x6018, 0xa080, 0x000f, 0x200c, 0x81ff,
- 0x090c, 0x61d3, 0x2009, 0x0052, 0x080c, 0x7518, 0xa085, 0x0001,
- 0x012e, 0x005e, 0x008e, 0x009e, 0x00ce, 0x0005, 0xa006, 0x0cc0,
- 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x749c, 0x001e,
- 0x0178, 0x660a, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009,
- 0x001f, 0x080c, 0x7518, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005,
- 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c,
- 0x749c, 0x001e, 0x0178, 0x660a, 0x611a, 0x601f, 0x0008, 0x2d00,
- 0x6012, 0x2009, 0x0021, 0x080c, 0x7518, 0xa085, 0x0001, 0x012e,
- 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000,
- 0x00c6, 0x080c, 0x749c, 0x001e, 0x0178, 0x660a, 0x611a, 0x601f,
- 0x0001, 0x2d00, 0x6012, 0x2009, 0x003d, 0x080c, 0x7518, 0xa085,
- 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126,
- 0x2091, 0x8000, 0x00c6, 0x080c, 0x749c, 0x001e, 0x0170, 0x611a,
- 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x080c, 0x7518,
- 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x0026,
- 0x00d6, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0110, 0x8211, 0x6a3e,
- 0x00de, 0x002e, 0x0005, 0x0006, 0x6013, 0x0000, 0x601f, 0x0007,
- 0x2001, 0x94dd, 0x2004, 0x6016, 0x000e, 0x0005, 0x0066, 0x00c6,
- 0x00d6, 0x2031, 0x9252, 0x2634, 0xd6e4, 0x0128, 0x6618, 0x2660,
- 0x6e48, 0x080c, 0x453a, 0x00de, 0x00ce, 0x006e, 0x0005, 0x0006,
- 0x0016, 0x6004, 0xa08e, 0x0002, 0x0140, 0xa08e, 0x0003, 0x0128,
- 0xa08e, 0x0004, 0x0110, 0xa085, 0x0001, 0x001e, 0x000e, 0x0005,
- 0x0006, 0x00d6, 0x6010, 0xa06d, 0x0128, 0x6838, 0xd0fc, 0x0110,
- 0xa006, 0x0010, 0xa085, 0x0001, 0x00de, 0x000e, 0x0005, 0x00c6,
- 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x749c, 0x001e, 0x0180,
- 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x080c, 0x266c, 0x2009,
- 0x0028, 0x080c, 0x7518, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005,
- 0xa006, 0x0cd8, 0xa186, 0x0015, 0x1178, 0x2011, 0x9220, 0x2204,
- 0xa086, 0x0074, 0x1148, 0x080c, 0x7a64, 0x6003, 0x0001, 0x6007,
- 0x0029, 0x080c, 0x603e, 0x0020, 0x080c, 0x7776, 0x080c, 0x74f2,
- 0x0005, 0xa186, 0x0015, 0x11b0, 0x2011, 0x9220, 0x2204, 0xa086,
- 0x0014, 0x1180, 0x00d6, 0x6018, 0x2068, 0x080c, 0x44c7, 0x00de,
- 0x080c, 0x7a6e, 0x1138, 0x2001, 0x0006, 0x080c, 0x43e3, 0x080c,
- 0x7598, 0x0020, 0x080c, 0x7776, 0x080c, 0x74f2, 0x0005, 0x6848,
- 0xa086, 0x0005, 0x1108, 0x0009, 0x0005, 0x6850, 0xc0ad, 0x6852,
- 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x2001, 0x94d9, 0x200c,
- 0x8000, 0x2014, 0x2001, 0x0064, 0x080c, 0x5eaf, 0x2001, 0x94dd,
- 0x82ff, 0x1110, 0x2011, 0x0002, 0x2202, 0x003e, 0x002e, 0x001e,
- 0x000e, 0x0005, 0x0006, 0x2001, 0x94dd, 0x2003, 0x0028, 0x2001,
- 0x94de, 0x2003, 0x07d0, 0x000e, 0x0005, 0x0066, 0x6000, 0xa0b2,
- 0x0010, 0x1a0c, 0x13fe, 0x0013, 0x006e, 0x0005, 0x856e, 0x881c,
- 0x8907, 0x856e, 0x856e, 0x856e, 0x856e, 0x856e, 0x85a6, 0x8973,
- 0x856e, 0x856e, 0x856e, 0x856e, 0x856e, 0x856e, 0x080c, 0x13fe,
- 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x13fe, 0x0013, 0x006e,
- 0x0005, 0x8589, 0x8ce9, 0x8589, 0x8589, 0x8589, 0x8589, 0x8589,
- 0x8589, 0x8cad, 0x8d31, 0x8589, 0x9105, 0x9135, 0x9105, 0x9135,
- 0x8589, 0x080c, 0x13fe, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c,
- 0x13fe, 0x0013, 0x006e, 0x0005, 0x85a4, 0x8ab9, 0x8b64, 0x8b88,
- 0x8bd3, 0x85a4, 0x85a4, 0x8c44, 0x897f, 0x8c87, 0x8c9a, 0x85a4,
- 0x85a4, 0x85a4, 0x85a4, 0x85a4, 0x080c, 0x13fe, 0xa1b2, 0x003e,
- 0x1a0c, 0x13fe, 0x2100, 0x0002, 0x85df, 0x86f0, 0x85df, 0x85df,
- 0x85df, 0x86f7, 0x85df, 0x85df, 0x85df, 0x85df, 0x85df, 0x85df,
- 0x85df, 0x85df, 0x85df, 0x85df, 0x85df, 0x85df, 0x85df, 0x85df,
- 0x85df, 0x85df, 0x85df, 0x85e1, 0x860b, 0x8616, 0x865a, 0x8674,
- 0x86aa, 0x86dd, 0x85df, 0x85df, 0x86fa, 0x85df, 0x85df, 0x8709,
- 0x8710, 0x85df, 0x85df, 0x85df, 0x85df, 0x85df, 0x87ab, 0x85df,
- 0x85df, 0x87b5, 0x85df, 0x85df, 0x875d, 0x85df, 0x85df, 0x080c,
- 0x13fe, 0x080c, 0x470e, 0x6618, 0x00c6, 0x2660, 0x080c, 0x4443,
- 0x00ce, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006,
- 0x0278, 0x080c, 0x8e28, 0x1904, 0x8654, 0x080c, 0x8dd3, 0x1120,
- 0x6007, 0x0008, 0x0804, 0x86eb, 0x6007, 0x0009, 0x0804, 0x86eb,
- 0x080c, 0x8fa4, 0x0128, 0x080c, 0x8e28, 0x0d78, 0x0804, 0x8654,
- 0x6013, 0x1900, 0x0c88, 0x6106, 0x080c, 0x8d83, 0x6007, 0x0006,
- 0x0804, 0x86eb, 0x6007, 0x0007, 0x0804, 0x86eb, 0x080c, 0x9150,
- 0x1904, 0x87c6, 0x00d6, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00,
- 0x8637, 0xa686, 0x0006, 0x01a0, 0xa686, 0x0004, 0x0188, 0x080c,
- 0x4dc5, 0x1160, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006, 0x0140,
- 0xa686, 0x0004, 0x0128, 0xa686, 0x0005, 0x0110, 0x00de, 0x00e0,
- 0x080c, 0x8e86, 0x11a0, 0xa686, 0x0006, 0x1150, 0x0026, 0x6218,
- 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x26b1, 0x002e,
- 0x080c, 0x44c7, 0x6007, 0x000a, 0x00de, 0x0804, 0x86eb, 0x6007,
- 0x000b, 0x00de, 0x0804, 0x86eb, 0x080c, 0x266c, 0x6007, 0x0001,
- 0x0804, 0x86eb, 0x080c, 0x9150, 0x1904, 0x87c6, 0x6618, 0x00d6,
- 0x2668, 0x6e04, 0x00de, 0xa686, 0x0707, 0x0d70, 0x0026, 0x6218,
- 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x26b1, 0x002e,
- 0x6007, 0x000c, 0x0804, 0x86eb, 0x080c, 0x470e, 0x6618, 0xa6b0,
- 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x02b0, 0xa6b4,
- 0xff00, 0x8637, 0xa686, 0x0004, 0x0118, 0xa686, 0x0006, 0x1960,
- 0x080c, 0x8e93, 0x1120, 0x6007, 0x000e, 0x0804, 0x86eb, 0x080c,
- 0x266c, 0x6007, 0x000f, 0x0804, 0x86eb, 0x080c, 0x8fa4, 0x0160,
- 0xa6b4, 0xff00, 0x8637, 0xa682, 0x0004, 0x0a04, 0x8654, 0xa682,
- 0x0007, 0x0e30, 0x0804, 0x8654, 0x6013, 0x1900, 0x6007, 0x0009,
- 0x0804, 0x86eb, 0x080c, 0x470e, 0x6618, 0xa6b0, 0x0001, 0x2634,
- 0xa684, 0x00ff, 0xa082, 0x0006, 0x02c0, 0xa6b4, 0xff00, 0x8637,
- 0xa686, 0x0004, 0x0120, 0xa686, 0x0006, 0x1904, 0x8654, 0x080c,
- 0x8ebb, 0x1130, 0x080c, 0x8dd3, 0x1118, 0x6007, 0x0010, 0x0418,
- 0x080c, 0x266c, 0x6007, 0x0011, 0x00f0, 0x080c, 0x8fa4, 0x0140,
- 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0d48, 0x0804, 0x8654,
- 0x6013, 0x1900, 0x6007, 0x0009, 0x0070, 0x7030, 0xa086, 0x6000,
- 0x0140, 0x080c, 0x9150, 0x1904, 0x87c6, 0x080c, 0x87c9, 0x1904,
- 0x8654, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x603e, 0x0005,
- 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x603e, 0x0cc0, 0x6007,
- 0x0005, 0x0cc0, 0x080c, 0x9150, 0x1904, 0x87c6, 0x080c, 0x87c9,
- 0x1904, 0x8654, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x603e,
- 0x0005, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x603e, 0x0005,
- 0x080c, 0x9150, 0x1904, 0x87c6, 0x080c, 0x87c9, 0x1904, 0x8654,
- 0x0016, 0x0026, 0x2011, 0x9791, 0x2214, 0xa286, 0xffff, 0x0190,
- 0x2c08, 0x080c, 0x82de, 0x01d8, 0x2260, 0x2011, 0x9790, 0x2214,
- 0x6008, 0xa206, 0x11a0, 0x6018, 0xa190, 0x0006, 0x2214, 0xa206,
- 0x01e0, 0x0068, 0x2011, 0x9790, 0x2214, 0x2c08, 0x080c, 0x90ab,
- 0x11a0, 0x2011, 0x9791, 0x2214, 0xa286, 0xffff, 0x01a0, 0x2160,
- 0x6007, 0x0026, 0x6013, 0x1700, 0x2011, 0x9789, 0x2214, 0xa296,
- 0xffff, 0x1160, 0x6007, 0x0025, 0x0048, 0x601c, 0xa086, 0x0007,
- 0x1d70, 0x080c, 0x74f2, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001,
- 0x080c, 0x603e, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c,
- 0x43d1, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019,
- 0x9205, 0x2011, 0x9796, 0x080c, 0x7aee, 0x003e, 0x002e, 0x001e,
- 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0x86eb, 0x080c, 0x7910,
- 0x080c, 0x4dc5, 0x1578, 0x0006, 0x0026, 0x0036, 0x2011, 0x9223,
- 0x2204, 0x8000, 0x2012, 0xa084, 0x0007, 0x0190, 0x2001, 0x94d7,
- 0x2003, 0xaaaa, 0x2001, 0x94d8, 0x2003, 0x0001, 0x2001, 0x9200,
- 0x2003, 0x0001, 0x080c, 0x4d10, 0x003e, 0x002e, 0x000e, 0x0005,
- 0x2001, 0x0001, 0x080c, 0x23ba, 0x080c, 0x4dd7, 0x1110, 0x080c,
- 0x4d9a, 0x2011, 0x8036, 0x2019, 0x0005, 0x080c, 0x3698, 0x003e,
- 0x002e, 0x000e, 0x0005, 0x6106, 0x0479, 0x6007, 0x002b, 0x0804,
- 0x86eb, 0x6007, 0x002c, 0x0804, 0x86eb, 0x080c, 0x9150, 0x1170,
- 0x0081, 0x1904, 0x8654, 0x6106, 0x0419, 0x1120, 0x6007, 0x002e,
- 0x0804, 0x86eb, 0x6007, 0x002f, 0x0804, 0x86eb, 0x080c, 0x74f2,
- 0x0005, 0x00d6, 0x0066, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00,
- 0x8637, 0xa686, 0x0006, 0x0128, 0xa686, 0x0004, 0x0110, 0xa085,
- 0x0001, 0x006e, 0x00de, 0x0005, 0x00d6, 0x0439, 0x00de, 0x0005,
- 0x00d6, 0x0481, 0x11e0, 0x680c, 0xa08c, 0xff00, 0x6824, 0xa084,
- 0x00ff, 0xa115, 0x6212, 0xd1e4, 0x0118, 0x2009, 0x0001, 0x0060,
- 0xd1ec, 0x0168, 0x6920, 0xa18c, 0x00ff, 0x6824, 0x080c, 0x240b,
- 0x1130, 0x2110, 0x2009, 0x0000, 0x080c, 0x26b1, 0x0018, 0xa085,
- 0x0001, 0x0008, 0xa006, 0x00de, 0x0005, 0x2069, 0x978d, 0x6800,
- 0xa082, 0x0010, 0x1228, 0x6013, 0x0000, 0xa085, 0x0001, 0x0008,
- 0xa006, 0x0005, 0x6013, 0x0000, 0x2069, 0x978c, 0x6808, 0xa084,
- 0xff00, 0xa086, 0x0800, 0x0005, 0x6004, 0xa0b2, 0x003e, 0x1a0c,
- 0x13fe, 0xa1b6, 0x0013, 0x1110, 0x2008, 0x0092, 0xa1b6, 0x0027,
- 0x0120, 0xa1b6, 0x0014, 0x190c, 0x13fe, 0x2001, 0x0007, 0x080c,
- 0x43f1, 0x080c, 0x6389, 0x080c, 0x849b, 0x080c, 0x6462, 0x0005,
- 0x8875, 0x8877, 0x8875, 0x8875, 0x8875, 0x8877, 0x8885, 0x88e7,
- 0x88b2, 0x88e7, 0x88c3, 0x88e7, 0x8885, 0x88e7, 0x88df, 0x88e7,
- 0x88df, 0x88e7, 0x88e7, 0x8875, 0x8875, 0x8875, 0x8875, 0x8875,
- 0x8875, 0x8875, 0x8875, 0x8875, 0x8875, 0x8875, 0x8875, 0x8875,
- 0x88e7, 0x8875, 0x8875, 0x88e7, 0x8875, 0x88e7, 0x88e7, 0x8875,
- 0x8875, 0x8875, 0x8875, 0x88e7, 0x88e7, 0x8875, 0x88e7, 0x88e7,
- 0x8875, 0x887f, 0x8875, 0x8875, 0x8875, 0x8875, 0x8875, 0x8875,
- 0x8875, 0x8875, 0x8875, 0x8875, 0x8875, 0x080c, 0x13fe, 0x080c,
- 0x6389, 0x6003, 0x0002, 0x080c, 0x6462, 0x0804, 0x88ed, 0x2001,
- 0x0000, 0x080c, 0x43d1, 0x0804, 0x88e7, 0x00f6, 0x2079, 0x9251,
- 0x7804, 0x00fe, 0xd0ac, 0x1904, 0x88e7, 0x2001, 0x0000, 0x080c,
- 0x43d1, 0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x0904,
- 0x88e7, 0x2001, 0x0002, 0x080c, 0x43e3, 0x080c, 0x6389, 0x601f,
- 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x603e, 0x080c,
- 0x6462, 0x00c6, 0x6118, 0x2160, 0x2009, 0x0001, 0x080c, 0x573d,
- 0x00ce, 0x04d8, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa6b4,
- 0xff00, 0x8637, 0xa686, 0x0006, 0x0550, 0xa686, 0x0004, 0x0538,
- 0x2001, 0x0004, 0x0410, 0x2001, 0x9200, 0x2004, 0xa086, 0x0003,
- 0x1110, 0x080c, 0x370a, 0x2001, 0x0006, 0x0401, 0x6618, 0x00d6,
+ 0x62a0, 0x00c6, 0x080c, 0x6cc2, 0x005e, 0x01f8, 0x6013, 0x0000,
+ 0x651a, 0x601f, 0x0003, 0x00c6, 0x2560, 0x080c, 0x44e6, 0x00ce,
+ 0x080c, 0x59d5, 0x0086, 0x2041, 0x0000, 0x080c, 0x5911, 0x2c08,
+ 0x080c, 0x878f, 0x008e, 0x2009, 0x004c, 0x080c, 0x6d3f, 0xa085,
+ 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00c6,
+ 0x0056, 0x0126, 0x2091, 0x8000, 0x62a0, 0x00c6, 0x080c, 0x6cc2,
+ 0x005e, 0x0500, 0x6612, 0x651a, 0x601f, 0x0003, 0x2019, 0x0005,
+ 0x00c6, 0x2560, 0x080c, 0x44e6, 0x00ce, 0x080c, 0x59d5, 0x0086,
+ 0x2041, 0x0000, 0x080c, 0x5911, 0x2c08, 0x080c, 0x878f, 0x008e,
+ 0x2009, 0x004d, 0x080c, 0x6d3f, 0xa085, 0x0001, 0x012e, 0x005e,
+ 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00c6, 0x0056, 0x0126, 0x2091,
+ 0x8000, 0x62a0, 0x00c6, 0x080c, 0x6cc2, 0x005e, 0x0500, 0x6612,
+ 0x651a, 0x601f, 0x0003, 0x2019, 0x0005, 0x00c6, 0x2560, 0x080c,
+ 0x44e6, 0x00ce, 0x080c, 0x59d5, 0x0086, 0x2041, 0x0000, 0x080c,
+ 0x5911, 0x2c08, 0x080c, 0x878f, 0x008e, 0x2009, 0x004e, 0x080c,
+ 0x6d3f, 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006,
+ 0x0cd0, 0x00c6, 0x0096, 0x0086, 0x0056, 0x0126, 0x2091, 0x8000,
+ 0x62a0, 0x00c6, 0x080c, 0x6cc2, 0x005e, 0x0904, 0x7cc7, 0x6612,
+ 0x651a, 0x601f, 0x0003, 0x00c6, 0x2560, 0x080c, 0x4488, 0x0118,
+ 0x2001, 0x7c8d, 0x0028, 0x080c, 0x445a, 0x0160, 0x2001, 0x7c93,
+ 0x0006, 0xa00e, 0x2001, 0x0004, 0x080c, 0x4773, 0x080c, 0x46a1,
+ 0x000e, 0x0807, 0x2019, 0x0004, 0x080c, 0x5bd9, 0x0036, 0x003e,
+ 0x00ce, 0x2041, 0x0001, 0x2608, 0x080c, 0x59ee, 0x080c, 0x5911,
+ 0x2c08, 0x2648, 0x080c, 0x878f, 0x6018, 0xa080, 0x000f, 0x200c,
+ 0x81ff, 0x090c, 0x5a81, 0x2009, 0x0052, 0x080c, 0x6d3f, 0xa085,
+ 0x0001, 0x012e, 0x005e, 0x008e, 0x009e, 0x00ce, 0x0005, 0xa006,
+ 0x0cc0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x6cc2,
+ 0x001e, 0x0178, 0x660a, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012,
+ 0x2009, 0x001f, 0x080c, 0x6d3f, 0xa085, 0x0001, 0x012e, 0x00ce,
+ 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6,
+ 0x080c, 0x6cc2, 0x001e, 0x0178, 0x660a, 0x611a, 0x601f, 0x0008,
+ 0x2d00, 0x6012, 0x2009, 0x0021, 0x080c, 0x6d3f, 0xa085, 0x0001,
+ 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091,
+ 0x8000, 0x00c6, 0x080c, 0x6cc2, 0x001e, 0x0178, 0x660a, 0x611a,
+ 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x003d, 0x080c, 0x6d3f,
+ 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6,
+ 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x6cc2, 0x001e, 0x0170,
+ 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x080c,
+ 0x6d3f, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8,
+ 0x0026, 0x00d6, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0110, 0x8211,
+ 0x6a3e, 0x00de, 0x002e, 0x0005, 0x0006, 0x6013, 0x0000, 0x601f,
+ 0x0007, 0x2001, 0x8da2, 0x2004, 0x6016, 0x000e, 0x0005, 0x0066,
+ 0x00c6, 0x00d6, 0x2031, 0x8b52, 0x2634, 0xd6e4, 0x0128, 0x6618,
+ 0x2660, 0x6e48, 0x080c, 0x4413, 0x00de, 0x00ce, 0x006e, 0x0005,
+ 0x0006, 0x0016, 0x6004, 0xa08e, 0x0002, 0x0140, 0xa08e, 0x0003,
+ 0x0128, 0xa08e, 0x0004, 0x0110, 0xa085, 0x0001, 0x001e, 0x000e,
+ 0x0005, 0x0006, 0x00d6, 0x6010, 0xa06d, 0x0128, 0x6838, 0xd0fc,
+ 0x0110, 0xa006, 0x0010, 0xa085, 0x0001, 0x00de, 0x000e, 0x0005,
+ 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x6cc2, 0x001e,
+ 0x0180, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x080c, 0x2563,
+ 0x2009, 0x0028, 0x080c, 0x6d3f, 0xa085, 0x0001, 0x012e, 0x00ce,
+ 0x0005, 0xa006, 0x0cd8, 0xa186, 0x0015, 0x1178, 0x2011, 0x8b20,
+ 0x2204, 0xa086, 0x0074, 0x1148, 0x080c, 0x72a4, 0x6003, 0x0001,
+ 0x6007, 0x0029, 0x080c, 0x58e2, 0x0020, 0x080c, 0x6fb6, 0x080c,
+ 0x6d18, 0x0005, 0xa186, 0x0015, 0x11b0, 0x2011, 0x8b20, 0x2204,
+ 0xa086, 0x0014, 0x1180, 0x00d6, 0x6018, 0x2068, 0x080c, 0x43a0,
+ 0x00de, 0x080c, 0x72ae, 0x1138, 0x2001, 0x0006, 0x080c, 0x42b9,
+ 0x080c, 0x6dc7, 0x0020, 0x080c, 0x6fb6, 0x080c, 0x6d18, 0x0005,
+ 0x6848, 0xa086, 0x0005, 0x1108, 0x0009, 0x0005, 0x6850, 0xc0ad,
+ 0x6852, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x2001, 0x8d9e,
+ 0x200c, 0x8000, 0x2014, 0x2001, 0x0064, 0x080c, 0x575a, 0x2001,
+ 0x8da2, 0x82ff, 0x1110, 0x2011, 0x0002, 0x2202, 0x003e, 0x002e,
+ 0x001e, 0x000e, 0x0005, 0x0006, 0x2001, 0x8da2, 0x2003, 0x0028,
+ 0x2001, 0x8da3, 0x2003, 0x07d0, 0x000e, 0x0005, 0x00d6, 0x6024,
+ 0xa06d, 0x0110, 0x080c, 0x149f, 0x00de, 0x0005, 0x0066, 0x6000,
+ 0xa0b2, 0x0010, 0x1a0c, 0x1410, 0x0013, 0x006e, 0x0005, 0x7e17,
+ 0x80cf, 0x81c5, 0x7e17, 0x7e17, 0x7e17, 0x7e17, 0x7e17, 0x7e4f,
+ 0x8231, 0x7e17, 0x7e17, 0x7e17, 0x7e17, 0x7e17, 0x7e17, 0x080c,
+ 0x1410, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x1410, 0x0013,
+ 0x006e, 0x0005, 0x7e32, 0x8594, 0x7e32, 0x7e32, 0x7e32, 0x7e32,
+ 0x7e32, 0x7e32, 0x8558, 0x85dc, 0x7e32, 0x89b0, 0x89e0, 0x89b0,
+ 0x89e0, 0x7e32, 0x080c, 0x1410, 0x0066, 0x6000, 0xa0b2, 0x0010,
+ 0x1a0c, 0x1410, 0x0013, 0x006e, 0x0005, 0x7e4d, 0x8364, 0x840f,
+ 0x8433, 0x847e, 0x7e4d, 0x7e4d, 0x84ef, 0x823d, 0x8532, 0x8545,
+ 0x7e4d, 0x7e4d, 0x7e4d, 0x7e4d, 0x7e4d, 0x080c, 0x1410, 0xa1b2,
+ 0x0040, 0x1a0c, 0x1410, 0x2100, 0x0002, 0x7e98, 0x7fa9, 0x7e98,
+ 0x7e98, 0x7e98, 0x7fb0, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98,
+ 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98,
+ 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e9a, 0x7ec4, 0x7ecf, 0x7f13,
+ 0x7f2d, 0x7f63, 0x7f96, 0x7e98, 0x7e98, 0x7fb3, 0x7e98, 0x7e98,
+ 0x7fc2, 0x7fc9, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x805e,
+ 0x7e98, 0x7e98, 0x8068, 0x7e98, 0x7e98, 0x8016, 0x7e98, 0x7e98,
+ 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98,
+ 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98, 0x7e98,
+ 0x080c, 0x1410, 0x080c, 0x45e7, 0x6618, 0x00c6, 0x2660, 0x080c,
+ 0x4319, 0x00ce, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082,
+ 0x0006, 0x0278, 0x080c, 0x86d3, 0x1904, 0x7f0d, 0x080c, 0x867e,
+ 0x1120, 0x6007, 0x0008, 0x0804, 0x7fa4, 0x6007, 0x0009, 0x0804,
+ 0x7fa4, 0x080c, 0x884f, 0x0128, 0x080c, 0x86d3, 0x0d78, 0x0804,
+ 0x7f0d, 0x6013, 0x1900, 0x0c88, 0x6106, 0x080c, 0x862e, 0x6007,
+ 0x0006, 0x0804, 0x7fa4, 0x6007, 0x0007, 0x0804, 0x7fa4, 0x080c,
+ 0x89fb, 0x1904, 0x8079, 0x00d6, 0x6618, 0x2668, 0x6e04, 0xa6b4,
+ 0xff00, 0x8637, 0xa686, 0x0006, 0x01a0, 0xa686, 0x0004, 0x0188,
+ 0x080c, 0x4c42, 0x1160, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006,
+ 0x0140, 0xa686, 0x0004, 0x0128, 0xa686, 0x0005, 0x0110, 0x00de,
+ 0x00e0, 0x080c, 0x8731, 0x11a0, 0xa686, 0x0006, 0x1150, 0x0026,
+ 0x6218, 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x25a8,
+ 0x002e, 0x080c, 0x43a0, 0x6007, 0x000a, 0x00de, 0x0804, 0x7fa4,
+ 0x6007, 0x000b, 0x00de, 0x0804, 0x7fa4, 0x080c, 0x2563, 0x6007,
+ 0x0001, 0x0804, 0x7fa4, 0x080c, 0x89fb, 0x1904, 0x8079, 0x6618,
+ 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa686, 0x0707, 0x0d70, 0x0026,
+ 0x6218, 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x25a8,
+ 0x002e, 0x6007, 0x000c, 0x0804, 0x7fa4, 0x080c, 0x45e7, 0x6618,
+ 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x02b0,
+ 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004, 0x0118, 0xa686, 0x0006,
+ 0x1960, 0x080c, 0x873e, 0x1120, 0x6007, 0x000e, 0x0804, 0x7fa4,
+ 0x080c, 0x2563, 0x6007, 0x000f, 0x0804, 0x7fa4, 0x080c, 0x884f,
+ 0x0160, 0xa6b4, 0xff00, 0x8637, 0xa682, 0x0004, 0x0a04, 0x7f0d,
+ 0xa682, 0x0007, 0x0e30, 0x0804, 0x7f0d, 0x6013, 0x1900, 0x6007,
+ 0x0009, 0x0804, 0x7fa4, 0x080c, 0x45e7, 0x6618, 0xa6b0, 0x0001,
+ 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x02c0, 0xa6b4, 0xff00,
+ 0x8637, 0xa686, 0x0004, 0x0120, 0xa686, 0x0006, 0x1904, 0x7f0d,
+ 0x080c, 0x8766, 0x1130, 0x080c, 0x867e, 0x1118, 0x6007, 0x0010,
+ 0x0418, 0x080c, 0x2563, 0x6007, 0x0011, 0x00f0, 0x080c, 0x884f,
+ 0x0140, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0d48, 0x0804,
+ 0x7f0d, 0x6013, 0x1900, 0x6007, 0x0009, 0x0070, 0x7030, 0xa086,
+ 0x6000, 0x0140, 0x080c, 0x89fb, 0x1904, 0x8079, 0x080c, 0x807c,
+ 0x1904, 0x7f0d, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x58e2,
+ 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x58e2, 0x0cc0,
+ 0x6007, 0x0005, 0x0cc0, 0x080c, 0x89fb, 0x1904, 0x8079, 0x080c,
+ 0x807c, 0x1904, 0x7f0d, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c,
+ 0x58e2, 0x0005, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x58e2,
+ 0x0005, 0x080c, 0x89fb, 0x1904, 0x8079, 0x080c, 0x807c, 0x1904,
+ 0x7f0d, 0x0016, 0x0026, 0x2011, 0x9091, 0x2214, 0xa286, 0xffff,
+ 0x0190, 0x2c08, 0x080c, 0x7b7f, 0x01d8, 0x2260, 0x2011, 0x9090,
+ 0x2214, 0x6008, 0xa206, 0x11a0, 0x6018, 0xa190, 0x0006, 0x2214,
+ 0xa206, 0x01e0, 0x0068, 0x2011, 0x9090, 0x2214, 0x2c08, 0x080c,
+ 0x8956, 0x11a0, 0x2011, 0x9091, 0x2214, 0xa286, 0xffff, 0x01a0,
+ 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x2011, 0x9089, 0x2214,
+ 0xa296, 0xffff, 0x1160, 0x6007, 0x0025, 0x0048, 0x601c, 0xa086,
+ 0x0007, 0x1d70, 0x080c, 0x6d18, 0x2160, 0x6007, 0x0025, 0x6003,
+ 0x0001, 0x080c, 0x58e2, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001,
+ 0x080c, 0x42a7, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004,
+ 0x2019, 0x8b05, 0x2011, 0x9096, 0x080c, 0x7326, 0x003e, 0x002e,
+ 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0x7fa4, 0x080c,
+ 0x715d, 0x080c, 0x4c42, 0x1548, 0x0006, 0x0026, 0x0036, 0x2011,
+ 0x8b23, 0x2204, 0x8000, 0x2012, 0xa084, 0x0007, 0x0190, 0x2001,
+ 0x8d9c, 0x2003, 0xaaaa, 0x2001, 0x8d9d, 0x2003, 0x0001, 0x2001,
+ 0x8b00, 0x2003, 0x0001, 0x080c, 0x4b8b, 0x003e, 0x002e, 0x000e,
+ 0x0005, 0x2001, 0x0001, 0x080c, 0x2298, 0x080c, 0x4c54, 0x1110,
+ 0x080c, 0x4c15, 0x003e, 0x002e, 0x000e, 0x0005, 0x6106, 0x0479,
+ 0x6007, 0x002b, 0x0804, 0x7fa4, 0x6007, 0x002c, 0x0804, 0x7fa4,
+ 0x080c, 0x89fb, 0x1170, 0x0081, 0x1904, 0x7f0d, 0x6106, 0x0419,
+ 0x1120, 0x6007, 0x002e, 0x0804, 0x7fa4, 0x6007, 0x002f, 0x0804,
+ 0x7fa4, 0x080c, 0x6d18, 0x0005, 0x00d6, 0x0066, 0x6618, 0x2668,
+ 0x6e04, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0128, 0xa686,
+ 0x0004, 0x0110, 0xa085, 0x0001, 0x006e, 0x00de, 0x0005, 0x00d6,
+ 0x0439, 0x00de, 0x0005, 0x00d6, 0x0481, 0x11e0, 0x680c, 0xa08c,
+ 0xff00, 0x6824, 0xa084, 0x00ff, 0xa115, 0x6212, 0xd1e4, 0x0118,
+ 0x2009, 0x0001, 0x0060, 0xd1ec, 0x0168, 0x6920, 0xa18c, 0x00ff,
+ 0x6824, 0x080c, 0x22e9, 0x1130, 0x2110, 0x2009, 0x0000, 0x080c,
+ 0x25a8, 0x0018, 0xa085, 0x0001, 0x0008, 0xa006, 0x00de, 0x0005,
+ 0x2069, 0x908d, 0x6800, 0xa082, 0x0010, 0x1228, 0x6013, 0x0000,
+ 0xa085, 0x0001, 0x0008, 0xa006, 0x0005, 0x6013, 0x0000, 0x2069,
+ 0x908c, 0x6808, 0xa084, 0xff00, 0xa086, 0x0800, 0x0005, 0x6004,
+ 0xa0b2, 0x0040, 0x1a0c, 0x1410, 0xa1b6, 0x0013, 0x1110, 0x2008,
+ 0x0092, 0xa1b6, 0x0027, 0x0120, 0xa1b6, 0x0014, 0x190c, 0x1410,
+ 0x2001, 0x0007, 0x080c, 0x42c7, 0x080c, 0x5c37, 0x080c, 0x7d3c,
+ 0x080c, 0x5d10, 0x0005, 0x812b, 0x812d, 0x812b, 0x812b, 0x812b,
+ 0x812d, 0x813b, 0x81a3, 0x816e, 0x81a3, 0x817f, 0x81a3, 0x813b,
+ 0x81a3, 0x819b, 0x81a3, 0x819b, 0x81a3, 0x81a3, 0x812b, 0x812b,
+ 0x812b, 0x812b, 0x812b, 0x812b, 0x812b, 0x812b, 0x812b, 0x812b,
+ 0x812b, 0x812b, 0x812b, 0x81a3, 0x812b, 0x812b, 0x81a3, 0x812b,
+ 0x81a3, 0x81a3, 0x812b, 0x812b, 0x812b, 0x812b, 0x81a3, 0x81a3,
+ 0x812b, 0x81a3, 0x81a3, 0x812b, 0x8135, 0x812b, 0x812b, 0x812b,
+ 0x812b, 0x812b, 0x812b, 0x812b, 0x812b, 0x812b, 0x812b, 0x812b,
+ 0x812b, 0x812b, 0x812b, 0x080c, 0x1410, 0x080c, 0x5c37, 0x6003,
+ 0x0002, 0x080c, 0x5d10, 0x0804, 0x81a9, 0x2001, 0x0000, 0x080c,
+ 0x42a7, 0x0804, 0x81a3, 0x00f6, 0x2079, 0x8b51, 0x7804, 0x00fe,
+ 0xd0ac, 0x1904, 0x81a3, 0x2001, 0x0000, 0x080c, 0x42a7, 0x6018,
+ 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x1138, 0x00f6, 0x2079,
+ 0x8b00, 0x7894, 0x8000, 0x7896, 0x00fe, 0x2001, 0x0002, 0x080c,
+ 0x42b9, 0x080c, 0x5c37, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007,
+ 0x0002, 0x080c, 0x58e2, 0x080c, 0x5d10, 0x00c6, 0x6118, 0x2160,
+ 0x2009, 0x0001, 0x080c, 0x5619, 0x00ce, 0x04d8, 0x6618, 0x00d6,
0x2668, 0x6e04, 0x00de, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006,
- 0x0170, 0x2001, 0x0006, 0x0048, 0x2001, 0x0004, 0x0030, 0x2001,
- 0x0006, 0x0061, 0x0020, 0x0018, 0x0010, 0x080c, 0x43f1, 0x080c,
- 0x6389, 0x080c, 0x74f2, 0x080c, 0x6462, 0x0005, 0x0016, 0x00d6,
- 0x6118, 0x2168, 0x6900, 0xd184, 0x0178, 0x6104, 0xa18e, 0x000a,
- 0x1128, 0x699c, 0xd1a4, 0x1110, 0x2001, 0x0007, 0x2001, 0x0000,
- 0x080c, 0x43d1, 0x080c, 0x2692, 0x00de, 0x001e, 0x0005, 0x00d6,
- 0x6618, 0x2668, 0x6804, 0xa084, 0xff00, 0x8007, 0x00de, 0xa0b2,
- 0x000c, 0x1a0c, 0x13fe, 0xa1b6, 0x0015, 0x1110, 0x003b, 0x0028,
- 0xa1b6, 0x0016, 0x190c, 0x13fe, 0x04eb, 0x0005, 0x7805, 0x7805,
- 0x7805, 0x7805, 0x7805, 0x7805, 0x7805, 0x892a, 0x7805, 0x7805,
- 0x7805, 0x7805, 0x00f6, 0x2079, 0x9251, 0x7804, 0x00fe, 0xd0ac,
- 0x1198, 0x2001, 0x0000, 0x080c, 0x43d1, 0x2001, 0x0002, 0x080c,
- 0x43e3, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
- 0x603e, 0x080c, 0x6462, 0x00a8, 0x2011, 0x9783, 0x2204, 0x8211,
- 0x220c, 0x080c, 0x240b, 0x1168, 0x00c6, 0x080c, 0x4434, 0x0120,
- 0x00ce, 0x080c, 0x74f2, 0x0028, 0x080c, 0x41e0, 0x00ce, 0x080c,
- 0x74f2, 0x0005, 0x7805, 0x7805, 0x7805, 0x7805, 0x7805, 0x7805,
- 0x7805, 0x8966, 0x7805, 0x7805, 0x7805, 0x7805, 0x080c, 0x7a61,
- 0x1138, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x603e, 0x0010,
- 0x080c, 0x74f2, 0x0005, 0x6004, 0xa08a, 0x003e, 0x1a0c, 0x13fe,
- 0x080c, 0x6389, 0x080c, 0x849b, 0x080c, 0x6462, 0x0005, 0xa182,
- 0x0040, 0x0002, 0x8995, 0x8995, 0x8995, 0x8995, 0x8997, 0x8995,
- 0x8995, 0x8995, 0x8995, 0x8995, 0x8995, 0x8995, 0x8995, 0x8995,
- 0x8995, 0x8995, 0x8995, 0x8995, 0x8995, 0x080c, 0x13fe, 0x00d6,
- 0x00e6, 0x00f6, 0x0156, 0x0046, 0x0026, 0x6106, 0x2071, 0x9780,
- 0x7444, 0xa4a4, 0xf600, 0x0904, 0x8a0d, 0xa486, 0x2000, 0x01f0,
- 0xa486, 0x0400, 0x01d8, 0xa486, 0x1000, 0x0178, 0xa486, 0x4000,
- 0x01d8, 0xa486, 0x0200, 0x0120, 0x080c, 0x74f2, 0x0804, 0x8a67,
- 0x6118, 0x2104, 0xc0fd, 0x200a, 0x0078, 0x2069, 0x9566, 0x6a00,
- 0xd284, 0x0904, 0x8a79, 0xc2cd, 0x6a02, 0x0030, 0x2009, 0x0001,
- 0x2011, 0x0200, 0x080c, 0x585b, 0x080c, 0x147c, 0x090c, 0x13fe,
+ 0x0550, 0xa686, 0x0004, 0x0538, 0x2001, 0x0004, 0x0410, 0x2001,
+ 0x8b00, 0x2004, 0xa086, 0x0003, 0x1110, 0x080c, 0x3689, 0x2001,
+ 0x0006, 0x0401, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa6b4,
+ 0xff00, 0x8637, 0xa686, 0x0006, 0x0170, 0x2001, 0x0006, 0x0048,
+ 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0061, 0x0020, 0x0018,
+ 0x0010, 0x080c, 0x42c7, 0x080c, 0x5c37, 0x080c, 0x6d18, 0x080c,
+ 0x5d10, 0x0005, 0x0016, 0x00d6, 0x6118, 0x2168, 0x6900, 0xd184,
+ 0x0188, 0x6104, 0xa18e, 0x000a, 0x1128, 0x699c, 0xd1a4, 0x1110,
+ 0x2001, 0x0007, 0x080c, 0x42b9, 0x2001, 0x0000, 0x080c, 0x42a7,
+ 0x080c, 0x2589, 0x00de, 0x001e, 0x0005, 0x00d6, 0x6618, 0x2668,
+ 0x6804, 0xa084, 0xff00, 0x8007, 0x00de, 0xa0b2, 0x000c, 0x1a0c,
+ 0x1410, 0xa1b6, 0x0015, 0x1110, 0x003b, 0x0028, 0xa1b6, 0x0016,
+ 0x190c, 0x1410, 0x04eb, 0x0005, 0x7045, 0x7045, 0x7045, 0x7045,
+ 0x7045, 0x7045, 0x7045, 0x81e8, 0x7045, 0x7045, 0x7045, 0x7045,
+ 0x00f6, 0x2079, 0x8b51, 0x7804, 0x00fe, 0xd0ac, 0x1198, 0x2001,
+ 0x0000, 0x080c, 0x42a7, 0x2001, 0x0002, 0x080c, 0x42b9, 0x601f,
+ 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x58e2, 0x080c,
+ 0x5d10, 0x00a8, 0x2011, 0x9083, 0x2204, 0x8211, 0x220c, 0x080c,
+ 0x22e9, 0x1168, 0x00c6, 0x080c, 0x430a, 0x0120, 0x00ce, 0x080c,
+ 0x6d18, 0x0028, 0x080c, 0x4118, 0x00ce, 0x080c, 0x6d18, 0x0005,
+ 0x7045, 0x7045, 0x7045, 0x7045, 0x7045, 0x7045, 0x7045, 0x8224,
+ 0x7045, 0x7045, 0x7045, 0x7045, 0x080c, 0x72a1, 0x1138, 0x6003,
+ 0x0001, 0x6007, 0x0001, 0x080c, 0x58e2, 0x0010, 0x080c, 0x6d18,
+ 0x0005, 0x6004, 0xa08a, 0x0040, 0x1a0c, 0x1410, 0x080c, 0x5c37,
+ 0x080c, 0x7d3c, 0x080c, 0x5d10, 0x0005, 0xa182, 0x0040, 0x0002,
+ 0x8253, 0x8253, 0x8253, 0x8253, 0x8255, 0x8253, 0x8253, 0x8253,
+ 0x8253, 0x8253, 0x8253, 0x8253, 0x8253, 0x8253, 0x8253, 0x8253,
+ 0x8253, 0x8253, 0x8253, 0x080c, 0x1410, 0x00d6, 0x00e6, 0x00f6,
+ 0x0156, 0x0046, 0x0026, 0x6106, 0x2071, 0x9080, 0x7444, 0xa4a4,
+ 0xff00, 0x0904, 0x82bd, 0xa486, 0x2000, 0x0180, 0xa486, 0x0400,
+ 0x0168, 0xa486, 0x1000, 0x0108, 0x0078, 0x2069, 0x8e2a, 0x6a00,
+ 0xd284, 0x0904, 0x8324, 0xc2cd, 0x6a02, 0x0030, 0x2009, 0x0001,
+ 0x2011, 0x0200, 0x080c, 0x5734, 0x080c, 0x1488, 0x090c, 0x1410,
0x6003, 0x0007, 0x2d00, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b,
0x0000, 0x6c5a, 0x2c00, 0x685e, 0x6008, 0x68b2, 0x6018, 0x2078,
0x78a0, 0x8007, 0x7130, 0x694a, 0x0016, 0xa084, 0xff00, 0x6846,
- 0x684f, 0x0000, 0x6857, 0x0036, 0x080c, 0x4809, 0x001e, 0xa486,
- 0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0x9071, 0x0804, 0x8a67,
- 0xa486, 0x0400, 0x1130, 0x2019, 0x0002, 0x080c, 0x9033, 0x0804,
- 0x8a67, 0xa486, 0x0200, 0x1110, 0x080c, 0x9020, 0xa486, 0x1000,
- 0x1110, 0x080c, 0x905e, 0x0804, 0x8a67, 0x2069, 0x9566, 0x6a00,
- 0xd284, 0x0904, 0x8ab6, 0xa284, 0x0300, 0x1904, 0x8ab0, 0x6804,
- 0xa005, 0x0904, 0x8aa1, 0x2d78, 0x6003, 0x0007, 0x6018, 0x2004,
- 0xd0fc, 0x1904, 0x8ab0, 0x080c, 0x145f, 0x0904, 0x8a6e, 0x7800,
- 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, 0x6013, 0x0000, 0x6803,
- 0x0000, 0x6837, 0x0116, 0x683b, 0x0000, 0x6008, 0x68b2, 0x2c00,
- 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x6986, 0x6846,
- 0x6853, 0x003d, 0x7244, 0xa294, 0x0003, 0xa286, 0x0002, 0x1118,
- 0x684f, 0x0040, 0x0040, 0xa286, 0x0001, 0x1118, 0x684f, 0x0080,
- 0x0010, 0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, 0x9790, 0xad90,
- 0x0015, 0x200c, 0x810f, 0x2112, 0x8000, 0x8210, 0x1f04, 0x8a59,
- 0x200c, 0x6982, 0x8000, 0x200c, 0x697e, 0x080c, 0x4809, 0x002e,
- 0x004e, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x0005, 0x6013, 0x0100,
- 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x5ff8, 0x080c, 0x6462,
- 0x0c70, 0x2069, 0x9792, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200,
- 0x11a8, 0x2069, 0x9780, 0x686c, 0xa084, 0x00ff, 0x0016, 0x6110,
- 0xa18c, 0x0700, 0xa10d, 0x6112, 0x001e, 0x6003, 0x0001, 0x6007,
- 0x0043, 0x080c, 0x5ff8, 0x080c, 0x6462, 0x0888, 0x6013, 0x0200,
- 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x5ff8, 0x080c, 0x6462,
- 0x0830, 0x6013, 0x0300, 0x0010, 0x6013, 0x0100, 0x6003, 0x0001,
- 0x6007, 0x0041, 0x080c, 0x5ff8, 0x080c, 0x6462, 0x0804, 0x8a67,
- 0x6013, 0x0500, 0x0c98, 0x6013, 0x0600, 0x0818, 0x6013, 0x0200,
- 0x0800, 0xa186, 0x0013, 0x1170, 0x6004, 0xa08a, 0x0040, 0x0a0c,
- 0x13fe, 0xa08a, 0x0053, 0x1a0c, 0x13fe, 0xa082, 0x0040, 0x2008,
- 0x0804, 0x8b24, 0xa186, 0x0047, 0x11b8, 0x2001, 0x0109, 0x2004,
- 0xd084, 0x01f0, 0x0126, 0x2091, 0x2400, 0x0006, 0x0016, 0x0026,
- 0x080c, 0x5ee3, 0x002e, 0x001e, 0x000e, 0x012e, 0x6000, 0xa086,
- 0x0002, 0x1170, 0x0804, 0x8b64, 0xa186, 0x0027, 0x0120, 0xa186,
- 0x0014, 0x190c, 0x13fe, 0x6004, 0xa082, 0x0040, 0x2008, 0x001a,
- 0x080c, 0x7526, 0x0005, 0x8b06, 0x8b08, 0x8b08, 0x8b06, 0x8b06,
- 0x8b06, 0x8b06, 0x8b06, 0x8b06, 0x8b06, 0x8b06, 0x8b06, 0x8b06,
- 0x8b06, 0x8b06, 0x8b06, 0x8b06, 0x8b06, 0x8b06, 0x080c, 0x13fe,
- 0x080c, 0x6389, 0x080c, 0x6462, 0x0036, 0x00d6, 0x6010, 0xa06d,
- 0x0180, 0xad84, 0xf000, 0x0168, 0x2019, 0x0004, 0x080c, 0x9097,
- 0x6013, 0x0000, 0x6014, 0xa005, 0x1110, 0x6017, 0x0014, 0x6003,
- 0x0007, 0x00de, 0x003e, 0x0005, 0x0002, 0x8b38, 0x8b55, 0x8b41,
- 0x8b5e, 0x8b38, 0x8b38, 0x8b38, 0x8b38, 0x8b38, 0x8b38, 0x8b38,
- 0x8b38, 0x8b38, 0x8b38, 0x8b38, 0x8b38, 0x8b38, 0x8b38, 0x8b38,
- 0x080c, 0x13fe, 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400,
- 0x200a, 0x080c, 0x6389, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4,
- 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c, 0x7518, 0x0010,
- 0x6003, 0x0002, 0x080c, 0x6462, 0x0005, 0x080c, 0x6389, 0x080c,
- 0x5836, 0x080c, 0x74f2, 0x080c, 0x6462, 0x0005, 0x080c, 0x6389,
- 0x2009, 0x0041, 0x0804, 0x8c44, 0xa182, 0x0040, 0x0002, 0x8b7a,
- 0x8b7c, 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7d, 0x8b7a,
- 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7a, 0x8b7a,
- 0x8b7a, 0x8b7a, 0x080c, 0x13fe, 0x0005, 0x6003, 0x0004, 0x6110,
- 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x16c6, 0x0005,
- 0xa182, 0x0040, 0x0002, 0x8b9e, 0x8b9e, 0x8b9e, 0x8b9e, 0x8b9e,
- 0x8b9e, 0x8b9e, 0x8b9e, 0x8b9e, 0x8ba0, 0x8bc0, 0x8b9e, 0x8b9e,
- 0x8b9e, 0x8b9e, 0x8bc0, 0x8b9e, 0x8b9e, 0x8b9e, 0x080c, 0x13fe,
- 0x080c, 0x641b, 0x080c, 0x651c, 0x6010, 0x00d6, 0x2068, 0x684c,
- 0xd0fc, 0x0150, 0xa08c, 0x0003, 0xa18e, 0x0002, 0x0158, 0x2009,
- 0x0041, 0x00de, 0x0804, 0x8c44, 0x6003, 0x0007, 0x080c, 0x5836,
- 0x00de, 0x0005, 0x080c, 0x5836, 0x080c, 0x74f2, 0x00de, 0x0cc8,
- 0x0036, 0x080c, 0x641b, 0x080c, 0x651c, 0x6010, 0x00d6, 0x2068,
- 0x2019, 0x0004, 0x080c, 0x9097, 0x080c, 0x849b, 0x6017, 0x0028,
- 0x00de, 0x003e, 0x0005, 0xa186, 0x0013, 0x1150, 0x6004, 0xa086,
- 0x0042, 0x190c, 0x13fe, 0x080c, 0x6389, 0x080c, 0x6462, 0x0005,
- 0xa186, 0x0027, 0x0118, 0xa186, 0x0014, 0x1180, 0x6004, 0xa086,
- 0x0042, 0x190c, 0x13fe, 0x2001, 0x0007, 0x080c, 0x43f1, 0x080c,
- 0x6389, 0x080c, 0x849b, 0x080c, 0x6462, 0x0005, 0xa182, 0x0040,
- 0x0002, 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c,
- 0x8c0e, 0x8c1a, 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c,
- 0x8c0c, 0x8c0c, 0x8c0c, 0x8c0c, 0x080c, 0x13fe, 0x0036, 0x0046,
- 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x16c6, 0x004e,
- 0x003e, 0x0005, 0x6010, 0x00d6, 0x2068, 0x6810, 0x6a14, 0xa20d,
- 0x1168, 0x684c, 0xd0fc, 0x0120, 0x2009, 0x0041, 0x00de, 0x00e0,
- 0x6003, 0x0007, 0x080c, 0x5836, 0x00de, 0x0005, 0x6003, 0x0007,
- 0x0021, 0x080c, 0x5838, 0x00de, 0x0005, 0xd2fc, 0x0140, 0x8002,
- 0x8000, 0x8212, 0xa291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009,
- 0x0015, 0x6a6a, 0x6866, 0x0005, 0xa182, 0x0040, 0x0002, 0x8c5a,
- 0x8c5c, 0x8c68, 0x8c74, 0x8c5a, 0x8c5a, 0x8c5a, 0x8c83, 0x8c5a,
- 0x8c5a, 0x8c5a, 0x8c5a, 0x8c5a, 0x8c5a, 0x8c5a, 0x8c5a, 0x8c5a,
- 0x8c5a, 0x8c5a, 0x080c, 0x13fe, 0x6003, 0x0001, 0x6106, 0x080c,
- 0x5ff8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6462, 0x012e, 0x0005,
- 0x6003, 0x0001, 0x6106, 0x080c, 0x5ff8, 0x0126, 0x2091, 0x8000,
- 0x080c, 0x6462, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10,
- 0x080c, 0x1c88, 0x0126, 0x2091, 0x8000, 0x080c, 0x605b, 0x080c,
- 0x651c, 0x012e, 0x0005, 0xa016, 0x080c, 0x16c6, 0x0005, 0x080c,
- 0x6389, 0x6110, 0x81ff, 0x0148, 0x00d6, 0x2168, 0x0036, 0x2019,
- 0x0029, 0x080c, 0x9097, 0x003e, 0x00de, 0x080c, 0x849b, 0x080c,
- 0x6462, 0x0005, 0x080c, 0x641b, 0x6110, 0x81ff, 0x0148, 0x00d6,
- 0x2168, 0x0036, 0x2019, 0x0029, 0x080c, 0x9097, 0x003e, 0x00de,
- 0x080c, 0x849b, 0x080c, 0x651c, 0x0005, 0xa182, 0x0085, 0x0002,
- 0x8cb9, 0x8cb7, 0x8cb7, 0x8cc5, 0x8cb7, 0x8cb7, 0x8cb7, 0x080c,
- 0x13fe, 0x6003, 0x000b, 0x6106, 0x080c, 0x5ff8, 0x0126, 0x2091,
- 0x8000, 0x080c, 0x6462, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c,
- 0x9150, 0x0118, 0x080c, 0x74f2, 0x00c8, 0x2071, 0x9780, 0x7224,
- 0x6212, 0x7220, 0x080c, 0x8f71, 0x0118, 0x6007, 0x0086, 0x0040,
- 0x6007, 0x0087, 0x7224, 0xa296, 0xffff, 0x1110, 0x6007, 0x0086,
- 0x6003, 0x0001, 0x080c, 0x5ff8, 0x080c, 0x6462, 0x00ee, 0x002e,
- 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a, 0x0085, 0x0a0c,
- 0x13fe, 0xa08a, 0x008c, 0x1a0c, 0x13fe, 0xa082, 0x0085, 0x00a2,
- 0xa186, 0x0027, 0x0130, 0xa186, 0x0014, 0x0118, 0x080c, 0x7526,
- 0x0050, 0x2001, 0x0007, 0x080c, 0x43f1, 0x080c, 0x6389, 0x080c,
- 0x849b, 0x080c, 0x6462, 0x0005, 0x8d13, 0x8d15, 0x8d15, 0x8d13,
- 0x8d13, 0x8d13, 0x8d13, 0x080c, 0x13fe, 0x080c, 0x6389, 0x080c,
- 0x74f2, 0x080c, 0x6462, 0x0005, 0xa182, 0x0085, 0x0a0c, 0x13fe,
- 0xa182, 0x008c, 0x1a0c, 0x13fe, 0xa182, 0x0085, 0x0002, 0x8d2e,
- 0x8d2e, 0x8d2e, 0x8d30, 0x8d2e, 0x8d2e, 0x8d2e, 0x080c, 0x13fe,
- 0x0005, 0xa186, 0x0013, 0x0148, 0xa186, 0x0014, 0x0130, 0xa186,
- 0x0027, 0x0118, 0x080c, 0x7526, 0x0030, 0x080c, 0x6389, 0x080c,
- 0x849b, 0x080c, 0x6462, 0x0005, 0x0036, 0x2019, 0x000b, 0x0031,
- 0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036,
- 0x0086, 0x2091, 0x8000, 0x2c40, 0x080c, 0x724a, 0x1540, 0x080c,
- 0x72e2, 0x1528, 0x6000, 0xa086, 0x0000, 0x0508, 0x601c, 0xa086,
- 0x0007, 0x01e8, 0x00d6, 0x6000, 0xa086, 0x0004, 0x1140, 0x601f,
- 0x0007, 0x2001, 0x94dd, 0x2004, 0x6016, 0x080c, 0x1788, 0x6010,
- 0x2068, 0x080c, 0x82ee, 0x0110, 0x080c, 0x9097, 0x00de, 0x6013,
- 0x0000, 0x601f, 0x0007, 0x2001, 0x94dd, 0x2004, 0x6016, 0x008e,
- 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, 0x0036, 0x0156, 0x2079,
- 0x9780, 0x7938, 0x783c, 0x080c, 0x240b, 0x1904, 0x8dce, 0x0016,
- 0x00c6, 0x080c, 0x4434, 0x15c0, 0x2011, 0x9790, 0xac98, 0x000a,
- 0x20a9, 0x0004, 0x080c, 0x7aee, 0x1578, 0x001e, 0x002e, 0x0026,
- 0x0016, 0x2019, 0x0029, 0x080c, 0x73a2, 0x080c, 0x6127, 0x0086,
- 0x2041, 0x0000, 0x080c, 0x606d, 0x008e, 0x001e, 0x0086, 0x2041,
- 0x0000, 0x080c, 0x8ee4, 0x008e, 0x080c, 0x460d, 0x0026, 0x6204,
- 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, 0x0118, 0xa286, 0x0004,
- 0x1118, 0x62a0, 0x080c, 0x2704, 0x002e, 0x001e, 0x080c, 0x41e0,
- 0x6612, 0x6516, 0xa006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e,
- 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x2009, 0x9220,
- 0x2104, 0xa086, 0x0074, 0x1904, 0x8e1e, 0x2069, 0x978e, 0x690c,
- 0xa182, 0x0100, 0x0678, 0x6908, 0xa184, 0x8000, 0x05a0, 0x2001,
- 0x94d7, 0x2004, 0xa005, 0x1118, 0xa184, 0x0800, 0x0560, 0x6910,
- 0xa18a, 0x0001, 0x0610, 0x6914, 0x2069, 0x97ae, 0x6904, 0x81ff,
- 0x1198, 0x690c, 0xa182, 0x0100, 0x02a8, 0x6908, 0x81ff, 0x1178,
- 0x6910, 0xa18a, 0x0001, 0x0288, 0x6918, 0xa18a, 0x0001, 0x0298,
- 0x00d0, 0x6013, 0x0100, 0x00a0, 0x6013, 0x0300, 0x0088, 0x6013,
- 0x0500, 0x0070, 0x6013, 0x0700, 0x0058, 0x6013, 0x0900, 0x0040,
- 0x6013, 0x0b00, 0x0028, 0x6013, 0x0f00, 0x0010, 0x6013, 0x2d00,
- 0xa085, 0x0001, 0x0008, 0xa006, 0x001e, 0x00de, 0x00ce, 0x0005,
- 0x00c6, 0x00d6, 0x0026, 0x0036, 0x0156, 0x6218, 0x2268, 0x6b04,
- 0xa394, 0x00ff, 0xa286, 0x0006, 0x0190, 0xa286, 0x0004, 0x0178,
- 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, 0x0148, 0xa286, 0x0004,
- 0x0130, 0x00c6, 0x2d60, 0x080c, 0x4443, 0x00ce, 0x04c0, 0x2011,
- 0x9796, 0xad98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x7aee, 0x1580,
- 0x2011, 0x979a, 0xad98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x7aee,
- 0x1538, 0x0046, 0x0016, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006,
- 0x2009, 0x9252, 0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c,
- 0x90d7, 0x6800, 0xc0e5, 0x6802, 0x2019, 0x0029, 0x080c, 0x6127,
- 0x0086, 0x2041, 0x0000, 0x080c, 0x606d, 0x2c08, 0x080c, 0x8ee4,
- 0x008e, 0x2001, 0x0007, 0x080c, 0x43f1, 0x001e, 0x004e, 0xa006,
- 0x015e, 0x003e, 0x002e, 0x00de, 0x00ce, 0x0005, 0x00d6, 0x2069,
- 0x978e, 0x6800, 0xa086, 0x0800, 0x0118, 0x6013, 0x0000, 0x0008,
- 0xa006, 0x00de, 0x0005, 0x00c6, 0x00f6, 0x0016, 0x0026, 0x0036,
- 0x0156, 0x2079, 0x978c, 0x7930, 0x7834, 0x080c, 0x240b, 0x11a0,
- 0x080c, 0x4434, 0x1188, 0x2011, 0x9790, 0xac98, 0x000a, 0x20a9,
- 0x0004, 0x080c, 0x7aee, 0x1140, 0x2011, 0x9794, 0xac98, 0x0006,
- 0x20a9, 0x0004, 0x080c, 0x7aee, 0x015e, 0x003e, 0x002e, 0x001e,
- 0x00fe, 0x00ce, 0x0005, 0x00c6, 0x0006, 0x0016, 0x0026, 0x0036,
- 0x0156, 0x2011, 0x9783, 0x2204, 0x8211, 0x220c, 0x080c, 0x240b,
- 0x11a0, 0x080c, 0x4434, 0x1188, 0x2011, 0x9796, 0xac98, 0x000a,
- 0x20a9, 0x0004, 0x080c, 0x7aee, 0x1140, 0x2011, 0x979a, 0xac98,
- 0x0006, 0x20a9, 0x0004, 0x080c, 0x7aee, 0x015e, 0x003e, 0x002e,
- 0x001e, 0x000e, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0076, 0x0066,
- 0x0056, 0x0046, 0x0026, 0x0126, 0x2091, 0x8000, 0x2029, 0x94ee,
- 0x252c, 0x2021, 0x94f4, 0x2424, 0x2061, 0x9900, 0x2071, 0x9200,
- 0x7644, 0x7064, 0x8001, 0xa602, 0x1a04, 0x8f44, 0x2100, 0xac06,
- 0x05d0, 0x080c, 0x90ee, 0x05b8, 0x671c, 0xa786, 0x0001, 0x0904,
- 0x8f56, 0xa786, 0x0007, 0x0578, 0x2500, 0xac06, 0x0560, 0x2400,
- 0xac06, 0x0548, 0x080c, 0x90fe, 0x1530, 0x88ff, 0x0118, 0x6020,
- 0xa906, 0x1508, 0x00d6, 0x6000, 0xa086, 0x0004, 0x1120, 0x0016,
- 0x080c, 0x1788, 0x001e, 0x6010, 0x2068, 0x080c, 0x82ee, 0x0180,
- 0xa786, 0x0003, 0x1510, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
- 0x0016, 0x080c, 0x8527, 0x080c, 0x4809, 0x001e, 0x080c, 0x848f,
- 0x00de, 0x080c, 0x849b, 0xace0, 0x000c, 0x2001, 0x9216, 0x2004,
- 0xac02, 0x1210, 0x0804, 0x8ef6, 0x012e, 0x002e, 0x004e, 0x005e,
- 0x006e, 0x007e, 0x00ce, 0x00ee, 0x0005, 0xa786, 0x0006, 0x19d8,
- 0xa386, 0x0005, 0x0d40, 0x080c, 0x9097, 0x0c10, 0x080c, 0x90fe,
- 0x1d10, 0xa180, 0x0001, 0x2004, 0xa086, 0x0018, 0x19e0, 0x6000,
- 0xa086, 0x0002, 0x19c0, 0x080c, 0x84b7, 0x0130, 0x080c, 0x84c8,
- 0x1990, 0x080c, 0x7776, 0x0010, 0x080c, 0x2692, 0x080c, 0x849b,
- 0x0850, 0x00c6, 0x00e6, 0x0016, 0x2c08, 0x2170, 0x080c, 0x90ab,
- 0x001e, 0x0120, 0x601c, 0xa084, 0x000f, 0x001b, 0x00ee, 0x00ce,
- 0x0005, 0x8f89, 0x8f89, 0x8f89, 0x8f89, 0x8f89, 0x8f89, 0x8f8b,
- 0x8f89, 0xa006, 0x0005, 0x0046, 0x0016, 0x7018, 0xa080, 0x0028,
- 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, 0x2009, 0x0020, 0x080c,
- 0x90d7, 0x001e, 0x004e, 0x0036, 0x2019, 0x0002, 0x080c, 0x8d4e,
- 0x003e, 0xa085, 0x0001, 0x0005, 0x2001, 0x0001, 0x080c, 0x43d1,
- 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x9205,
- 0x2011, 0x9796, 0x080c, 0x7aee, 0x003e, 0x002e, 0x001e, 0x015e,
- 0xa005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0076, 0x0066, 0x0026,
- 0x0126, 0x2091, 0x8000, 0x2061, 0x9900, 0x2079, 0x0001, 0x8fff,
- 0x0904, 0x9014, 0x2071, 0x9200, 0x7644, 0x7064, 0x8001, 0xa602,
- 0x1a04, 0x9014, 0x88ff, 0x0128, 0x2800, 0xac06, 0x15a0, 0x2079,
- 0x0000, 0x080c, 0x90ee, 0x0578, 0x2400, 0xac06, 0x0560, 0x671c,
- 0xa786, 0x0006, 0x1540, 0xa786, 0x0007, 0x0528, 0x88ff, 0x1140,
- 0x6018, 0xa206, 0x1500, 0x85ff, 0x0118, 0x6020, 0xa106, 0x11d8,
- 0x00d6, 0x6000, 0xa086, 0x0004, 0x1140, 0x601f, 0x0007, 0x2001,
- 0x94dd, 0x2004, 0x6016, 0x080c, 0x1788, 0x6010, 0x2068, 0x080c,
- 0x82ee, 0x0120, 0x0046, 0x080c, 0x9097, 0x004e, 0x00de, 0x080c,
- 0x849b, 0x88ff, 0x1190, 0xace0, 0x000c, 0x2001, 0x9216, 0x2004,
- 0xac02, 0x1210, 0x0804, 0x8fc7, 0xa006, 0x012e, 0x002e, 0x006e,
- 0x007e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0xa8c5, 0x0001, 0x0ca8,
- 0x0086, 0x0056, 0x2041, 0x0000, 0x2029, 0x0001, 0x2c20, 0x2019,
- 0x0002, 0x6218, 0x080c, 0x724a, 0x080c, 0x72e2, 0x080c, 0x8fba,
- 0x005e, 0x008e, 0x0005, 0x0026, 0x0046, 0x0056, 0x0086, 0x00c6,
- 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016,
- 0x0036, 0x080c, 0x4434, 0x1170, 0x2c10, 0x2041, 0x0000, 0x2508,
- 0x0056, 0x2029, 0x0001, 0x080c, 0x724a, 0x080c, 0x72e2, 0x080c,
- 0x8fba, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0x903f, 0x015e,
- 0x00ce, 0x008e, 0x005e, 0x004e, 0x002e, 0x0005, 0x0086, 0x0056,
- 0x6218, 0x2041, 0x0000, 0x2029, 0x0001, 0x2019, 0x0048, 0x080c,
- 0x724a, 0x080c, 0x72e2, 0x2c20, 0x080c, 0x8fba, 0x005e, 0x008e,
- 0x0005, 0x0026, 0x0046, 0x0056, 0x0086, 0x00c6, 0x0156, 0x2c20,
- 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x0036, 0x080c, 0x4434,
- 0x1150, 0x2c10, 0x2041, 0x0000, 0x2828, 0x080c, 0x724a, 0x080c,
- 0x72e2, 0x080c, 0x8fba, 0x003e, 0x001e, 0x8108, 0x1f04, 0x907c,
- 0x015e, 0x00ce, 0x008e, 0x005e, 0x004e, 0x002e, 0x0005, 0x0016,
- 0x00f6, 0x8dff, 0x0168, 0x6800, 0xa07d, 0x0138, 0x6803, 0x0000,
- 0x6b52, 0x080c, 0x4809, 0x2f68, 0x0cb0, 0x6b52, 0x080c, 0x4809,
- 0x00fe, 0x001e, 0x0005, 0x00e6, 0x0046, 0x0036, 0x2061, 0x9900,
- 0x2071, 0x9200, 0x7444, 0x7064, 0x8001, 0xa402, 0x12d8, 0x2100,
- 0xac06, 0x0168, 0x6000, 0xa086, 0x0000, 0x0148, 0x6008, 0xa206,
- 0x1130, 0x6018, 0xa1a0, 0x0006, 0x2424, 0xa406, 0x0140, 0xace0,
- 0x000c, 0x2001, 0x9216, 0x2004, 0xac02, 0x1220, 0x0c08, 0xa085,
- 0x0001, 0x0008, 0xa006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x00d6,
- 0x0006, 0x080c, 0x147c, 0x000e, 0x090c, 0x13fe, 0x6837, 0x010d,
- 0x685e, 0x6956, 0x6c46, 0x684f, 0x0000, 0xa006, 0x68b2, 0x6802,
- 0x683a, 0x685a, 0x080c, 0x4809, 0x00de, 0x0005, 0x6700, 0xa786,
- 0x0000, 0x0158, 0xa786, 0x0001, 0x0140, 0xa786, 0x000a, 0x0128,
- 0xa786, 0x0009, 0x0110, 0xa085, 0x0001, 0x0005, 0x00e6, 0x6018,
- 0x2070, 0x70a0, 0xa206, 0x00ee, 0x0005, 0xa186, 0x0013, 0x1128,
- 0x6004, 0xa082, 0x0085, 0x2008, 0x00c2, 0xa186, 0x0027, 0x1178,
- 0x080c, 0x6389, 0x0036, 0x00d6, 0x6010, 0x2068, 0x2019, 0x0004,
- 0x080c, 0x9097, 0x00de, 0x003e, 0x080c, 0x6462, 0x0005, 0xa186,
- 0x0014, 0x0d70, 0x080c, 0x7526, 0x0005, 0x912e, 0x912c, 0x912c,
- 0x912c, 0x912c, 0x912c, 0x912e, 0x080c, 0x13fe, 0x080c, 0x6389,
- 0x6003, 0x000c, 0x080c, 0x6462, 0x0005, 0xa182, 0x008c, 0x1220,
- 0xa182, 0x0085, 0x0208, 0x001a, 0x080c, 0x7526, 0x0005, 0x9146,
- 0x9146, 0x9146, 0x9146, 0x9148, 0x914d, 0x9146, 0x080c, 0x13fe,
- 0x00d6, 0x080c, 0x74f2, 0x00de, 0x0005, 0x080c, 0x74f2, 0x0005,
- 0x00e6, 0x6018, 0x2070, 0x7000, 0xd0ec, 0x00ee, 0x0005, 0x0126,
- 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0x9240, 0xd5a4, 0x0118,
- 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0118, 0x7030, 0x8000, 0x7032,
- 0xd5ac, 0x0118, 0x2071, 0x924a, 0x0451, 0x00ee, 0x000e, 0x012e,
- 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0x9240,
- 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0118, 0x7030,
- 0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, 0x924a, 0x0081, 0x00ee,
- 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000,
- 0x2071, 0x9242, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e04,
- 0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x0005,
- 0x00e6, 0x2071, 0x9240, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071,
- 0x9244, 0x0c69, 0x00ee, 0x0005, 0x0001, 0x0002, 0x0004, 0x0008,
- 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800,
- 0x1000, 0x2000, 0x4000, 0x8000, 0x448c
+ 0x684f, 0x0000, 0x6857, 0x0036, 0x080c, 0x46a1, 0x001e, 0xa486,
+ 0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0x891c, 0x0804, 0x8312,
+ 0xa486, 0x0400, 0x1130, 0x2019, 0x0002, 0x080c, 0x88de, 0x0804,
+ 0x8312, 0xa486, 0x0200, 0x1110, 0x080c, 0x88cb, 0xa486, 0x1000,
+ 0x1110, 0x080c, 0x8909, 0x0804, 0x8312, 0x2069, 0x8e2a, 0x6a00,
+ 0xd284, 0x0904, 0x8361, 0xa284, 0x0300, 0x1904, 0x835b, 0x6804,
+ 0xa005, 0x0904, 0x834c, 0x2d78, 0x6003, 0x0007, 0x080c, 0x146f,
+ 0x0904, 0x8319, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806,
+ 0x6013, 0x0000, 0x6803, 0x0000, 0x6837, 0x0116, 0x683b, 0x0000,
+ 0x6008, 0x68b2, 0x2c00, 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007,
+ 0x7130, 0x6986, 0x6846, 0x6853, 0x003d, 0x7244, 0xa294, 0x0003,
+ 0xa286, 0x0002, 0x1118, 0x684f, 0x0040, 0x0040, 0xa286, 0x0001,
+ 0x1118, 0x684f, 0x0080, 0x0010, 0x684f, 0x0000, 0x20a9, 0x000a,
+ 0x2001, 0x9090, 0xad90, 0x0015, 0x200c, 0x810f, 0x2112, 0x8000,
+ 0x8210, 0x1f04, 0x8304, 0x200c, 0x6982, 0x8000, 0x200c, 0x697e,
+ 0x080c, 0x46a1, 0x002e, 0x004e, 0x015e, 0x00fe, 0x00ee, 0x00de,
+ 0x0005, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c,
+ 0x589c, 0x080c, 0x5d10, 0x0c70, 0x2069, 0x9092, 0x2d04, 0xa084,
+ 0xff00, 0xa086, 0x1200, 0x11a8, 0x2069, 0x9080, 0x686c, 0xa084,
+ 0x00ff, 0x0016, 0x6110, 0xa18c, 0x0700, 0xa10d, 0x6112, 0x001e,
+ 0x6003, 0x0001, 0x6007, 0x0043, 0x080c, 0x589c, 0x080c, 0x5d10,
+ 0x0888, 0x6013, 0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c,
+ 0x589c, 0x080c, 0x5d10, 0x0830, 0x6013, 0x0300, 0x0010, 0x6013,
+ 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x589c, 0x080c,
+ 0x5d10, 0x0804, 0x8312, 0x6013, 0x0500, 0x0c98, 0x6013, 0x0600,
+ 0x0818, 0x6013, 0x0200, 0x0800, 0xa186, 0x0013, 0x1170, 0x6004,
+ 0xa08a, 0x0040, 0x0a0c, 0x1410, 0xa08a, 0x0053, 0x1a0c, 0x1410,
+ 0xa082, 0x0040, 0x2008, 0x0804, 0x83cf, 0xa186, 0x0047, 0x11b8,
+ 0x2001, 0x0109, 0x2004, 0xd084, 0x01f0, 0x0126, 0x2091, 0x2400,
+ 0x0006, 0x0016, 0x0026, 0x080c, 0x578e, 0x002e, 0x001e, 0x000e,
+ 0x012e, 0x6000, 0xa086, 0x0002, 0x1170, 0x0804, 0x840f, 0xa186,
+ 0x0027, 0x0120, 0xa186, 0x0014, 0x190c, 0x1410, 0x6004, 0xa082,
+ 0x0040, 0x2008, 0x001a, 0x080c, 0x6d55, 0x0005, 0x83b1, 0x83b3,
+ 0x83b3, 0x83b1, 0x83b1, 0x83b1, 0x83b1, 0x83b1, 0x83b1, 0x83b1,
+ 0x83b1, 0x83b1, 0x83b1, 0x83b1, 0x83b1, 0x83b1, 0x83b1, 0x83b1,
+ 0x83b1, 0x080c, 0x1410, 0x080c, 0x5c37, 0x080c, 0x5d10, 0x0036,
+ 0x00d6, 0x6010, 0xa06d, 0x0180, 0xad84, 0xf000, 0x0168, 0x2019,
+ 0x0004, 0x080c, 0x8942, 0x6013, 0x0000, 0x6014, 0xa005, 0x1110,
+ 0x6017, 0x0014, 0x6003, 0x0007, 0x00de, 0x003e, 0x0005, 0x0002,
+ 0x83e3, 0x8400, 0x83ec, 0x8409, 0x83e3, 0x83e3, 0x83e3, 0x83e3,
+ 0x83e3, 0x83e3, 0x83e3, 0x83e3, 0x83e3, 0x83e3, 0x83e3, 0x83e3,
+ 0x83e3, 0x83e3, 0x83e3, 0x080c, 0x1410, 0x6010, 0xa088, 0x0013,
+ 0x2104, 0xa085, 0x0400, 0x200a, 0x080c, 0x5c37, 0x6010, 0xa080,
+ 0x0013, 0x2004, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009, 0x0043,
+ 0x080c, 0x6d3f, 0x0010, 0x6003, 0x0002, 0x080c, 0x5d10, 0x0005,
+ 0x080c, 0x5c37, 0x080c, 0x570f, 0x080c, 0x6d18, 0x080c, 0x5d10,
+ 0x0005, 0x080c, 0x5c37, 0x2009, 0x0041, 0x0804, 0x84ef, 0xa182,
+ 0x0040, 0x0002, 0x8425, 0x8427, 0x8425, 0x8425, 0x8425, 0x8425,
+ 0x8425, 0x8428, 0x8425, 0x8425, 0x8425, 0x8425, 0x8425, 0x8425,
+ 0x8425, 0x8425, 0x8425, 0x8425, 0x8425, 0x080c, 0x1410, 0x0005,
+ 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10,
+ 0x080c, 0x16d1, 0x0005, 0xa182, 0x0040, 0x0002, 0x8449, 0x8449,
+ 0x8449, 0x8449, 0x8449, 0x8449, 0x8449, 0x8449, 0x8449, 0x844b,
+ 0x846b, 0x8449, 0x8449, 0x8449, 0x8449, 0x846b, 0x8449, 0x8449,
+ 0x8449, 0x080c, 0x1410, 0x080c, 0x5cc9, 0x080c, 0x5dc2, 0x6010,
+ 0x00d6, 0x2068, 0x684c, 0xd0fc, 0x0150, 0xa08c, 0x0003, 0xa18e,
+ 0x0002, 0x0158, 0x2009, 0x0041, 0x00de, 0x0804, 0x84ef, 0x6003,
+ 0x0007, 0x080c, 0x570f, 0x00de, 0x0005, 0x080c, 0x570f, 0x080c,
+ 0x6d18, 0x00de, 0x0cc8, 0x0036, 0x080c, 0x5cc9, 0x080c, 0x5dc2,
+ 0x6010, 0x00d6, 0x2068, 0x2019, 0x0004, 0x080c, 0x8942, 0x080c,
+ 0x7d3c, 0x6017, 0x0028, 0x00de, 0x003e, 0x0005, 0xa186, 0x0013,
+ 0x1150, 0x6004, 0xa086, 0x0042, 0x190c, 0x1410, 0x080c, 0x5c37,
+ 0x080c, 0x5d10, 0x0005, 0xa186, 0x0027, 0x0118, 0xa186, 0x0014,
+ 0x1180, 0x6004, 0xa086, 0x0042, 0x190c, 0x1410, 0x2001, 0x0007,
+ 0x080c, 0x42c7, 0x080c, 0x5c37, 0x080c, 0x7d3c, 0x080c, 0x5d10,
+ 0x0005, 0xa182, 0x0040, 0x0002, 0x84b7, 0x84b7, 0x84b7, 0x84b7,
+ 0x84b7, 0x84b7, 0x84b7, 0x84b9, 0x84c5, 0x84b7, 0x84b7, 0x84b7,
+ 0x84b7, 0x84b7, 0x84b7, 0x84b7, 0x84b7, 0x84b7, 0x84b7, 0x080c,
+ 0x1410, 0x0036, 0x0046, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10,
+ 0x080c, 0x16d1, 0x004e, 0x003e, 0x0005, 0x6010, 0x00d6, 0x2068,
+ 0x6810, 0x6a14, 0xa20d, 0x1168, 0x684c, 0xd0fc, 0x0120, 0x2009,
+ 0x0041, 0x00de, 0x00e0, 0x6003, 0x0007, 0x080c, 0x570f, 0x00de,
+ 0x0005, 0x6003, 0x0007, 0x0021, 0x080c, 0x5711, 0x00de, 0x0005,
+ 0xd2fc, 0x0140, 0x8002, 0x8000, 0x8212, 0xa291, 0x0000, 0x2009,
+ 0x0009, 0x0010, 0x2009, 0x0015, 0x6a6a, 0x6866, 0x0005, 0xa182,
+ 0x0040, 0x0002, 0x8505, 0x8507, 0x8513, 0x851f, 0x8505, 0x8505,
+ 0x8505, 0x852e, 0x8505, 0x8505, 0x8505, 0x8505, 0x8505, 0x8505,
+ 0x8505, 0x8505, 0x8505, 0x8505, 0x8505, 0x080c, 0x1410, 0x6003,
+ 0x0001, 0x6106, 0x080c, 0x589c, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x5d10, 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x589c,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x5d10, 0x012e, 0x0005, 0x6003,
+ 0x0003, 0x6106, 0x2c10, 0x080c, 0x1bc8, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x58ff, 0x080c, 0x5dc2, 0x012e, 0x0005, 0xa016, 0x080c,
+ 0x16d1, 0x0005, 0x080c, 0x5c37, 0x6110, 0x81ff, 0x0148, 0x00d6,
+ 0x2168, 0x0036, 0x2019, 0x0029, 0x080c, 0x8942, 0x003e, 0x00de,
+ 0x080c, 0x7d3c, 0x080c, 0x5d10, 0x0005, 0x080c, 0x5cc9, 0x6110,
+ 0x81ff, 0x0148, 0x00d6, 0x2168, 0x0036, 0x2019, 0x0029, 0x080c,
+ 0x8942, 0x003e, 0x00de, 0x080c, 0x7d3c, 0x080c, 0x5dc2, 0x0005,
+ 0xa182, 0x0085, 0x0002, 0x8564, 0x8562, 0x8562, 0x8570, 0x8562,
+ 0x8562, 0x8562, 0x080c, 0x1410, 0x6003, 0x000b, 0x6106, 0x080c,
+ 0x589c, 0x0126, 0x2091, 0x8000, 0x080c, 0x5d10, 0x012e, 0x0005,
+ 0x0026, 0x00e6, 0x080c, 0x89fb, 0x0118, 0x080c, 0x6d18, 0x00c8,
+ 0x2071, 0x9080, 0x7224, 0x6212, 0x7220, 0x080c, 0x881c, 0x0118,
+ 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0xa296, 0xffff,
+ 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x080c, 0x589c, 0x080c,
+ 0x5d10, 0x00ee, 0x002e, 0x0005, 0xa186, 0x0013, 0x1160, 0x6004,
+ 0xa08a, 0x0085, 0x0a0c, 0x1410, 0xa08a, 0x008c, 0x1a0c, 0x1410,
+ 0xa082, 0x0085, 0x00a2, 0xa186, 0x0027, 0x0130, 0xa186, 0x0014,
+ 0x0118, 0x080c, 0x6d55, 0x0050, 0x2001, 0x0007, 0x080c, 0x42c7,
+ 0x080c, 0x5c37, 0x080c, 0x7d3c, 0x080c, 0x5d10, 0x0005, 0x85be,
+ 0x85c0, 0x85c0, 0x85be, 0x85be, 0x85be, 0x85be, 0x080c, 0x1410,
+ 0x080c, 0x5c37, 0x080c, 0x6d18, 0x080c, 0x5d10, 0x0005, 0xa182,
+ 0x0085, 0x0a0c, 0x1410, 0xa182, 0x008c, 0x1a0c, 0x1410, 0xa182,
+ 0x0085, 0x0002, 0x85d9, 0x85d9, 0x85d9, 0x85db, 0x85d9, 0x85d9,
+ 0x85d9, 0x080c, 0x1410, 0x0005, 0xa186, 0x0013, 0x0148, 0xa186,
+ 0x0014, 0x0130, 0xa186, 0x0027, 0x0118, 0x080c, 0x6d55, 0x0030,
+ 0x080c, 0x5c37, 0x080c, 0x7d3c, 0x080c, 0x5d10, 0x0005, 0x0036,
+ 0x2019, 0x000b, 0x0031, 0x601f, 0x0006, 0x6003, 0x0007, 0x003e,
+ 0x0005, 0x0126, 0x0036, 0x0086, 0x2091, 0x8000, 0x2c40, 0x080c,
+ 0x6a17, 0x1540, 0x080c, 0x6aaf, 0x1528, 0x6000, 0xa086, 0x0000,
+ 0x0508, 0x601c, 0xa086, 0x0007, 0x01e8, 0x00d6, 0x6000, 0xa086,
+ 0x0004, 0x1140, 0x601f, 0x0007, 0x2001, 0x8da2, 0x2004, 0x6016,
+ 0x080c, 0x179e, 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0110, 0x080c,
+ 0x8942, 0x00de, 0x6013, 0x0000, 0x601f, 0x0007, 0x2001, 0x8da2,
+ 0x2004, 0x6016, 0x008e, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6,
+ 0x0036, 0x0156, 0x2079, 0x9080, 0x7938, 0x783c, 0x080c, 0x22e9,
+ 0x1904, 0x8679, 0x0016, 0x00c6, 0x080c, 0x430a, 0x15c0, 0x2011,
+ 0x9090, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x7326, 0x1578,
+ 0x001e, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0x6b6f,
+ 0x080c, 0x59d5, 0x0086, 0x2041, 0x0000, 0x080c, 0x5911, 0x008e,
+ 0x001e, 0x0086, 0x2041, 0x0000, 0x080c, 0x878f, 0x008e, 0x080c,
+ 0x44e6, 0x0026, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006,
+ 0x0118, 0xa286, 0x0004, 0x1118, 0x62a0, 0x080c, 0x25fb, 0x002e,
+ 0x001e, 0x080c, 0x4118, 0x6612, 0x6516, 0xa006, 0x0010, 0x00ce,
+ 0x001e, 0x015e, 0x003e, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6,
+ 0x0016, 0x2009, 0x8b20, 0x2104, 0xa086, 0x0074, 0x1904, 0x86c9,
+ 0x2069, 0x908e, 0x690c, 0xa182, 0x0100, 0x0678, 0x6908, 0xa184,
+ 0x8000, 0x05a0, 0x2001, 0x8d9c, 0x2004, 0xa005, 0x1118, 0xa184,
+ 0x0800, 0x0560, 0x6910, 0xa18a, 0x0001, 0x0610, 0x6914, 0x2069,
+ 0x90ae, 0x6904, 0x81ff, 0x1198, 0x690c, 0xa182, 0x0100, 0x02a8,
+ 0x6908, 0x81ff, 0x1178, 0x6910, 0xa18a, 0x0001, 0x0288, 0x6918,
+ 0xa18a, 0x0001, 0x0298, 0x00d0, 0x6013, 0x0100, 0x00a0, 0x6013,
+ 0x0300, 0x0088, 0x6013, 0x0500, 0x0070, 0x6013, 0x0700, 0x0058,
+ 0x6013, 0x0900, 0x0040, 0x6013, 0x0b00, 0x0028, 0x6013, 0x0f00,
+ 0x0010, 0x6013, 0x2d00, 0xa085, 0x0001, 0x0008, 0xa006, 0x001e,
+ 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x0026, 0x0036, 0x0156,
+ 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff, 0xa286, 0x0006, 0x0190,
+ 0xa286, 0x0004, 0x0178, 0xa394, 0xff00, 0x8217, 0xa286, 0x0006,
+ 0x0148, 0xa286, 0x0004, 0x0130, 0x00c6, 0x2d60, 0x080c, 0x4319,
+ 0x00ce, 0x04c0, 0x2011, 0x9096, 0xad98, 0x000a, 0x20a9, 0x0004,
+ 0x080c, 0x7326, 0x1580, 0x2011, 0x909a, 0xad98, 0x0006, 0x20a9,
+ 0x0004, 0x080c, 0x7326, 0x1538, 0x0046, 0x0016, 0x6aa0, 0xa294,
+ 0x00ff, 0x8227, 0xa006, 0x2009, 0x8b52, 0x210c, 0xd1a4, 0x0138,
+ 0x2009, 0x0029, 0x080c, 0x8982, 0x6800, 0xc0e5, 0x6802, 0x2019,
+ 0x0029, 0x080c, 0x59d5, 0x0086, 0x2041, 0x0000, 0x080c, 0x5911,
+ 0x2c08, 0x080c, 0x878f, 0x008e, 0x2001, 0x0007, 0x080c, 0x42c7,
+ 0x001e, 0x004e, 0xa006, 0x015e, 0x003e, 0x002e, 0x00de, 0x00ce,
+ 0x0005, 0x00d6, 0x2069, 0x908e, 0x6800, 0xa086, 0x0800, 0x0118,
+ 0x6013, 0x0000, 0x0008, 0xa006, 0x00de, 0x0005, 0x00c6, 0x00f6,
+ 0x0016, 0x0026, 0x0036, 0x0156, 0x2079, 0x908c, 0x7930, 0x7834,
+ 0x080c, 0x22e9, 0x11a0, 0x080c, 0x430a, 0x1188, 0x2011, 0x9090,
+ 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x7326, 0x1140, 0x2011,
+ 0x9094, 0xac98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x7326, 0x015e,
+ 0x003e, 0x002e, 0x001e, 0x00fe, 0x00ce, 0x0005, 0x00c6, 0x0006,
+ 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, 0x9083, 0x2204, 0x8211,
+ 0x220c, 0x080c, 0x22e9, 0x11a0, 0x080c, 0x430a, 0x1188, 0x2011,
+ 0x9096, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x7326, 0x1140,
+ 0x2011, 0x909a, 0xac98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x7326,
+ 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00ce, 0x0005, 0x00e6,
+ 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091,
+ 0x8000, 0x2029, 0x8db3, 0x252c, 0x2021, 0x8db9, 0x2424, 0x2061,
+ 0x9200, 0x2071, 0x8b00, 0x7644, 0x7064, 0x8001, 0xa602, 0x1a04,
+ 0x87ef, 0x2100, 0xac06, 0x05d0, 0x080c, 0x8999, 0x05b8, 0x671c,
+ 0xa786, 0x0001, 0x0904, 0x8801, 0xa786, 0x0007, 0x0578, 0x2500,
+ 0xac06, 0x0560, 0x2400, 0xac06, 0x0548, 0x080c, 0x89a9, 0x1530,
+ 0x88ff, 0x0118, 0x6020, 0xa906, 0x1508, 0x00d6, 0x6000, 0xa086,
+ 0x0004, 0x1120, 0x0016, 0x080c, 0x179e, 0x001e, 0x6010, 0x2068,
+ 0x080c, 0x7b8f, 0x0180, 0xa786, 0x0003, 0x1510, 0x6837, 0x0103,
+ 0x6b4a, 0x6847, 0x0000, 0x0016, 0x080c, 0x7dc8, 0x080c, 0x46a1,
+ 0x001e, 0x080c, 0x7d30, 0x00de, 0x080c, 0x7d3c, 0xace0, 0x000c,
+ 0x2001, 0x8b16, 0x2004, 0xac02, 0x1210, 0x0804, 0x87a1, 0x012e,
+ 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00ee, 0x0005,
+ 0xa786, 0x0006, 0x19d8, 0xa386, 0x0005, 0x0d40, 0x080c, 0x8942,
+ 0x0c10, 0x080c, 0x89a9, 0x1d10, 0xa180, 0x0001, 0x2004, 0xa086,
+ 0x0018, 0x19e0, 0x6000, 0xa086, 0x0002, 0x19c0, 0x080c, 0x7d58,
+ 0x0130, 0x080c, 0x7d69, 0x1990, 0x080c, 0x6fb6, 0x0010, 0x080c,
+ 0x2589, 0x080c, 0x7d3c, 0x0850, 0x00c6, 0x00e6, 0x0016, 0x2c08,
+ 0x2170, 0x080c, 0x8956, 0x001e, 0x0120, 0x601c, 0xa084, 0x000f,
+ 0x001b, 0x00ee, 0x00ce, 0x0005, 0x8834, 0x8834, 0x8834, 0x8834,
+ 0x8834, 0x8834, 0x8836, 0x8834, 0xa006, 0x0005, 0x0046, 0x0016,
+ 0x7018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00,
+ 0x2009, 0x0020, 0x080c, 0x8982, 0x001e, 0x004e, 0x0036, 0x2019,
+ 0x0002, 0x080c, 0x85f9, 0x003e, 0xa085, 0x0001, 0x0005, 0x2001,
+ 0x0001, 0x080c, 0x42a7, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9,
+ 0x0004, 0x2019, 0x8b05, 0x2011, 0x9096, 0x080c, 0x7326, 0x003e,
+ 0x002e, 0x001e, 0x015e, 0xa005, 0x0005, 0x00f6, 0x00e6, 0x00c6,
+ 0x0076, 0x0066, 0x0026, 0x0126, 0x2091, 0x8000, 0x2061, 0x9200,
+ 0x2079, 0x0001, 0x8fff, 0x0904, 0x88bf, 0x2071, 0x8b00, 0x7644,
+ 0x7064, 0x8001, 0xa602, 0x1a04, 0x88bf, 0x88ff, 0x0128, 0x2800,
+ 0xac06, 0x15a0, 0x2079, 0x0000, 0x080c, 0x8999, 0x0578, 0x2400,
+ 0xac06, 0x0560, 0x671c, 0xa786, 0x0006, 0x1540, 0xa786, 0x0007,
+ 0x0528, 0x88ff, 0x1140, 0x6018, 0xa206, 0x1500, 0x85ff, 0x0118,
+ 0x6020, 0xa106, 0x11d8, 0x00d6, 0x6000, 0xa086, 0x0004, 0x1140,
+ 0x601f, 0x0007, 0x2001, 0x8da2, 0x2004, 0x6016, 0x080c, 0x179e,
+ 0x6010, 0x2068, 0x080c, 0x7b8f, 0x0120, 0x0046, 0x080c, 0x8942,
+ 0x004e, 0x00de, 0x080c, 0x7d3c, 0x88ff, 0x1190, 0xace0, 0x000c,
+ 0x2001, 0x8b16, 0x2004, 0xac02, 0x1210, 0x0804, 0x8872, 0xa006,
+ 0x012e, 0x002e, 0x006e, 0x007e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+ 0xa8c5, 0x0001, 0x0ca8, 0x0086, 0x0056, 0x2041, 0x0000, 0x2029,
+ 0x0001, 0x2c20, 0x2019, 0x0002, 0x6218, 0x080c, 0x6a17, 0x080c,
+ 0x6aaf, 0x080c, 0x8865, 0x005e, 0x008e, 0x0005, 0x0026, 0x0046,
+ 0x0056, 0x0086, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f,
+ 0x2009, 0x0000, 0x0016, 0x0036, 0x080c, 0x430a, 0x1170, 0x2c10,
+ 0x2041, 0x0000, 0x2508, 0x0056, 0x2029, 0x0001, 0x080c, 0x6a17,
+ 0x080c, 0x6aaf, 0x080c, 0x8865, 0x005e, 0x003e, 0x001e, 0x8108,
+ 0x1f04, 0x88ea, 0x015e, 0x00ce, 0x008e, 0x005e, 0x004e, 0x002e,
+ 0x0005, 0x0086, 0x0056, 0x6218, 0x2041, 0x0000, 0x2029, 0x0001,
+ 0x2019, 0x0048, 0x080c, 0x6a17, 0x080c, 0x6aaf, 0x2c20, 0x080c,
+ 0x8865, 0x005e, 0x008e, 0x0005, 0x0026, 0x0046, 0x0056, 0x0086,
+ 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016,
+ 0x0036, 0x080c, 0x430a, 0x1150, 0x2c10, 0x2041, 0x0000, 0x2828,
+ 0x080c, 0x6a17, 0x080c, 0x6aaf, 0x080c, 0x8865, 0x003e, 0x001e,
+ 0x8108, 0x1f04, 0x8927, 0x015e, 0x00ce, 0x008e, 0x005e, 0x004e,
+ 0x002e, 0x0005, 0x0016, 0x00f6, 0x8dff, 0x0168, 0x6800, 0xa07d,
+ 0x0138, 0x6803, 0x0000, 0x6b52, 0x080c, 0x46a1, 0x2f68, 0x0cb0,
+ 0x6b52, 0x080c, 0x46a1, 0x00fe, 0x001e, 0x0005, 0x00e6, 0x0046,
+ 0x0036, 0x2061, 0x9200, 0x2071, 0x8b00, 0x7444, 0x7064, 0x8001,
+ 0xa402, 0x12d8, 0x2100, 0xac06, 0x0168, 0x6000, 0xa086, 0x0000,
+ 0x0148, 0x6008, 0xa206, 0x1130, 0x6018, 0xa1a0, 0x0006, 0x2424,
+ 0xa406, 0x0140, 0xace0, 0x000c, 0x2001, 0x8b16, 0x2004, 0xac02,
+ 0x1220, 0x0c08, 0xa085, 0x0001, 0x0008, 0xa006, 0x003e, 0x004e,
+ 0x00ee, 0x0005, 0x00d6, 0x0006, 0x080c, 0x1488, 0x000e, 0x090c,
+ 0x1410, 0x6837, 0x010d, 0x685e, 0x6956, 0x6c46, 0x684f, 0x0000,
+ 0xa006, 0x68b2, 0x6802, 0x683a, 0x685a, 0x080c, 0x46a1, 0x00de,
+ 0x0005, 0x6700, 0xa786, 0x0000, 0x0158, 0xa786, 0x0001, 0x0140,
+ 0xa786, 0x000a, 0x0128, 0xa786, 0x0009, 0x0110, 0xa085, 0x0001,
+ 0x0005, 0x00e6, 0x6018, 0x2070, 0x70a0, 0xa206, 0x00ee, 0x0005,
+ 0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x00c2,
+ 0xa186, 0x0027, 0x1178, 0x080c, 0x5c37, 0x0036, 0x00d6, 0x6010,
+ 0x2068, 0x2019, 0x0004, 0x080c, 0x8942, 0x00de, 0x003e, 0x080c,
+ 0x5d10, 0x0005, 0xa186, 0x0014, 0x0d70, 0x080c, 0x6d55, 0x0005,
+ 0x89d9, 0x89d7, 0x89d7, 0x89d7, 0x89d7, 0x89d7, 0x89d9, 0x080c,
+ 0x1410, 0x080c, 0x5c37, 0x6003, 0x000c, 0x080c, 0x5d10, 0x0005,
+ 0xa182, 0x008c, 0x1220, 0xa182, 0x0085, 0x0208, 0x001a, 0x080c,
+ 0x6d55, 0x0005, 0x89f1, 0x89f1, 0x89f1, 0x89f1, 0x89f3, 0x89f8,
+ 0x89f1, 0x080c, 0x1410, 0x00d6, 0x080c, 0x6d18, 0x00de, 0x0005,
+ 0x080c, 0x6d18, 0x0005, 0x00e6, 0x6018, 0x2070, 0x7000, 0xd0ec,
+ 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071,
+ 0x8b40, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0118,
+ 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, 0x8b4a, 0x0451,
+ 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091,
+ 0x8000, 0x2071, 0x8b40, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036,
+ 0xd5b4, 0x0118, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071,
+ 0x8b4a, 0x0081, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006,
+ 0x00e6, 0x2091, 0x8000, 0x2071, 0x8b42, 0x0021, 0x00ee, 0x000e,
+ 0x012e, 0x0005, 0x2e04, 0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04,
+ 0x8000, 0x2072, 0x0005, 0x00e6, 0x2071, 0x8b40, 0x0c99, 0x00ee,
+ 0x0005, 0x00e6, 0x2071, 0x8b44, 0x0c69, 0x00ee, 0x0005, 0x0001,
+ 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
+ 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x2854
};
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index 038f5e9ed..a7418f18b 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -781,7 +781,7 @@ static int __init qpti_map_queues(struct qlogicpti *qpti)
struct sbus_dev *sdev = qpti->sdev;
#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
- qpti->res_cpu = sbus_alloc_consistant(sdev,
+ qpti->res_cpu = sbus_alloc_consistent(sdev,
QSIZE(RES_QUEUE_LEN),
&qpti->res_dvma);
if (qpti->res_cpu == NULL ||
@@ -790,12 +790,12 @@ static int __init qpti_map_queues(struct qlogicpti *qpti)
return -1;
}
- qpti->req_cpu = sbus_alloc_consistant(sdev,
+ qpti->req_cpu = sbus_alloc_consistent(sdev,
QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
&qpti->req_dvma);
if (qpti->req_cpu == NULL ||
qpti->req_dvma == 0) {
- sbus_free_consistant(sdev, QSIZE(RES_QUEUE_LEN),
+ sbus_free_consistent(sdev, QSIZE(RES_QUEUE_LEN),
qpti->res_cpu, qpti->res_dvma);
printk("QPTI: Cannot map request queue.\n");
return -1;
@@ -917,10 +917,10 @@ int __init qlogicpti_detect(Scsi_Host_Template *tpnt)
fail_unmap_queues:
#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
- sbus_free_consistant(qpti->sdev,
+ sbus_free_consistent(qpti->sdev,
QSIZE(RES_QUEUE_LEN),
qpti->res_cpu, qpti->res_dvma);
- sbus_free_consistant(qpti->sdev,
+ sbus_free_consistent(qpti->sdev,
QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
qpti->req_cpu, qpti->req_dvma);
#undef QSIZE
@@ -958,10 +958,10 @@ int qlogicpti_release(struct Scsi_Host *host)
free_irq(qpti->irq, qpti);
#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
- sbus_free_consistant(qpti->sdev,
+ sbus_free_consistent(qpti->sdev,
QSIZE(RES_QUEUE_LEN),
qpti->res_cpu, qpti->res_dvma);
- sbus_free_consistant(qpti->sdev,
+ sbus_free_consistent(qpti->sdev,
QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
qpti->req_cpu, qpti->req_dvma);
#undef QSIZE
@@ -1046,8 +1046,8 @@ static inline int load_cmd(Scsi_Cmnd *Cmnd, struct Command_Entry *cmd,
if (n > 4)
n = 4;
for (i = 0; i < n; i++, sg++) {
- ds[i].d_base = sg->dvma_address;
- ds[i].d_count = sg->dvma_length;
+ ds[i].d_base = sg_dma_address(sg);
+ ds[i].d_count = sg_dma_len(sg);
}
sg_count -= 4;
while (sg_count > 0) {
@@ -1069,8 +1069,8 @@ static inline int load_cmd(Scsi_Cmnd *Cmnd, struct Command_Entry *cmd,
if (n > 7)
n = 7;
for (i = 0; i < n; i++, sg++) {
- ds[i].d_base = sg->dvma_address;
- ds[i].d_count = sg->dvma_length;
+ ds[i].d_base = sg_dma_address(sg);
+ ds[i].d_count = sg_dma_len(sg);
}
sg_count -= n;
}
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index eeff3d5fd..2472fe167 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -86,44 +86,11 @@ static void scsi_dump_status(int level);
* Definitions and constants.
*/
-/*
- * PAGE_SIZE must be a multiple of the sector size (512). True
- * for all reasonably recent architectures (even the VAX...).
- */
-#define SECTOR_SIZE 512
-#define SECTORS_PER_PAGE (PAGE_SIZE/SECTOR_SIZE)
-
-#if SECTORS_PER_PAGE <= 8
-typedef unsigned char FreeSectorBitmap;
-#elif SECTORS_PER_PAGE <= 32
-typedef unsigned int FreeSectorBitmap;
-#else
-#error You lose.
-#endif
-
#define MIN_RESET_DELAY (2*HZ)
/* Do not call reset on error if we just did a reset within 15 sec. */
#define MIN_RESET_PERIOD (15*HZ)
-/* The following devices are known not to tolerate a lun != 0 scan for
- * one reason or another. Some will respond to all luns, others will
- * lock up.
- */
-
-#define BLIST_NOLUN 0x001
-#define BLIST_FORCELUN 0x002
-#define BLIST_BORKEN 0x004
-#define BLIST_KEY 0x008
-#define BLIST_SINGLELUN 0x010
-#define BLIST_NOTQ 0x020
-#define BLIST_SPARSELUN 0x040
-#define BLIST_MAX5LUN 0x080
-#define BLIST_ISDISK 0x100
-#define BLIST_ISROM 0x200
-#define BLIST_GHOST 0x400
-
-
/*
* Data declarations.
@@ -139,12 +106,6 @@ const unsigned char scsi_command_size[8] =
static unsigned long serial_number = 0;
static Scsi_Cmnd *scsi_bh_queue_head = NULL;
static Scsi_Cmnd *scsi_bh_queue_tail = NULL;
-static FreeSectorBitmap *dma_malloc_freelist = NULL;
-static int need_isa_bounce_buffers;
-static unsigned int dma_sectors = 0;
-unsigned int scsi_dma_free_sectors = 0;
-unsigned int scsi_need_isa_buffer = 0;
-static unsigned char **dma_malloc_pages = NULL;
/*
* Note - the initial logging level can be set here to log events at boot time.
@@ -173,12 +134,7 @@ const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] =
/*
* Function prototypes.
*/
-static void resize_dma_pool(void);
-static void print_inquiry(unsigned char *data);
extern void scsi_times_out(Scsi_Cmnd * SCpnt);
-static int scan_scsis_single(int channel, int dev, int lun, int *max_scsi_dev,
- int *sparse_lun, Scsi_Device ** SDpnt, Scsi_Cmnd * SCpnt,
- struct Scsi_Host *shpnt, char *scsi_result);
void scsi_build_commandblocks(Scsi_Device * SDpnt);
static int scsi_unregister_device(struct Scsi_Device_Template *tpnt);
@@ -189,140 +145,40 @@ static int scsi_unregister_device(struct Scsi_Device_Template *tpnt);
extern void scsi_old_done(Scsi_Cmnd * SCpnt);
extern void scsi_old_times_out(Scsi_Cmnd * SCpnt);
-struct dev_info {
- const char *vendor;
- const char *model;
- const char *revision; /* Latest revision known to be bad. Not used yet */
- unsigned flags;
-};
/*
- * This is what was previously known as the blacklist. The concept
- * has been expanded so that we can specify other types of things we
- * need to be aware of.
- */
-static struct dev_info device_list[] =
-{
- {"Aashima", "IMAGERY 2400SP", "1.03", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
- {"CHINON", "CD-ROM CDS-431", "H42", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
- {"CHINON", "CD-ROM CDS-535", "Q14", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
- {"DENON", "DRD-25X", "V", BLIST_NOLUN}, /* Locks up if probed for lun != 0 */
- {"HITACHI", "DK312C", "CM81", BLIST_NOLUN}, /* Responds to all lun - dtg */
- {"HITACHI", "DK314C", "CR21", BLIST_NOLUN}, /* responds to all lun */
- {"IMS", "CDD521/10", "2.06", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */
- {"MAXTOR", "XT-3280", "PR02", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */
- {"MAXTOR", "XT-4380S", "B3C", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */
- {"MAXTOR", "MXT-1240S", "I1.2", BLIST_NOLUN}, /* Locks up when LUN>0 polled */
- {"MAXTOR", "XT-4170S", "B5A", BLIST_NOLUN}, /* Locks-up sometimes when LUN>0 polled. */
- {"MAXTOR", "XT-8760S", "B7B", BLIST_NOLUN}, /* guess what? */
- {"MEDIAVIS", "RENO CD-ROMX2A", "2.03", BLIST_NOLUN}, /*Responds to all lun */
- {"MICROP", "4110", "*", BLIST_NOTQ}, /* Buggy Tagged Queuing */
- {"NEC", "CD-ROM DRIVE:841", "1.0", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */
- {"PHILIPS", "PCA80SC", "V4-2", BLIST_NOLUN}, /* Responds to all lun */
- {"RODIME", "RO3000S", "2.33", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
- {"SANYO", "CRD-250S", "1.20", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1
- * for aha152x controller, which causes
- * SCSI code to reset bus.*/
- {"SEAGATE", "ST157N", "\004|j", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1
- * for aha152x controller, which causes
- * SCSI code to reset bus.*/
- {"SEAGATE", "ST296", "921", BLIST_NOLUN}, /* Responds to all lun */
- {"SEAGATE", "ST1581", "6538", BLIST_NOLUN}, /* Responds to all lun */
- {"SONY", "CD-ROM CDU-541", "4.3d", BLIST_NOLUN},
- {"SONY", "CD-ROM CDU-55S", "1.0i", BLIST_NOLUN},
- {"SONY", "CD-ROM CDU-561", "1.7x", BLIST_NOLUN},
- {"SONY", "CD-ROM CDU-8012", "*", BLIST_NOLUN},
- {"TANDBERG", "TDC 3600", "U07", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
- {"TEAC", "CD-R55S", "1.0H", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
- {"TEAC", "CD-ROM", "1.06", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1
- * for seagate controller, which causes
- * SCSI code to reset bus.*/
- {"TEAC", "MT-2ST/45S2-27", "RV M", BLIST_NOLUN}, /* Responds to all lun */
- {"TEXEL", "CD-ROM", "1.06", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1
- * for seagate controller, which causes
- * SCSI code to reset bus.*/
- {"QUANTUM", "LPS525S", "3110", BLIST_NOLUN}, /* Locks sometimes if polled for lun != 0 */
- {"QUANTUM", "PD1225S", "3110", BLIST_NOLUN}, /* Locks sometimes if polled for lun != 0 */
- {"QUANTUM", "FIREBALL ST4.3S", "0F0C", BLIST_NOLUN}, /* Locks up when polled for lun != 0 */
- {"MEDIAVIS", "CDR-H93MV", "1.31", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
- {"SANKYO", "CP525", "6.64", BLIST_NOLUN}, /* causes failed REQ SENSE, extra reset */
- {"HP", "C1750A", "3226", BLIST_NOLUN}, /* scanjet iic */
- {"HP", "C1790A", "", BLIST_NOLUN}, /* scanjet iip */
- {"HP", "C2500A", "", BLIST_NOLUN}, /* scanjet iicx */
- {"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 */
- {"RELISYS", "Scorpio", "*", BLIST_NOLUN}, /* responds to all LUN */
- {"MICROTEK", "ScanMaker II", "5.61", BLIST_NOLUN}, /* responds to all LUN */
-
-/*
- * Other types of devices that have special flags.
+ * Function: scsi_get_request_handler()
+ *
+ * Purpose: Selects queue handler function for a device.
+ *
+ * Arguments: SDpnt - device for which we need a handler function.
+ *
+ * Returns: Nothing
+ *
+ * Lock status: No locking assumed or required.
+ *
+ * Notes: Most devices will end up using scsi_request_fn for the
+ * handler function (at least as things are done now).
+ * The "block" feature basically ensures that only one of
+ * the blocked hosts is active at one time, mainly to work around
+ * buggy DMA chipsets where the memory gets starved.
+ * For this case, we have a special handler function, which
+ * does some checks and ultimately calls scsi_request_fn.
+ *
+ * As a future enhancement, it might be worthwhile to add support
+ * for stacked handlers - there might get to be too many permutations
+ * otherwise. Then again, we might just have one handler that does
+ * all of the special cases (a little bit slower), and those devices
+ * that don't need the special case code would directly call
+ * scsi_request_fn.
+ *
+ * As it stands, I can think of a number of special cases that
+ * we might need to handle. This would not only include the blocked
+ * case, but single_lun (for changers), and any special handling
+ * we might need for a spun-down disk to spin it back up again.
*/
- {"SONY", "CD-ROM CDU-8001", "*", BLIST_BORKEN},
- {"TEXEL", "CD-ROM", "1.06", BLIST_BORKEN},
- {"IOMEGA", "Io20S *F", "*", BLIST_KEY},
- {"INSITE", "Floptical F*8I", "*", BLIST_KEY},
- {"INSITE", "I325VM", "*", BLIST_KEY},
- {"NRC", "MBR-7", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
- {"NRC", "MBR-7.4", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
- {"REGAL", "CDC-4X", "*", BLIST_MAX5LUN | BLIST_SINGLELUN},
- {"NAKAMICH", "MJ-4.8S", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
- {"NAKAMICH", "MJ-5.16S", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
- {"PIONEER", "CD-ROM DRM-600", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
- {"PIONEER", "CD-ROM DRM-602X", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
- {"PIONEER", "CD-ROM DRM-604X", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
- {"EMULEX", "MD21/S2 ESDI", "*", BLIST_SINGLELUN},
- {"CANON", "IPUBJD", "*", BLIST_SPARSELUN},
- {"nCipher", "Fastness Crypto", "*", BLIST_FORCELUN},
- {"NEC", "PD-1 ODX654P", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
- {"MATSHITA", "PD-1", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
- {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
- {"CREATIVE","DVD-RAM RAM","*", BLIST_GHOST},
- {"MATSHITA","PD-2 LF-D100","*", BLIST_GHOST},
- {"HITACHI", "GF-1050","*", BLIST_GHOST}, /* Hitachi SCSI DVD-RAM */
- {"TOSHIBA","CDROM","*", BLIST_ISROM},
- {"TOSHIBA","DVD-RAM SD-W1101","*", BLIST_GHOST},
- {"TOSHIBA","DVD-RAM SD-W1111","*", BLIST_GHOST},
-
- /*
- * Must be at end of list...
- */
- {NULL, NULL, NULL}
-};
-
-static int get_device_flags(unsigned char *response_data)
-{
- int i = 0;
- unsigned char *pnt;
- for (i = 0; 1; i++) {
- if (device_list[i].vendor == NULL)
- return 0;
- pnt = &response_data[8];
- while (*pnt && *pnt == ' ')
- pnt++;
- if (memcmp(device_list[i].vendor, pnt,
- strlen(device_list[i].vendor)))
- continue;
- pnt = &response_data[16];
- while (*pnt && *pnt == ' ')
- pnt++;
- if (memcmp(device_list[i].model, pnt,
- strlen(device_list[i].model)))
- continue;
- return device_list[i].flags;
- }
- return 0;
-}
-
-
-static void scan_scsis_done(Scsi_Cmnd * SCpnt)
-{
-
- SCSI_LOG_MLCOMPLETE(1, printk("scan_scsis_done(%p, %06x)\n", SCpnt->host, SCpnt->result));
- SCpnt->request.rq_status = RQ_SCSI_DONE;
-
- if (SCpnt->request.sem != NULL)
- up(SCpnt->request.sem);
+request_fn_proc * scsi_get_request_handler(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt) {
+ return scsi_request_fn;
}
#ifdef MODULE
@@ -349,43 +205,24 @@ __setup("scsi_logging=", scsi_logging_setup);
#endif
-#ifdef CONFIG_SCSI_MULTI_LUN
-static int max_scsi_luns = 8;
-#else
-static int max_scsi_luns = 1;
-#endif
-
-#ifdef MODULE
-
-MODULE_PARM(max_scsi_luns, "i");
-MODULE_PARM_DESC(max_scsi_luns, "last scsi LUN (should be between 1 and 8)");
-
-#else
-
-static int __init scsi_luns_setup(char *str)
+/*
+ * Issue a command and wait for it to complete
+ */
+
+static void scsi_wait_done(Scsi_Cmnd * SCpnt)
{
- int tmp;
+ struct request *req;
- if (get_option(&str, &tmp) == 1) {
- max_scsi_luns = tmp;
- return 1;
- } else {
- printk("scsi_luns_setup : usage max_scsi_luns=n "
- "(n should be between 1 and 8)\n");
- return 0;
+ req = &SCpnt->request;
+ req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
+
+ if (req->sem != NULL) {
+ up(req->sem);
}
}
-__setup("max_scsi_luns=", scsi_luns_setup);
-
-#endif
-
-/*
- * Issue a command and wait for it to complete
- */
-
void scsi_wait_cmd (Scsi_Cmnd * SCpnt, const void *cmnd ,
- void *buffer, unsigned bufflen, void (*done)(Scsi_Cmnd *),
+ void *buffer, unsigned bufflen,
int timeout, int retries)
{
DECLARE_MUTEX_LOCKED(sem);
@@ -393,595 +230,13 @@ void scsi_wait_cmd (Scsi_Cmnd * SCpnt, const void *cmnd ,
SCpnt->request.sem = &sem;
SCpnt->request.rq_status = RQ_SCSI_BUSY;
scsi_do_cmd (SCpnt, (void *) cmnd,
- buffer, bufflen, done, timeout, retries);
+ buffer, bufflen, scsi_wait_done, timeout, retries);
down (&sem);
SCpnt->request.sem = NULL;
}
/*
- * Detecting SCSI devices :
- * We scan all present host adapter's busses, from ID 0 to ID (max_id).
- * We use the INQUIRY command, determine device type, and pass the ID /
- * lun address of all sequential devices to the tape driver, all random
- * devices to the disk driver.
- */
-static void scan_scsis(struct Scsi_Host *shpnt,
- unchar hardcoded,
- unchar hchannel,
- unchar hid,
- unchar hlun)
-{
- int channel;
- int dev;
- int lun;
- int max_dev_lun;
- Scsi_Cmnd *SCpnt;
- unsigned char *scsi_result;
- unsigned char scsi_result0[256];
- Scsi_Device *SDpnt;
- Scsi_Device *SDtail;
- int sparse_lun;
-
- scsi_result = NULL;
- SCpnt = (Scsi_Cmnd *) scsi_init_malloc(sizeof(Scsi_Cmnd),
- GFP_ATOMIC | GFP_DMA);
- if (SCpnt) {
- SDpnt = (Scsi_Device *) scsi_init_malloc(sizeof(Scsi_Device),
- GFP_ATOMIC);
- if (SDpnt) {
- /*
- * Register the queue for the device. All I/O requests will come
- * in through here. We also need to register a pointer to
- * ourselves, since the queue handler won't know what device
- * the queue actually represents. We could look it up, but it
- * is pointless work.
- */
- blk_init_queue(&SDpnt->request_queue, scsi_request_fn);
- blk_queue_headactive(&SDpnt->request_queue, 0);
- SDpnt->request_queue.queuedata = (void *) SDpnt;
- /* Make sure we have something that is valid for DMA purposes */
- scsi_result = ((!shpnt->unchecked_isa_dma)
- ? &scsi_result0[0] : scsi_init_malloc(512, GFP_DMA));
- }
- }
- if (scsi_result == NULL) {
- printk("Unable to obtain scsi_result buffer\n");
- goto leave;
- }
- /*
- * We must chain ourself in the host_queue, so commands can time out
- */
- SCpnt->next = NULL;
- SDpnt->device_queue = SCpnt;
- SDpnt->host = shpnt;
- SDpnt->online = TRUE;
-
- initialize_merge_fn(SDpnt);
-
- /*
- * Initialize the object that we will use to wait for command blocks.
- */
- init_waitqueue_head(&SDpnt->scpnt_wait);
-
- /*
- * Next, hook the device to the host in question.
- */
- SDpnt->prev = NULL;
- SDpnt->next = NULL;
- if (shpnt->host_queue != NULL) {
- SDtail = shpnt->host_queue;
- while (SDtail->next != NULL)
- SDtail = SDtail->next;
-
- SDtail->next = SDpnt;
- SDpnt->prev = SDtail;
- } else {
- shpnt->host_queue = SDpnt;
- }
-
- /*
- * We need to increment the counter for this one device so we can track when
- * things are quiet.
- */
- atomic_inc(&shpnt->host_active);
- atomic_inc(&SDpnt->device_active);
-
- if (hardcoded == 1) {
- Scsi_Device *oldSDpnt = SDpnt;
- struct Scsi_Device_Template *sdtpnt;
- channel = hchannel;
- if (channel > shpnt->max_channel)
- goto leave;
- dev = hid;
- if (dev >= shpnt->max_id)
- goto leave;
- lun = hlun;
- if (lun >= shpnt->max_lun)
- goto leave;
- scan_scsis_single(channel, dev, lun, &max_dev_lun, &sparse_lun,
- &SDpnt, SCpnt, shpnt, scsi_result);
- if (SDpnt != oldSDpnt) {
-
- /* it could happen the blockdevice hasn't yet been inited */
- for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if (sdtpnt->init && sdtpnt->dev_noticed)
- (*sdtpnt->init) ();
-
- for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) {
- if (sdtpnt->attach) {
- (*sdtpnt->attach) (oldSDpnt);
- if (oldSDpnt->attached) {
- scsi_build_commandblocks(oldSDpnt);
- if (0 == oldSDpnt->has_cmdblocks) {
- printk("scan_scsis: DANGER, no command blocks\n");
- /* What to do now ?? */
- }
- }
- }
- }
- resize_dma_pool();
-
- for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) {
- if (sdtpnt->finish && sdtpnt->nr_dev) {
- (*sdtpnt->finish) ();
- }
- }
- }
- } else {
- /* Actual LUN. PC ordering is 0->n IBM/spec ordering is n->0 */
- int order_dev;
-
- for (channel = 0; channel <= shpnt->max_channel; channel++) {
- for (dev = 0; dev < shpnt->max_id; ++dev) {
- if (shpnt->reverse_ordering)
- /* Shift to scanning 15,14,13... or 7,6,5,4, */
- order_dev = shpnt->max_id - dev - 1;
- else
- order_dev = dev;
-
- if (shpnt->this_id != order_dev) {
-
- /*
- * We need the for so our continue, etc. work fine. We put this in
- * a variable so that we can override it during the scan if we
- * detect a device *KNOWN* to have multiple logical units.
- */
- max_dev_lun = (max_scsi_luns < shpnt->max_lun ?
- max_scsi_luns : shpnt->max_lun);
- sparse_lun = 0;
- for (lun = 0; lun < max_dev_lun; ++lun) {
- if (!scan_scsis_single(channel, order_dev, lun, &max_dev_lun,
- &sparse_lun, &SDpnt, SCpnt, shpnt,
- scsi_result)
- && !sparse_lun)
- break; /* break means don't probe further for luns!=0 */
- } /* for lun ends */
- } /* if this_id != id ends */
- } /* for dev ends */
- } /* for channel ends */
- } /* if/else hardcoded */
-
- /*
- * We need to decrement the counter for this one device
- * so we know when everything is quiet.
- */
- atomic_dec(&shpnt->host_active);
- atomic_dec(&SDpnt->device_active);
-
- leave:
-
- { /* Unchain SCpnt from host_queue */
- Scsi_Device *prev, *next;
- Scsi_Device *dqptr;
-
- for (dqptr = shpnt->host_queue; dqptr != SDpnt; dqptr = dqptr->next)
- continue;
- if (dqptr) {
- prev = dqptr->prev;
- next = dqptr->next;
- if (prev)
- prev->next = next;
- else
- shpnt->host_queue = next;
- if (next)
- next->prev = prev;
- }
- }
-
- /* Last device block does not exist. Free memory. */
- if (SDpnt != NULL)
- scsi_init_free((char *) SDpnt, sizeof(Scsi_Device));
-
- if (SCpnt != NULL)
- scsi_init_free((char *) SCpnt, sizeof(Scsi_Cmnd));
-
- /* If we allocated a buffer so we could do DMA, free it now */
- if (scsi_result != &scsi_result0[0] && scsi_result != NULL) {
- scsi_init_free(scsi_result, 512);
- } {
- Scsi_Device *sdev;
- Scsi_Cmnd *scmd;
-
- SCSI_LOG_SCAN_BUS(4, printk("Host status for host %p:\n", shpnt));
- for (sdev = shpnt->host_queue; sdev; sdev = sdev->next) {
- SCSI_LOG_SCAN_BUS(4, printk("Device %d %p: ", sdev->id, sdev));
- for (scmd = sdev->device_queue; scmd; scmd = scmd->next) {
- SCSI_LOG_SCAN_BUS(4, printk("%p ", scmd));
- }
- SCSI_LOG_SCAN_BUS(4, printk("\n"));
- }
- }
-}
-
-/*
- * The worker for scan_scsis.
- * Returning 0 means Please don't ask further for lun!=0, 1 means OK go on.
- * Global variables used : scsi_devices(linked list)
- */
-int scan_scsis_single(int channel, int dev, int lun, int *max_dev_lun,
- int *sparse_lun, Scsi_Device ** SDpnt2, Scsi_Cmnd * SCpnt,
- struct Scsi_Host *shpnt, char *scsi_result)
-{
- unsigned char scsi_cmd[12];
- struct Scsi_Device_Template *sdtpnt;
- Scsi_Device *SDtail, *SDpnt = *SDpnt2;
- int bflags, type = -1;
- static int ghost_channel=-1, ghost_dev=-1;
- int org_lun = lun;
-
- SDpnt->host = shpnt;
- SDpnt->id = dev;
- SDpnt->lun = lun;
- SDpnt->channel = channel;
- SDpnt->online = TRUE;
-
-
- if ((channel == ghost_channel) && (dev == ghost_dev) && (lun == 1)) {
- SDpnt->lun = 0;
- } else {
- ghost_channel = ghost_dev = -1;
- }
-
-
- /* Some low level driver could use device->type (DB) */
- SDpnt->type = -1;
-
- /*
- * Assume that the device will have handshaking problems, and then fix this
- * field later if it turns out it doesn't
- */
- SDpnt->borken = 1;
- SDpnt->was_reset = 0;
- SDpnt->expecting_cc_ua = 0;
- SDpnt->starved = 0;
-
- scsi_cmd[0] = TEST_UNIT_READY;
- scsi_cmd[1] = lun << 5;
- scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[4] = scsi_cmd[5] = 0;
-
- SCpnt->host = SDpnt->host;
- SCpnt->device = SDpnt;
- SCpnt->target = SDpnt->id;
- SCpnt->lun = SDpnt->lun;
- SCpnt->channel = SDpnt->channel;
-
- scsi_wait_cmd (SCpnt, (void *) scsi_cmd,
- (void *) NULL,
- 0, scan_scsis_done, SCSI_TIMEOUT + 4 * HZ, 5);
-
- SCSI_LOG_SCAN_BUS(3, printk("scsi: scan_scsis_single id %d lun %d. Return code 0x%08x\n",
- dev, lun, SCpnt->result));
- SCSI_LOG_SCAN_BUS(3, print_driverbyte(SCpnt->result));
- SCSI_LOG_SCAN_BUS(3, print_hostbyte(SCpnt->result));
- SCSI_LOG_SCAN_BUS(3, printk("\n"));
-
- if (SCpnt->result) {
- if (((driver_byte(SCpnt->result) & DRIVER_SENSE) ||
- (status_byte(SCpnt->result) & CHECK_CONDITION)) &&
- ((SCpnt->sense_buffer[0] & 0x70) >> 4) == 7) {
- if (((SCpnt->sense_buffer[2] & 0xf) != NOT_READY) &&
- ((SCpnt->sense_buffer[2] & 0xf) != UNIT_ATTENTION) &&
- ((SCpnt->sense_buffer[2] & 0xf) != ILLEGAL_REQUEST || lun > 0))
- return 1;
- } else
- return 0;
- }
- SCSI_LOG_SCAN_BUS(3, printk("scsi: performing INQUIRY\n"));
- /*
- * Build an INQUIRY command block.
- */
- scsi_cmd[0] = INQUIRY;
- scsi_cmd[1] = (lun << 5) & 0xe0;
- scsi_cmd[2] = 0;
- scsi_cmd[3] = 0;
- scsi_cmd[4] = 255;
- scsi_cmd[5] = 0;
- SCpnt->cmd_len = 0;
-
- scsi_wait_cmd (SCpnt, (void *) scsi_cmd,
- (void *) scsi_result,
- 256, scan_scsis_done, SCSI_TIMEOUT, 3);
-
- SCSI_LOG_SCAN_BUS(3, printk("scsi: INQUIRY %s with code 0x%x\n",
- SCpnt->result ? "failed" : "successful", SCpnt->result));
-
- if (SCpnt->result)
- return 0; /* assume no peripheral if any sort of error */
-
- /*
- * Check the peripheral qualifier field - this tells us whether LUNS
- * are supported here or not.
- */
- if ((scsi_result[0] >> 5) == 3) {
- return 0; /* assume no peripheral if any sort of error */
- }
-
- /*
- * Get any flags for this device.
- */
- bflags = get_device_flags (scsi_result);
-
-
- /* The Toshiba ROM was "gender-changed" here as an inline hack.
- This is now much more generic.
- This is a mess: What we really want is to leave the scsi_result
- alone, and just change the SDpnt structure. And the SDpnt is what
- we want print_inquiry to print. -- REW
- */
- if (bflags & BLIST_ISDISK) {
- scsi_result[0] = TYPE_DISK;
- scsi_result[1] |= 0x80; /* removable */
- }
-
- if (bflags & BLIST_ISROM) {
- scsi_result[0] = TYPE_ROM;
- scsi_result[1] |= 0x80; /* removable */
- }
-
- if (bflags & BLIST_GHOST) {
- if ((ghost_channel == channel) && (ghost_dev == dev) && (org_lun == 1)) {
- lun=1;
- } else {
- ghost_channel = channel;
- ghost_dev = dev;
- scsi_result[0] = TYPE_MOD;
- scsi_result[1] |= 0x80; /* removable */
- }
- }
-
-
- memcpy(SDpnt->vendor, scsi_result + 8, 8);
- memcpy(SDpnt->model, scsi_result + 16, 16);
- memcpy(SDpnt->rev, scsi_result + 32, 4);
-
- SDpnt->removable = (0x80 & scsi_result[1]) >> 7;
- SDpnt->online = TRUE;
- SDpnt->lockable = SDpnt->removable;
- SDpnt->changed = 0;
- SDpnt->access_count = 0;
- SDpnt->busy = 0;
- SDpnt->has_cmdblocks = 0;
- /*
- * Currently, all sequential devices are assumed to be tapes, all random
- * devices disk, with the appropriate read only flags set for ROM / WORM
- * treated as RO.
- */
- switch (type = (scsi_result[0] & 0x1f)) {
- case TYPE_TAPE:
- case TYPE_DISK:
- case TYPE_MOD:
- case TYPE_PROCESSOR:
- case TYPE_SCANNER:
- case TYPE_MEDIUM_CHANGER:
- case TYPE_ENCLOSURE:
- SDpnt->writeable = 1;
- break;
- case TYPE_WORM:
- case TYPE_ROM:
- SDpnt->writeable = 0;
- break;
- default:
- printk("scsi: unknown type %d\n", type);
- }
-
- SDpnt->device_blocked = FALSE;
- SDpnt->device_busy = 0;
- SDpnt->single_lun = 0;
- SDpnt->soft_reset =
- (scsi_result[7] & 1) && ((scsi_result[3] & 7) == 2);
- SDpnt->random = (type == TYPE_TAPE) ? 0 : 1;
- SDpnt->type = (type & 0x1f);
-
- print_inquiry(scsi_result);
-
- for (sdtpnt = scsi_devicelist; sdtpnt;
- sdtpnt = sdtpnt->next)
- if (sdtpnt->detect)
- SDpnt->attached +=
- (*sdtpnt->detect) (SDpnt);
-
- SDpnt->scsi_level = scsi_result[2] & 0x07;
- if (SDpnt->scsi_level >= 2 ||
- (SDpnt->scsi_level == 1 &&
- (scsi_result[3] & 0x0f) == 1))
- SDpnt->scsi_level++;
-
- /*
- * Accommodate drivers that want to sleep when they should be in a polling
- * loop.
- */
- SDpnt->disconnect = 0;
-
-
- /*
- * Set the tagged_queue flag for SCSI-II devices that purport to support
- * tagged queuing in the INQUIRY data.
- */
- SDpnt->tagged_queue = 0;
- if ((SDpnt->scsi_level >= SCSI_2) &&
- (scsi_result[7] & 2) &&
- !(bflags & BLIST_NOTQ)) {
- SDpnt->tagged_supported = 1;
- SDpnt->current_tag = 0;
- }
- /*
- * Some revisions of the Texel CD ROM drives have handshaking problems when
- * used with the Seagate controllers. Before we know what type of device
- * we're talking to, we assume it's borken and then change it here if it
- * turns out that it isn't a TEXEL drive.
- */
- if ((bflags & BLIST_BORKEN) == 0)
- SDpnt->borken = 0;
-
- /*
- * 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.
- */
- if (bflags & BLIST_SINGLELUN)
- SDpnt->single_lun = 1;
-
- /*
- * These devices need this "key" to unlock the devices so we can use it
- */
- if ((bflags & BLIST_KEY) != 0) {
- printk("Unlocked floptical drive.\n");
- SDpnt->lockable = 0;
- scsi_cmd[0] = MODE_SENSE;
- scsi_cmd[1] = (lun << 5) & 0xe0;
- scsi_cmd[2] = 0x2e;
- scsi_cmd[3] = 0;
- scsi_cmd[4] = 0x2a;
- scsi_cmd[5] = 0;
- SCpnt->cmd_len = 0;
- scsi_wait_cmd (SCpnt, (void *) scsi_cmd,
- (void *) scsi_result, 0x2a,
- scan_scsis_done, SCSI_TIMEOUT, 3);
- }
- /*
- * Detach the command from the device. It was just a temporary to be used while
- * scanning the bus - the real ones will be allocated later.
- */
- SDpnt->device_queue = NULL;
-
- /*
- * This device was already hooked up to the host in question,
- * so at this point we just let go of it and it should be fine. We do need to
- * allocate a new one and attach it to the host so that we can further scan the bus.
- */
- SDpnt = (Scsi_Device *) scsi_init_malloc(sizeof(Scsi_Device), GFP_ATOMIC);
- *SDpnt2 = SDpnt;
- if (!SDpnt) {
- printk("scsi: scan_scsis_single: Cannot malloc\n");
- return 0;
- }
- /*
- * Register the queue for the device. All I/O requests will come
- * in through here. We also need to register a pointer to
- * ourselves, since the queue handler won't know what device
- * the queue actually represents. We could look it up, but it
- * is pointless work.
- */
- blk_init_queue(&SDpnt->request_queue, scsi_request_fn);
- blk_queue_headactive(&SDpnt->request_queue, 0);
- SDpnt->request_queue.queuedata = (void *) SDpnt;
- SDpnt->host = shpnt;
- initialize_merge_fn(SDpnt);
-
- /*
- * And hook up our command block to the new device we will be testing
- * for.
- */
- SDpnt->device_queue = SCpnt;
- SDpnt->online = TRUE;
-
- /*
- * Initialize the object that we will use to wait for command blocks.
- */
- init_waitqueue_head(&SDpnt->scpnt_wait);
-
- /*
- * Since we just found one device, there had damn well better be one in the list
- * already.
- */
- if (shpnt->host_queue == NULL)
- panic("scan_scsis_single: Host queue == NULL\n");
-
- SDtail = shpnt->host_queue;
- while (SDtail->next) {
- SDtail = SDtail->next;
- }
-
- /* Add this device to the linked list at the end */
- SDtail->next = SDpnt;
- SDpnt->prev = SDtail;
- SDpnt->next = NULL;
-
- /*
- * Some scsi devices cannot be polled for lun != 0 due to firmware bugs
- */
- if (bflags & BLIST_NOLUN)
- return 0; /* break; */
-
- /*
- * If this device is known to support sparse multiple units, override the
- * other settings, and scan all of them.
- */
- if (bflags & BLIST_SPARSELUN) {
- *max_dev_lun = 8;
- *sparse_lun = 1;
- return 1;
- }
- /*
- * If this device is known to support multiple units, override the other
- * settings, and scan all of them.
- */
- if (bflags & BLIST_FORCELUN) {
- *max_dev_lun = 8;
- return 1;
- }
- /*
- * REGAL CDC-4X: avoid hang after LUN 4
- */
- if (bflags & BLIST_MAX5LUN) {
- *max_dev_lun = 5;
- return 1;
- }
-
- /*
- * If this device is Ghosted, scan upto two luns. (It physically only
- * has one). -- REW
- */
- if (bflags & BLIST_GHOST) {
- *max_dev_lun = 2;
- return 1;
- }
-
-
- /*
- * We assume the device can't handle lun!=0 if: - it reports scsi-0 (ANSI
- * SCSI Revision 0) (old drives like MAXTOR XT-3280) or - it reports scsi-1
- * (ANSI SCSI Revision 1) and Response Data Format 0
- */
- if (((scsi_result[2] & 0x07) == 0)
- ||
- ((scsi_result[2] & 0x07) == 1 &&
- (scsi_result[3] & 0x0f) == 0))
- return 0;
- return 1;
-}
-
-/*
- * Flag bits for the internal_timeout array
- */
-#define NORMAL_TIMEOUT 0
-#define IN_ABORT 1
-#define IN_RESET 2
-#define IN_RESET2 4
-#define IN_RESET3 8
-
-
-/*
* This lock protects the freelist for all devices on the system.
* We could make this finer grained by having a single lock per
* device if it is ever found that there is excessive contention
@@ -990,11 +245,6 @@ int scan_scsis_single(int channel, int dev, int lun, int *max_dev_lun,
static spinlock_t device_request_lock = SPIN_LOCK_UNLOCKED;
/*
- * Used for access to internal allocator used for DMA safe buffers.
- */
-static spinlock_t allocator_request_lock = SPIN_LOCK_UNLOCKED;
-
-/*
* Used to protect insertion into and removal from the queue of
* commands to be processed by the bottom half handler.
*/
@@ -1465,7 +715,8 @@ void scsi_do_cmd(Scsi_Cmnd * SCpnt, const void *cmnd,
* the completion function for the high level driver.
*/
- memcpy((void *) SCpnt->data_cmnd, (const void *) cmnd, 12);
+ memcpy((void *) SCpnt->data_cmnd, (const void *) cmnd,
+ sizeof(SCpnt->data_cmnd));
SCpnt->reset_chain = NULL;
SCpnt->serial_number = 0;
SCpnt->serial_number_at_timeout = 0;
@@ -1477,7 +728,8 @@ void scsi_do_cmd(Scsi_Cmnd * SCpnt, const void *cmnd,
SCpnt->done = done;
SCpnt->timeout_per_command = timeout;
- memcpy((void *) SCpnt->cmnd, (const void *) cmnd, 12);
+ memcpy((void *) SCpnt->cmnd, (const void *) cmnd,
+ sizeof(SCpnt->cmnd));
/* Zero the sense buffer. Some host adapters automatically request
* sense on error. 0 is not a valid sense code.
*/
@@ -1820,127 +1072,6 @@ static int scsi_register_host(Scsi_Host_Template *);
static void scsi_unregister_host(Scsi_Host_Template *);
#endif
-/*
- * Function: scsi_malloc
- *
- * Purpose: Allocate memory from the DMA-safe pool.
- *
- * Arguments: len - amount of memory we need.
- *
- * Lock status: No locks assumed to be held. This function is SMP-safe.
- *
- * Returns: Pointer to memory block.
- *
- * Notes: Prior to the new queue code, this function was not SMP-safe.
- * This function can only allocate in units of sectors
- * (i.e. 512 bytes).
- *
- * We cannot use the normal system allocator becuase we need
- * to be able to guarantee that we can process a complete disk
- * I/O request without touching the system allocator. Think
- * about it - if the system were heavily swapping, and tried to
- * write out a block of memory to disk, and the SCSI code needed
- * to allocate more memory in order to be able to write the
- * data to disk, you would wedge the system.
- */
-void *scsi_malloc(unsigned int len)
-{
- unsigned int nbits, mask;
- unsigned long flags;
-
- int i, j;
- if (len % SECTOR_SIZE != 0 || len > PAGE_SIZE)
- return NULL;
-
- nbits = len >> 9;
- mask = (1 << nbits) - 1;
-
- spin_lock_irqsave(&allocator_request_lock, flags);
-
- for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++)
- for (j = 0; j <= SECTORS_PER_PAGE - nbits; j++) {
- if ((dma_malloc_freelist[i] & (mask << j)) == 0) {
- dma_malloc_freelist[i] |= (mask << j);
- scsi_dma_free_sectors -= nbits;
-#ifdef DEBUG
- SCSI_LOG_MLQUEUE(3, printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9)));
- printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9));
-#endif
- spin_unlock_irqrestore(&allocator_request_lock, flags);
- return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9));
- }
- }
- spin_unlock_irqrestore(&allocator_request_lock, flags);
- return NULL; /* Nope. No more */
-}
-
-/*
- * Function: scsi_free
- *
- * Purpose: Free memory into the DMA-safe pool.
- *
- * Arguments: ptr - data block we are freeing.
- * len - size of block we are freeing.
- *
- * Lock status: No locks assumed to be held. This function is SMP-safe.
- *
- * Returns: Nothing
- *
- * Notes: This function *must* only be used to free memory
- * allocated from scsi_malloc().
- *
- * Prior to the new queue code, this function was not SMP-safe.
- * This function can only allocate in units of sectors
- * (i.e. 512 bytes).
- */
-int scsi_free(void *obj, unsigned int len)
-{
- unsigned int page, sector, nbits, mask;
- unsigned long flags;
-
-#ifdef DEBUG
- unsigned long ret = 0;
-
-#ifdef __mips__
- __asm__ __volatile__("move\t%0,$31":"=r"(ret));
-#else
- ret = __builtin_return_address(0);
-#endif
- printk("scsi_free %p %d\n", obj, len);
- SCSI_LOG_MLQUEUE(3, printk("SFree: %p %d\n", obj, len));
-#endif
-
- spin_lock_irqsave(&allocator_request_lock, flags);
-
- 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;
- mask = (1 << nbits) - 1;
-
- if ((mask << sector) >= (1 << SECTORS_PER_PAGE))
- panic("scsi_free:Bad memory alignment");
-
- if ((dma_malloc_freelist[page] &
- (mask << sector)) != (mask << sector)) {
-#ifdef DEBUG
- printk("scsi_free(obj=%p, len=%d) called from %08lx\n",
- obj, len, ret);
-#endif
- panic("scsi_free:Trying to free unused memory");
- }
- scsi_dma_free_sectors += nbits;
- dma_malloc_freelist[page] &= ~(mask << sector);
- spin_unlock_irqrestore(&allocator_request_lock, flags);
- return 0;
- }
- }
- panic("scsi_free:Bad offset");
-}
-
int scsi_loadable_module_flag; /* Set after we scan builtin drivers */
@@ -2124,7 +1255,7 @@ int __init scsi_dev_init(void)
/*
* This should build the DMA pool.
*/
- resize_dma_pool();
+ scsi_resize_dma_pool();
/*
* OK, now we finish the initialization by doing spin-up, read
@@ -2140,47 +1271,6 @@ int __init scsi_dev_init(void)
}
#endif /* MODULE */ /* } */
-static void print_inquiry(unsigned char *data)
-{
- int i;
-
- printk(" Vendor: ");
- for (i = 8; i < 16; i++) {
- if (data[i] >= 0x20 && i < data[4] + 5)
- printk("%c", data[i]);
- else
- printk(" ");
- }
-
- printk(" Model: ");
- for (i = 16; i < 32; i++) {
- if (data[i] >= 0x20 && i < data[4] + 5)
- printk("%c", data[i]);
- else
- printk(" ");
- }
-
- printk(" Rev: ");
- for (i = 32; i < 36; i++) {
- if (data[i] >= 0x20 && i < data[4] + 5)
- printk("%c", data[i]);
- else
- printk(" ");
- }
-
- printk("\n");
-
- i = data[0] & 0x1f;
-
- printk(" Type: %s ",
- i < MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] : "Unknown ");
- printk(" ANSI SCSI revision: %02x", data[2] & 0x07);
- if ((data[2] & 0x07) == 1 && (data[3] & 0x0f) == 1)
- printk(" CCS\n");
- else
- printk("\n");
-}
-
#ifdef CONFIG_PROC_FS
static int scsi_proc_info(char *buffer, char **start, off_t offset, int length)
{
@@ -2475,217 +1565,6 @@ out:
}
#endif
-/*
- * Function: resize_dma_pool
- *
- * Purpose: Ensure that the DMA pool is sufficiently large to be
- * able to guarantee that we can always process I/O requests
- * without calling the system allocator.
- *
- * Arguments: None.
- *
- * Lock status: No locks assumed to be held. This function is SMP-safe.
- *
- * Returns: Nothing
- *
- * Notes: Prior to the new queue code, this function was not SMP-safe.
- * Go through the device list and recompute the most appropriate
- * size for the dma pool. Then grab more memory (as required).
- */
-static void resize_dma_pool(void)
-{
- int i, k;
- unsigned long size;
- unsigned long flags;
- struct Scsi_Host *shpnt;
- struct Scsi_Host *host = NULL;
- Scsi_Device *SDpnt;
- FreeSectorBitmap *new_dma_malloc_freelist = NULL;
- unsigned int new_dma_sectors = 0;
- unsigned int new_need_isa_buffer = 0;
- unsigned char **new_dma_malloc_pages = NULL;
- int out_of_space = 0;
-
- spin_lock_irqsave(&allocator_request_lock, flags);
-
- if (!scsi_hostlist) {
- /*
- * Free up the DMA pool.
- */
- if (scsi_dma_free_sectors != dma_sectors)
- panic("SCSI DMA pool memory leak %d %d\n", scsi_dma_free_sectors, dma_sectors);
-
- for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++)
- scsi_init_free(dma_malloc_pages[i], PAGE_SIZE);
- if (dma_malloc_pages)
- scsi_init_free((char *) dma_malloc_pages,
- (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages));
- dma_malloc_pages = NULL;
- if (dma_malloc_freelist)
- scsi_init_free((char *) dma_malloc_freelist,
- (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_freelist));
- dma_malloc_freelist = NULL;
- dma_sectors = 0;
- scsi_dma_free_sectors = 0;
- spin_unlock_irqrestore(&allocator_request_lock, flags);
- return;
- }
- /* Next, check to see if we need to extend the DMA buffer pool */
-
- new_dma_sectors = 2 * SECTORS_PER_PAGE; /* Base value we use */
-
- if (__pa(high_memory) - 1 > ISA_DMA_THRESHOLD)
- need_isa_bounce_buffers = 1;
- else
- need_isa_bounce_buffers = 0;
-
- if (scsi_devicelist)
- for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next)
- new_dma_sectors += SECTORS_PER_PAGE; /* Increment for each host */
-
- for (host = scsi_hostlist; host; host = host->next) {
- for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
- /*
- * sd and sr drivers allocate scatterlists.
- * sr drivers may allocate for each command 1x2048 or 2x1024 extra
- * buffers for 2k sector size and 1k fs.
- * sg driver allocates buffers < 4k.
- * st driver does not need buffers from the dma pool.
- * estimate 4k buffer/command for devices of unknown type (should panic).
- */
- if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM ||
- SDpnt->type == TYPE_DISK || SDpnt->type == TYPE_MOD) {
- new_dma_sectors += ((host->sg_tablesize *
- sizeof(struct scatterlist) + 511) >> 9) *
- SDpnt->queue_depth;
- if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM)
- new_dma_sectors += (2048 >> 9) * SDpnt->queue_depth;
- } else if (SDpnt->type == TYPE_SCANNER ||
- SDpnt->type == TYPE_PROCESSOR ||
- SDpnt->type == TYPE_MEDIUM_CHANGER ||
- SDpnt->type == TYPE_ENCLOSURE) {
- new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth;
- } else {
- if (SDpnt->type != TYPE_TAPE) {
- printk("resize_dma_pool: unknown device type %d\n", SDpnt->type);
- new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth;
- }
- }
-
- if (host->unchecked_isa_dma &&
- need_isa_bounce_buffers &&
- SDpnt->type != TYPE_TAPE) {
- new_dma_sectors += (PAGE_SIZE >> 9) * host->sg_tablesize *
- SDpnt->queue_depth;
- new_need_isa_buffer++;
- }
- }
- }
-
-#ifdef DEBUG_INIT
- printk("resize_dma_pool: needed dma sectors = %d\n", new_dma_sectors);
-#endif
-
- /* limit DMA memory to 32MB: */
- new_dma_sectors = (new_dma_sectors + 15) & 0xfff0;
-
- /*
- * We never shrink the buffers - this leads to
- * race conditions that I would rather not even think
- * about right now.
- */
-#if 0 /* Why do this? No gain and risks out_of_space */
- if (new_dma_sectors < dma_sectors)
- new_dma_sectors = dma_sectors;
-#endif
- if (new_dma_sectors <= dma_sectors) {
- spin_unlock_irqrestore(&allocator_request_lock, flags);
- return; /* best to quit while we are in front */
- }
-
- for (k = 0; k < 20; ++k) { /* just in case */
- out_of_space = 0;
- size = (new_dma_sectors / SECTORS_PER_PAGE) *
- sizeof(FreeSectorBitmap);
- new_dma_malloc_freelist = (FreeSectorBitmap *)
- scsi_init_malloc(size, GFP_ATOMIC);
- if (new_dma_malloc_freelist) {
- size = (new_dma_sectors / SECTORS_PER_PAGE) *
- sizeof(*new_dma_malloc_pages);
- new_dma_malloc_pages = (unsigned char **)
- scsi_init_malloc(size, GFP_ATOMIC);
- if (!new_dma_malloc_pages) {
- size = (new_dma_sectors / SECTORS_PER_PAGE) *
- sizeof(FreeSectorBitmap);
- scsi_init_free((char *) new_dma_malloc_freelist, size);
- out_of_space = 1;
- }
- } else
- out_of_space = 1;
-
- if ((!out_of_space) && (new_dma_sectors > dma_sectors)) {
- for (i = dma_sectors / SECTORS_PER_PAGE;
- i < new_dma_sectors / SECTORS_PER_PAGE; i++) {
- new_dma_malloc_pages[i] = (unsigned char *)
- scsi_init_malloc(PAGE_SIZE, GFP_ATOMIC | GFP_DMA);
- if (!new_dma_malloc_pages[i])
- break;
- }
- if (i != new_dma_sectors / SECTORS_PER_PAGE) { /* clean up */
- int k = i;
-
- out_of_space = 1;
- for (i = 0; i < k; ++i)
- scsi_init_free(new_dma_malloc_pages[i], PAGE_SIZE);
- }
- }
- if (out_of_space) { /* try scaling down new_dma_sectors request */
- printk("scsi::resize_dma_pool: WARNING, dma_sectors=%u, "
- "wanted=%u, scaling\n", dma_sectors, new_dma_sectors);
- if (new_dma_sectors < (8 * SECTORS_PER_PAGE))
- break; /* pretty well hopeless ... */
- new_dma_sectors = (new_dma_sectors * 3) / 4;
- new_dma_sectors = (new_dma_sectors + 15) & 0xfff0;
- if (new_dma_sectors <= dma_sectors)
- break; /* stick with what we have got */
- } else
- break; /* found space ... */
- } /* end of for loop */
- if (out_of_space) {
- spin_unlock_irqrestore(&allocator_request_lock, flags);
- scsi_need_isa_buffer = new_need_isa_buffer; /* some useful info */
- printk(" WARNING, not enough memory, pool not expanded\n");
- return;
- }
- /* When we dick with the actual DMA list, we need to
- * protect things
- */
- if (dma_malloc_freelist) {
- size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(FreeSectorBitmap);
- memcpy(new_dma_malloc_freelist, dma_malloc_freelist, size);
- scsi_init_free((char *) dma_malloc_freelist, size);
- }
- dma_malloc_freelist = new_dma_malloc_freelist;
-
- if (dma_malloc_pages) {
- size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages);
- memcpy(new_dma_malloc_pages, dma_malloc_pages, size);
- scsi_init_free((char *) dma_malloc_pages, size);
- }
- scsi_dma_free_sectors += new_dma_sectors - dma_sectors;
- dma_malloc_pages = new_dma_malloc_pages;
- dma_sectors = new_dma_sectors;
- scsi_need_isa_buffer = new_need_isa_buffer;
-
- spin_unlock_irqrestore(&allocator_request_lock, flags);
-
-#ifdef DEBUG_INIT
- printk("resize_dma_pool: dma free sectors = %d\n", scsi_dma_free_sectors);
- printk("resize_dma_pool: dma sectors = %d\n", dma_sectors);
- printk("resize_dma_pool: need isa buffers = %d\n", scsi_need_isa_buffer);
-#endif
-}
-
#ifdef CONFIG_MODULES /* a big #ifdef block... */
/*
@@ -2819,7 +1698,7 @@ static int scsi_register_host(Scsi_Host_Template * tpnt)
* Now that we have all of the devices, resize the DMA pool,
* as required. */
if (!out_of_space)
- resize_dma_pool();
+ scsi_resize_dma_pool();
/* This does any final handling that is required. */
@@ -3037,7 +1916,7 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt)
* do the right thing and free everything.
*/
if (!scsi_hosts)
- resize_dma_pool();
+ scsi_resize_dma_pool();
printk("scsi : %d host%s.\n", next_scsi_host,
(next_scsi_host == 1) ? "" : "s");
@@ -3049,7 +1928,6 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt)
(scsi_memory_upper_value - scsi_init_memory_start) / 1024);
#endif
-
/* There were some hosts that were loaded at boot time, so we cannot
do any more than this */
if (tpnt->present)
@@ -3132,7 +2010,7 @@ static int scsi_register_device_module(struct Scsi_Device_Template *tpnt)
if (tpnt->finish && tpnt->nr_dev)
(*tpnt->finish) ();
if (!out_of_space)
- resize_dma_pool();
+ scsi_resize_dma_pool();
MOD_INC_USE_COUNT;
if (out_of_space) {
@@ -3362,6 +2240,11 @@ int init_module(void)
int has_space = 0;
struct proc_dir_entry *generic;
+ if( scsi_init_minimal_dma_pool() != 0 )
+ {
+ return 1;
+ }
+
/*
* This makes /proc/scsi and /proc/scsi/scsi visible.
*/
@@ -3382,39 +2265,6 @@ int init_module(void)
scsi_loadable_module_flag = 1;
- dma_sectors = PAGE_SIZE / SECTOR_SIZE;
- scsi_dma_free_sectors = dma_sectors;
- /*
- * Set up a minimal DMA buffer list - this will be used during scan_scsis
- * in some cases.
- */
-
- /* One bit per sector to indicate free/busy */
- size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(FreeSectorBitmap);
- dma_malloc_freelist = (FreeSectorBitmap *)
- scsi_init_malloc(size, GFP_ATOMIC);
- if (dma_malloc_freelist) {
- /* One pointer per page for the page list */
- dma_malloc_pages = (unsigned char **) scsi_init_malloc(
- (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages),
- GFP_ATOMIC);
- if (dma_malloc_pages) {
- dma_malloc_pages[0] = (unsigned char *)
- scsi_init_malloc(PAGE_SIZE, GFP_ATOMIC | GFP_DMA);
- if (dma_malloc_pages[0])
- has_space = 1;
- }
- }
- if (!has_space) {
- if (dma_malloc_freelist) {
- scsi_init_free((char *) dma_malloc_freelist, size);
- if (dma_malloc_pages)
- scsi_init_free((char *) dma_malloc_pages,
- (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages));
- }
- printk("scsi::init_module: failed, out of memory\n");
- return 1;
- }
/*
* This is where the processing takes place for most everything
* when commands are completed.
@@ -3437,7 +2287,7 @@ void cleanup_module(void)
/*
* Free up the DMA pool.
*/
- resize_dma_pool();
+ scsi_resize_dma_pool();
}
@@ -3491,7 +2341,7 @@ Scsi_Device * scsi_get_host_dev(struct Scsi_Host * SHpnt)
SDpnt->device_queue = SCpnt;
- blk_init_queue(&SDpnt->request_queue, scsi_request_fn);
+ blk_init_queue(&SDpnt->request_queue, scsi_get_request_handler(SDpnt, SDpnt->host));
blk_queue_headactive(&SDpnt->request_queue, 0);
SDpnt->request_queue.queuedata = (void *) SDpnt;
@@ -3519,7 +2369,7 @@ Scsi_Device * scsi_get_host_dev(struct Scsi_Host * SHpnt)
*/
void scsi_free_host_dev(Scsi_Device * SDpnt)
{
- if( SDpnt->id != SDpnt->host->this_id )
+ if( (unsigned char) SDpnt->id != (unsigned char) SDpnt->host->this_id )
{
panic("Attempt to delete wrong device\n");
}
diff --git a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
index b15575eac..f8f615c97 100644
--- a/drivers/scsi/scsi.h
+++ b/drivers/scsi/scsi.h
@@ -365,90 +365,120 @@ typedef struct scsi_cmnd Scsi_Cmnd;
* Initializes all SCSI devices. This scans all scsi busses.
*/
-extern int scsi_dev_init(void);
-
-
-
-void *scsi_malloc(unsigned int);
-int scsi_free(void *, unsigned int);
extern unsigned int scsi_logging_level; /* What do we log? */
extern unsigned int scsi_dma_free_sectors; /* How much room do we have left */
extern unsigned int scsi_need_isa_buffer; /* True if some devices need indirection
* buffers */
-extern void scsi_make_blocked_list(void);
extern volatile int in_scan_scsis;
extern const unsigned char scsi_command_size[8];
+
/*
* These are the error handling functions defined in scsi_error.c
*/
+extern void scsi_times_out(Scsi_Cmnd * SCpnt);
extern void scsi_add_timer(Scsi_Cmnd * SCset, int timeout,
void (*complete) (Scsi_Cmnd *));
-extern void scsi_done(Scsi_Cmnd * SCpnt);
extern int scsi_delete_timer(Scsi_Cmnd * SCset);
extern void scsi_error_handler(void *host);
-extern int scsi_retry_command(Scsi_Cmnd *);
-extern void scsi_finish_command(Scsi_Cmnd *);
extern int scsi_sense_valid(Scsi_Cmnd *);
extern int scsi_decide_disposition(Scsi_Cmnd * SCpnt);
extern int scsi_block_when_processing_errors(Scsi_Device *);
extern void scsi_sleep(int);
+
+/*
+ * Prototypes for functions in scsicam.c
+ */
extern int scsi_partsize(struct buffer_head *bh, unsigned long capacity,
unsigned int *cyls, unsigned int *hds,
unsigned int *secs);
/*
+ * Prototypes for functions in scsi_dma.c
+ */
+void scsi_resize_dma_pool(void);
+int scsi_init_minimal_dma_pool(void);
+void *scsi_malloc(unsigned int);
+int scsi_free(void *, unsigned int);
+
+/*
* Prototypes for functions in scsi_merge.c
*/
extern void recount_segments(Scsi_Cmnd * SCpnt);
+extern void initialize_merge_fn(Scsi_Device * SDpnt);
+
+/*
+ * Prototypes for functions in scsi_queue.c
+ */
+extern int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason);
/*
* Prototypes for functions in scsi_lib.c
*/
-extern void initialize_merge_fn(Scsi_Device * SDpnt);
-extern void scsi_request_fn(request_queue_t * q);
+extern void scsi_maybe_unblock_host(Scsi_Device * SDpnt);
+extern void scsi_blocked_request_fn(request_queue_t * q);
+extern Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, int uptodate,
+ int sectors);
+extern struct Scsi_Device_Template *scsi_get_request_dev(struct request *);
+extern int scsi_init_cmd_errh(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);
extern void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt);
+extern void scsi_request_fn(request_queue_t * q);
-extern int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int);
-extern int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt);
/*
* Prototypes for functions in scsi.c
*/
-
-/*
- * scsi_abort aborts the current command that is executing on host host.
- * The error code, if non zero is returned in the host byte, otherwise
- * DID_ABORT is returned in the hostbyte.
- */
-
+extern int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt);
+extern void scsi_bottom_half_handler(void);
+extern void scsi_build_commandblocks(Scsi_Device * SDpnt);
+extern void scsi_done(Scsi_Cmnd * SCpnt);
+extern void scsi_finish_command(Scsi_Cmnd *);
+extern int scsi_retry_command(Scsi_Cmnd *);
+extern Scsi_Cmnd *scsi_allocate_device(Scsi_Device *, int, int);
+extern void scsi_release_command(Scsi_Cmnd *);
extern void scsi_do_cmd(Scsi_Cmnd *, const void *cmnd,
void *buffer, unsigned bufflen,
void (*done) (struct scsi_cmnd *),
int timeout, int retries);
-
extern void scsi_wait_cmd(Scsi_Cmnd *, const void *cmnd,
void *buffer, unsigned bufflen,
- void (*done) (struct scsi_cmnd *),
int timeout, int retries);
+extern int scsi_dev_init(void);
-extern Scsi_Cmnd *scsi_allocate_device(Scsi_Device *, int, int);
-
-extern void scsi_release_command(Scsi_Cmnd *);
+/*
+ * Prototypes for functions/data in hosts.c
+ */
extern int max_scsi_hosts;
+/*
+ * Prototypes for functions in scsi_proc.c
+ */
extern void proc_print_scsidevice(Scsi_Device *, char *, int *, int);
extern struct proc_dir_entry *proc_scsi;
+/*
+ * Prototypes for functions in constants.c
+ */
extern void print_command(unsigned char *);
extern void print_sense(const char *, Scsi_Cmnd *);
extern void print_driverbyte(int scsiresult);
extern void print_hostbyte(int scsiresult);
+extern void print_status (int status);
/*
* The scsi_device struct contains what we know about each given scsi
* device.
+ *
+ * FIXME(eric) - one of the great regrets that I have is that I failed to define
+ * these structure elements as something like sdev_foo instead of foo. This would
+ * make it so much easier to grep through sources and so forth. I propose that
+ * all new elements that get added to these structures follow this convention.
+ * As time goes on and as people have the stomach for it, it should be possible to
+ * go back and retrofit at least some of the elements here with with the prefix.
*/
struct scsi_device {
@@ -538,6 +568,14 @@ typedef struct scsi_pointer {
} Scsi_Pointer;
+/*
+ * FIXME(eric) - one of the great regrets that I have is that I failed to define
+ * these structure elements as something like sc_foo instead of foo. This would
+ * make it so much easier to grep through sources and so forth. I propose that
+ * all new elements that get added to these structures follow this convention.
+ * As time goes on and as people have the stomach for it, it should be possible to
+ * go back and retrofit at least some of the elements here with with the prefix.
+ */
struct scsi_cmnd {
/* private: */
/*
@@ -593,14 +631,14 @@ struct scsi_cmnd {
unsigned char old_cmd_len;
/* These elements define the operation we are about to perform */
- unsigned char cmnd[12];
+ unsigned char cmnd[MAX_COMMAND_SIZE];
unsigned request_bufflen; /* Actual request size */
struct timer_list eh_timeout; /* Used to time out the command. */
void *request_buffer; /* Actual requested buffer */
/* These elements define the operation we ultimately want to perform */
- unsigned char data_cmnd[12];
+ unsigned char data_cmnd[MAX_COMMAND_SIZE];
unsigned short old_use_sg; /* We save use_sg here when requesting
* sense info */
unsigned short use_sg; /* Number of pieces of scatter-gather */
@@ -667,13 +705,9 @@ struct scsi_cmnd {
};
/*
- * Flag bits for the internal_timeout array
+ * Flag bit for the internal_timeout array
*/
#define NORMAL_TIMEOUT 0
-#define IN_ABORT 1
-#define IN_RESET 2
-#define IN_RESET2 4
-#define IN_RESET3 8
/*
* Definitions and prototypes used for scsi mid-level queue.
@@ -681,16 +715,6 @@ struct scsi_cmnd {
#define SCSI_MLQUEUE_HOST_BUSY 0x1055
#define SCSI_MLQUEUE_DEVICE_BUSY 0x1056
-extern int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason);
-
-extern Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, int uptodate,
- int sectors);
-
-extern void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
- int block_sectors);
-
-extern struct Scsi_Device_Template *scsi_get_request_dev(struct request *);
-
#define SCSI_SLEEP(QUEUE, CONDITION) { \
if (CONDITION) { \
DECLARE_WAITQUEUE(wait, current); \
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 925c0f8f7..9f36d08c5 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -544,18 +544,6 @@ int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
return 0;
}
-static void sd_test_done(Scsi_Cmnd * SCpnt)
-{
- struct request *req;
-
- req = &SCpnt->request;
- req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
-
- if (req->sem != NULL) {
- up(req->sem);
- }
-}
-
static void scsi_debug_send_self_command(struct Scsi_Host * shpnt)
{
static unsigned char cmd[6] =
@@ -575,7 +563,7 @@ static void scsi_debug_send_self_command(struct Scsi_Host * shpnt)
printk("Sending command\n");
scsi_wait_cmd (scp, (void *) cmd, (void *) NULL,
- 0, sd_test_done, 100, 3);
+ 0, 100, 3);
printk("Releasing command\n");
scsi_release_command(scp);
diff --git a/drivers/scsi/scsi_dma.c b/drivers/scsi/scsi_dma.c
new file mode 100644
index 000000000..c0eb4baa0
--- /dev/null
+++ b/drivers/scsi/scsi_dma.c
@@ -0,0 +1,449 @@
+/*
+ * scsi_dma.c Copyright (C) 2000 Eric Youngdale
+ *
+ * mid-level SCSI DMA bounce buffer allocator
+ *
+ */
+
+#define __NO_VERSION__
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/blk.h>
+
+
+#include "scsi.h"
+#include "hosts.h"
+#include "constants.h"
+
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif
+
+/*
+ * PAGE_SIZE must be a multiple of the sector size (512). True
+ * for all reasonably recent architectures (even the VAX...).
+ */
+#define SECTOR_SIZE 512
+#define SECTORS_PER_PAGE (PAGE_SIZE/SECTOR_SIZE)
+
+#if SECTORS_PER_PAGE <= 8
+typedef unsigned char FreeSectorBitmap;
+#elif SECTORS_PER_PAGE <= 32
+typedef unsigned int FreeSectorBitmap;
+#else
+#error You lose.
+#endif
+
+/*
+ * Used for access to internal allocator used for DMA safe buffers.
+ */
+static spinlock_t allocator_request_lock = SPIN_LOCK_UNLOCKED;
+
+static FreeSectorBitmap *dma_malloc_freelist = NULL;
+static int need_isa_bounce_buffers;
+static unsigned int dma_sectors = 0;
+unsigned int scsi_dma_free_sectors = 0;
+unsigned int scsi_need_isa_buffer = 0;
+static unsigned char **dma_malloc_pages = NULL;
+
+/*
+ * Function: scsi_malloc
+ *
+ * Purpose: Allocate memory from the DMA-safe pool.
+ *
+ * Arguments: len - amount of memory we need.
+ *
+ * Lock status: No locks assumed to be held. This function is SMP-safe.
+ *
+ * Returns: Pointer to memory block.
+ *
+ * Notes: Prior to the new queue code, this function was not SMP-safe.
+ * This function can only allocate in units of sectors
+ * (i.e. 512 bytes).
+ *
+ * We cannot use the normal system allocator becuase we need
+ * to be able to guarantee that we can process a complete disk
+ * I/O request without touching the system allocator. Think
+ * about it - if the system were heavily swapping, and tried to
+ * write out a block of memory to disk, and the SCSI code needed
+ * to allocate more memory in order to be able to write the
+ * data to disk, you would wedge the system.
+ */
+void *scsi_malloc(unsigned int len)
+{
+ unsigned int nbits, mask;
+ unsigned long flags;
+
+ int i, j;
+ if (len % SECTOR_SIZE != 0 || len > PAGE_SIZE)
+ return NULL;
+
+ nbits = len >> 9;
+ mask = (1 << nbits) - 1;
+
+ spin_lock_irqsave(&allocator_request_lock, flags);
+
+ for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++)
+ for (j = 0; j <= SECTORS_PER_PAGE - nbits; j++) {
+ if ((dma_malloc_freelist[i] & (mask << j)) == 0) {
+ dma_malloc_freelist[i] |= (mask << j);
+ scsi_dma_free_sectors -= nbits;
+#ifdef DEBUG
+ SCSI_LOG_MLQUEUE(3, printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9)));
+ printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9));
+#endif
+ spin_unlock_irqrestore(&allocator_request_lock, flags);
+ return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9));
+ }
+ }
+ spin_unlock_irqrestore(&allocator_request_lock, flags);
+ return NULL; /* Nope. No more */
+}
+
+/*
+ * Function: scsi_free
+ *
+ * Purpose: Free memory into the DMA-safe pool.
+ *
+ * Arguments: ptr - data block we are freeing.
+ * len - size of block we are freeing.
+ *
+ * Lock status: No locks assumed to be held. This function is SMP-safe.
+ *
+ * Returns: Nothing
+ *
+ * Notes: This function *must* only be used to free memory
+ * allocated from scsi_malloc().
+ *
+ * Prior to the new queue code, this function was not SMP-safe.
+ * This function can only allocate in units of sectors
+ * (i.e. 512 bytes).
+ */
+int scsi_free(void *obj, unsigned int len)
+{
+ unsigned int page, sector, nbits, mask;
+ unsigned long flags;
+
+#ifdef DEBUG
+ unsigned long ret = 0;
+
+#ifdef __mips__
+ __asm__ __volatile__("move\t%0,$31":"=r"(ret));
+#else
+ ret = __builtin_return_address(0);
+#endif
+ printk("scsi_free %p %d\n", obj, len);
+ SCSI_LOG_MLQUEUE(3, printk("SFree: %p %d\n", obj, len));
+#endif
+
+ spin_lock_irqsave(&allocator_request_lock, flags);
+
+ 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;
+ mask = (1 << nbits) - 1;
+
+ if ((mask << sector) >= (1 << SECTORS_PER_PAGE))
+ panic("scsi_free:Bad memory alignment");
+
+ if ((dma_malloc_freelist[page] &
+ (mask << sector)) != (mask << sector)) {
+#ifdef DEBUG
+ printk("scsi_free(obj=%p, len=%d) called from %08lx\n",
+ obj, len, ret);
+#endif
+ panic("scsi_free:Trying to free unused memory");
+ }
+ scsi_dma_free_sectors += nbits;
+ dma_malloc_freelist[page] &= ~(mask << sector);
+ spin_unlock_irqrestore(&allocator_request_lock, flags);
+ return 0;
+ }
+ }
+ panic("scsi_free:Bad offset");
+}
+
+
+/*
+ * Function: scsi_resize_dma_pool
+ *
+ * Purpose: Ensure that the DMA pool is sufficiently large to be
+ * able to guarantee that we can always process I/O requests
+ * without calling the system allocator.
+ *
+ * Arguments: None.
+ *
+ * Lock status: No locks assumed to be held. This function is SMP-safe.
+ *
+ * Returns: Nothing
+ *
+ * Notes: Prior to the new queue code, this function was not SMP-safe.
+ * Go through the device list and recompute the most appropriate
+ * size for the dma pool. Then grab more memory (as required).
+ */
+void scsi_resize_dma_pool(void)
+{
+ int i, k;
+ unsigned long size;
+ unsigned long flags;
+ struct Scsi_Host *shpnt;
+ struct Scsi_Host *host = NULL;
+ Scsi_Device *SDpnt;
+ FreeSectorBitmap *new_dma_malloc_freelist = NULL;
+ unsigned int new_dma_sectors = 0;
+ unsigned int new_need_isa_buffer = 0;
+ unsigned char **new_dma_malloc_pages = NULL;
+ int out_of_space = 0;
+
+ spin_lock_irqsave(&allocator_request_lock, flags);
+
+ if (!scsi_hostlist) {
+ /*
+ * Free up the DMA pool.
+ */
+ if (scsi_dma_free_sectors != dma_sectors)
+ panic("SCSI DMA pool memory leak %d %d\n", scsi_dma_free_sectors, dma_sectors);
+
+ for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++)
+ free_pages((unsigned long) dma_malloc_pages[i], 0);
+ if (dma_malloc_pages)
+ kfree((char *) dma_malloc_pages);
+ dma_malloc_pages = NULL;
+ if (dma_malloc_freelist)
+ kfree((char *) dma_malloc_freelist);
+ dma_malloc_freelist = NULL;
+ dma_sectors = 0;
+ scsi_dma_free_sectors = 0;
+ spin_unlock_irqrestore(&allocator_request_lock, flags);
+ return;
+ }
+ /* Next, check to see if we need to extend the DMA buffer pool */
+
+ new_dma_sectors = 2 * SECTORS_PER_PAGE; /* Base value we use */
+
+ if (__pa(high_memory) - 1 > ISA_DMA_THRESHOLD)
+ need_isa_bounce_buffers = 1;
+ else
+ need_isa_bounce_buffers = 0;
+
+ if (scsi_devicelist)
+ for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next)
+ new_dma_sectors += SECTORS_PER_PAGE; /* Increment for each host */
+
+ for (host = scsi_hostlist; host; host = host->next) {
+ for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
+ /*
+ * sd and sr drivers allocate scatterlists.
+ * sr drivers may allocate for each command 1x2048 or 2x1024 extra
+ * buffers for 2k sector size and 1k fs.
+ * sg driver allocates buffers < 4k.
+ * st driver does not need buffers from the dma pool.
+ * estimate 4k buffer/command for devices of unknown type (should panic).
+ */
+ if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM ||
+ SDpnt->type == TYPE_DISK || SDpnt->type == TYPE_MOD) {
+ int nents = host->sg_tablesize;
+#ifdef DMA_CHUNK_SIZE
+ /* If the architecture does DMA sg merging, make sure
+ we count with at least 64 entries even for HBAs
+ which handle very few sg entries. */
+ if (nents < 64) nents = 64;
+#endif
+ new_dma_sectors += ((nents *
+ sizeof(struct scatterlist) + 511) >> 9) *
+ SDpnt->queue_depth;
+ if (SDpnt->type == TYPE_WORM || SDpnt->type == TYPE_ROM)
+ new_dma_sectors += (2048 >> 9) * SDpnt->queue_depth;
+ } else if (SDpnt->type == TYPE_SCANNER ||
+ SDpnt->type == TYPE_PROCESSOR ||
+ SDpnt->type == TYPE_MEDIUM_CHANGER ||
+ SDpnt->type == TYPE_ENCLOSURE) {
+ new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth;
+ } else {
+ if (SDpnt->type != TYPE_TAPE) {
+ printk("resize_dma_pool: unknown device type %d\n", SDpnt->type);
+ new_dma_sectors += (4096 >> 9) * SDpnt->queue_depth;
+ }
+ }
+
+ if (host->unchecked_isa_dma &&
+ need_isa_bounce_buffers &&
+ SDpnt->type != TYPE_TAPE) {
+ new_dma_sectors += (PAGE_SIZE >> 9) * host->sg_tablesize *
+ SDpnt->queue_depth;
+ new_need_isa_buffer++;
+ }
+ }
+ }
+
+#ifdef DEBUG_INIT
+ printk("resize_dma_pool: needed dma sectors = %d\n", new_dma_sectors);
+#endif
+
+ /* limit DMA memory to 32MB: */
+ new_dma_sectors = (new_dma_sectors + 15) & 0xfff0;
+
+ /*
+ * We never shrink the buffers - this leads to
+ * race conditions that I would rather not even think
+ * about right now.
+ */
+#if 0 /* Why do this? No gain and risks out_of_space */
+ if (new_dma_sectors < dma_sectors)
+ new_dma_sectors = dma_sectors;
+#endif
+ if (new_dma_sectors <= dma_sectors) {
+ spin_unlock_irqrestore(&allocator_request_lock, flags);
+ return; /* best to quit while we are in front */
+ }
+
+ for (k = 0; k < 20; ++k) { /* just in case */
+ out_of_space = 0;
+ size = (new_dma_sectors / SECTORS_PER_PAGE) *
+ sizeof(FreeSectorBitmap);
+ new_dma_malloc_freelist = (FreeSectorBitmap *)
+ kmalloc(size, GFP_ATOMIC);
+ if (new_dma_malloc_freelist) {
+ memset(new_dma_malloc_freelist, 0, size);
+ size = (new_dma_sectors / SECTORS_PER_PAGE) *
+ sizeof(*new_dma_malloc_pages);
+ new_dma_malloc_pages = (unsigned char **)
+ kmalloc(size, GFP_ATOMIC);
+ if (!new_dma_malloc_pages) {
+ size = (new_dma_sectors / SECTORS_PER_PAGE) *
+ sizeof(FreeSectorBitmap);
+ kfree((char *) new_dma_malloc_freelist);
+ out_of_space = 1;
+ } else {
+ memset(new_dma_malloc_pages, 0, size);
+ }
+ } else
+ out_of_space = 1;
+
+ if ((!out_of_space) && (new_dma_sectors > dma_sectors)) {
+ for (i = dma_sectors / SECTORS_PER_PAGE;
+ i < new_dma_sectors / SECTORS_PER_PAGE; i++) {
+ new_dma_malloc_pages[i] = (unsigned char *)
+ __get_free_pages(GFP_ATOMIC | GFP_DMA, 0);
+ if (!new_dma_malloc_pages[i])
+ break;
+ }
+ if (i != new_dma_sectors / SECTORS_PER_PAGE) { /* clean up */
+ int k = i;
+
+ out_of_space = 1;
+ for (i = 0; i < k; ++i)
+ free_pages((unsigned long) new_dma_malloc_pages[i], 0);
+ }
+ }
+ if (out_of_space) { /* try scaling down new_dma_sectors request */
+ printk("scsi::resize_dma_pool: WARNING, dma_sectors=%u, "
+ "wanted=%u, scaling\n", dma_sectors, new_dma_sectors);
+ if (new_dma_sectors < (8 * SECTORS_PER_PAGE))
+ break; /* pretty well hopeless ... */
+ new_dma_sectors = (new_dma_sectors * 3) / 4;
+ new_dma_sectors = (new_dma_sectors + 15) & 0xfff0;
+ if (new_dma_sectors <= dma_sectors)
+ break; /* stick with what we have got */
+ } else
+ break; /* found space ... */
+ } /* end of for loop */
+ if (out_of_space) {
+ spin_unlock_irqrestore(&allocator_request_lock, flags);
+ scsi_need_isa_buffer = new_need_isa_buffer; /* some useful info */
+ printk(" WARNING, not enough memory, pool not expanded\n");
+ return;
+ }
+ /* When we dick with the actual DMA list, we need to
+ * protect things
+ */
+ if (dma_malloc_freelist) {
+ size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(FreeSectorBitmap);
+ memcpy(new_dma_malloc_freelist, dma_malloc_freelist, size);
+ kfree((char *) dma_malloc_freelist);
+ }
+ dma_malloc_freelist = new_dma_malloc_freelist;
+
+ if (dma_malloc_pages) {
+ size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages);
+ memcpy(new_dma_malloc_pages, dma_malloc_pages, size);
+ kfree((char *) dma_malloc_pages);
+ }
+ scsi_dma_free_sectors += new_dma_sectors - dma_sectors;
+ dma_malloc_pages = new_dma_malloc_pages;
+ dma_sectors = new_dma_sectors;
+ scsi_need_isa_buffer = new_need_isa_buffer;
+
+ spin_unlock_irqrestore(&allocator_request_lock, flags);
+
+#ifdef DEBUG_INIT
+ printk("resize_dma_pool: dma free sectors = %d\n", scsi_dma_free_sectors);
+ printk("resize_dma_pool: dma sectors = %d\n", dma_sectors);
+ printk("resize_dma_pool: need isa buffers = %d\n", scsi_need_isa_buffer);
+#endif
+}
+
+/*
+ * Function: scsi_init_minimal_dma_pool
+ *
+ * Purpose: Allocate a minimal (1-page) DMA pool.
+ *
+ * Arguments: None.
+ *
+ * Lock status: No locks assumed to be held. This function is SMP-safe.
+ *
+ * Returns: Nothing
+ *
+ * Notes:
+ */
+int scsi_init_minimal_dma_pool(void)
+{
+ unsigned long size;
+ unsigned long flags;
+ int has_space = 0;
+
+ spin_lock_irqsave(&allocator_request_lock, flags);
+
+ dma_sectors = PAGE_SIZE / SECTOR_SIZE;
+ scsi_dma_free_sectors = dma_sectors;
+ /*
+ * Set up a minimal DMA buffer list - this will be used during scan_scsis
+ * in some cases.
+ */
+
+ /* One bit per sector to indicate free/busy */
+ size = (dma_sectors / SECTORS_PER_PAGE) * sizeof(FreeSectorBitmap);
+ dma_malloc_freelist = (FreeSectorBitmap *)
+ kmalloc(size, GFP_ATOMIC);
+ if (dma_malloc_freelist) {
+ memset(dma_malloc_freelist, 0, size);
+ /* One pointer per page for the page list */
+ dma_malloc_pages = (unsigned char **) kmalloc(
+ (dma_sectors / SECTORS_PER_PAGE) * sizeof(*dma_malloc_pages),
+ GFP_ATOMIC);
+ if (dma_malloc_pages) {
+ memset(dma_malloc_pages, 0, size);
+ dma_malloc_pages[0] = (unsigned char *)
+ __get_free_pages(GFP_ATOMIC | GFP_DMA, 0);
+ if (dma_malloc_pages[0])
+ has_space = 1;
+ }
+ }
+ if (!has_space) {
+ if (dma_malloc_freelist) {
+ kfree((char *) dma_malloc_freelist);
+ if (dma_malloc_pages)
+ kfree((char *) dma_malloc_pages);
+ }
+ spin_unlock_irqrestore(&allocator_request_lock, flags);
+ printk("scsi::init_module: failed, out of memory\n");
+ return 1;
+ }
+
+ spin_unlock_irqrestore(&allocator_request_lock, flags);
+ return 0;
+}
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index 1a45b5880..f62c1f015 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -90,18 +90,6 @@ static int ioctl_probe(struct Scsi_Host *host, void *buffer)
* The output area is then filled in starting from the command byte.
*/
-static void scsi_ioctl_done(Scsi_Cmnd * SCpnt)
-{
- struct request *req;
-
- req = &SCpnt->request;
- req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
-
- if (req->sem != NULL) {
- up(req->sem);
- }
-}
-
static int ioctl_internal_command(Scsi_Device * dev, char *cmd,
int timeout, int retries)
{
@@ -117,7 +105,7 @@ static int ioctl_internal_command(Scsi_Device * dev, char *cmd,
return -EINTR;
}
- scsi_wait_cmd(SCpnt, cmd, NULL, 0, scsi_ioctl_done, timeout, retries);
+ scsi_wait_cmd(SCpnt, cmd, NULL, 0, timeout, retries);
SCSI_LOG_IOCTL(2, printk("Ioctl returned 0x%x\n", SCpnt->result));
@@ -201,7 +189,7 @@ static int ioctl_internal_command(Scsi_Device * dev, char *cmd,
int scsi_ioctl_send_command(Scsi_Device * dev, Scsi_Ioctl_Command * sic)
{
char *buf;
- unsigned char cmd[12];
+ unsigned char cmd[MAX_COMMAND_SIZE];
char *cmd_in;
Scsi_Cmnd *SCpnt;
Scsi_Device *SDpnt;
@@ -300,8 +288,7 @@ int scsi_ioctl_send_command(Scsi_Device * dev, Scsi_Ioctl_Command * sic)
return -EINTR;
}
- scsi_wait_cmd(SCpnt, cmd, buf, needed, scsi_ioctl_done,
- timeout, retries);
+ scsi_wait_cmd(SCpnt, cmd, buf, needed, timeout, retries);
/*
* If there was an error condition, pass the info back to the user.
@@ -358,7 +345,7 @@ int scsi_ioctl_send_command(Scsi_Device * dev, Scsi_Ioctl_Command * sic)
int scsi_ioctl(Scsi_Device * dev, int cmd, void *arg)
{
int result;
- char scsi_cmd[12];
+ char scsi_cmd[MAX_COMMAND_SIZE];
/* No idea how this happens.... */
if (!dev)
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 48b1c977d..7d2c021e9 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -51,6 +51,13 @@
*/
/*
+ * For hosts that request single-file access to the ISA bus, this is a pointer to
+ * the currently active host.
+ */
+volatile struct Scsi_Host *host_active = NULL;
+
+
+/*
* Function: scsi_insert_special_cmd()
*
* Purpose: Insert pre-formed command into request queue.
@@ -184,6 +191,7 @@ int scsi_init_cmd_errh(Scsi_Cmnd * SCpnt)
return 1;
}
+
/*
* Function: scsi_queue_next_request()
*
@@ -202,6 +210,23 @@ int scsi_init_cmd_errh(Scsi_Cmnd * SCpnt)
* If SCpnt is NULL, it means that the previous command
* was completely finished, and we should simply start
* a new command, if possible.
+ *
+ * This is where a lot of special case code has begun to
+ * accumulate. It doesn't really affect readability or
+ * anything, but it might be considered architecturally
+ * inelegant. If more of these special cases start to
+ * accumulate, I am thinking along the lines of implementing
+ * an atexit() like technology that gets run when commands
+ * complete. I am not convinced that it is worth the
+ * added overhead, however. Right now as things stand,
+ * there are simple conditional checks, and most hosts
+ * would skip past.
+ *
+ * Another possible solution would be to tailor different
+ * handler functions, sort of like what we did in scsi_merge.c.
+ * This is probably a better solution, but the number of different
+ * permutations grows as 2**N, and if too many more special cases
+ * get added, we start to get screwed.
*/
void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
{
diff --git a/drivers/scsi/scsi_merge.c b/drivers/scsi/scsi_merge.c
index 3dffe88ad..290d33d6c 100644
--- a/drivers/scsi/scsi_merge.c
+++ b/drivers/scsi/scsi_merge.c
@@ -5,6 +5,7 @@
* Initial versions: Eric Youngdale (eric@andante.org).
* Based upon conversations with large numbers
* of people at Linux Expo.
+ * Support for dynamic DMA mapping: Jakub Jelinek (jakub@redhat.com).
*/
/*
@@ -55,6 +56,7 @@
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/dma.h>
+#include <asm/io.h>
#include "scsi.h"
#include "hosts.h"
@@ -303,6 +305,10 @@ recount_segments(Scsi_Cmnd * SCpnt)
SHpnt->unchecked_isa_dma, NULL);
}
+#define MERGEABLE_BUFFERS(X,Y) \
+(((((long)(X)->b_data+(X)->b_size)|((long)(Y)->b_data)) & \
+ (DMA_CHUNK_SIZE - 1)) == 0)
+
/*
* Function: __scsi_merge_fn()
*
@@ -369,7 +375,7 @@ __inline static int __scsi_merge_fn(request_queue_t * q,
*/
if (dma_host &&
virt_to_phys(req->bhtail->b_data) - 1 == ISA_DMA_THRESHOLD) {
- goto new_segment;
+ goto new_end_segment;
}
if (CONTIGUOUS_BUFFERS(req->bhtail, bh)) {
#ifdef DMA_SEGMENT_SIZE_LIMITED
@@ -377,9 +383,8 @@ __inline static int __scsi_merge_fn(request_queue_t * q,
&& virt_to_phys(bh->b_data) - 1 >= ISA_DMA_THRESHOLD ) {
segment_size = 0;
count = __count_segments(req, use_clustering, dma_host, &segment_size);
- if( segment_size + bh->b_size > PAGE_SIZE )
- {
- goto new_segment;
+ if( segment_size + bh->b_size > PAGE_SIZE ) {
+ goto new_end_segment;
}
}
#endif
@@ -389,8 +394,17 @@ __inline static int __scsi_merge_fn(request_queue_t * q,
return 1;
}
}
+ new_end_segment:
+#ifdef DMA_CHUNK_SIZE
+ if (MERGEABLE_BUFFERS(req->bhtail, bh))
+ goto new_mergeable;
+#endif
goto new_segment;
- } else if (req->sector - count == sector) {
+ } else {
+ if (req->sector - count != sector) {
+ /* Attempt to merge sector that doesn't belong */
+ BUG();
+ }
if (use_clustering) {
/*
* See if we can do this without creating another
@@ -400,7 +414,7 @@ __inline static int __scsi_merge_fn(request_queue_t * q,
*/
if (dma_host &&
virt_to_phys(bh->b_data) - 1 == ISA_DMA_THRESHOLD) {
- goto new_segment;
+ goto new_start_segment;
}
if (CONTIGUOUS_BUFFERS(bh, req->bh)) {
#ifdef DMA_SEGMENT_SIZE_LIMITED
@@ -409,7 +423,7 @@ __inline static int __scsi_merge_fn(request_queue_t * q,
segment_size = bh->b_size;
count = __count_segments(req, use_clustering, dma_host, &segment_size);
if( count != req->nr_segments ) {
- goto new_segment;
+ goto new_start_segment;
}
}
#endif
@@ -419,10 +433,41 @@ __inline static int __scsi_merge_fn(request_queue_t * q,
return 1;
}
}
+ new_start_segment:
+#ifdef DMA_CHUNK_SIZE
+ if (MERGEABLE_BUFFERS(bh, req->bh))
+ goto new_mergeable;
+#endif
goto new_segment;
- } else {
- panic("Attempt to merge sector that doesn't belong");
}
+#ifdef DMA_CHUNK_SIZE
+ new_mergeable:
+ /*
+ * pci_map_sg will be able to merge these two
+ * into a single hardware sg entry, check if
+ * we'll have enough memory for the sg list.
+ * scsi.c allocates for this purpose
+ * min(64,sg_tablesize) entries.
+ */
+ if (req->nr_segments >= 64 &&
+ req->nr_segments >= SHpnt->sg_tablesize)
+ return 0;
+ req->nr_segments++;
+ return 1;
+ new_segment:
+ /*
+ * pci_map_sg won't be able to map these two
+ * into a single hardware sg entry, so we have to
+ * check if things fit into sg_tablesize.
+ */
+ if (req->nr_hw_segments >= SHpnt->sg_tablesize ||
+ (req->nr_segments >= 64 &&
+ req->nr_segments >= SHpnt->sg_tablesize))
+ return 0;
+ req->nr_hw_segments++;
+ req->nr_segments++;
+ return 1;
+#else
new_segment:
if (req->nr_segments < SHpnt->sg_tablesize) {
/*
@@ -434,6 +479,7 @@ __inline static int __scsi_merge_fn(request_queue_t * q,
} else {
return 0;
}
+#endif
}
/*
@@ -464,8 +510,10 @@ static int _FUNCTION(request_queue_t * q, \
return ret; \
}
+/* Version with use_clustering 0 and dma_host 1 is not necessary,
+ * since the only use of dma_host above is protected by use_clustering.
+ */
MERGEFCT(scsi_merge_fn_, 0, 0)
-MERGEFCT(scsi_merge_fn_d, 0, 1)
MERGEFCT(scsi_merge_fn_c, 1, 0)
MERGEFCT(scsi_merge_fn_dc, 1, 1)
/*
@@ -513,6 +561,18 @@ __inline static int __scsi_merge_requests_fn(request_queue_t * q,
SDpnt = (Scsi_Device *) q->queuedata;
SHpnt = SDpnt->host;
+#ifdef DMA_CHUNK_SIZE
+ /* If it would not fit into prepared memory space for sg chain,
+ * then don't allow the merge.
+ */
+ if (req->nr_segments + next->nr_segments - 1 > 64 &&
+ req->nr_segments + next->nr_segments - 1 > SHpnt->sg_tablesize) {
+ return 0;
+ }
+ if (req->nr_hw_segments + next->nr_hw_segments - 1 > SHpnt->sg_tablesize) {
+ return 0;
+ }
+#else
/*
* If the two requests together are too large (even assuming that we
* can merge the boundary requests into one segment, then don't
@@ -521,6 +581,7 @@ __inline static int __scsi_merge_requests_fn(request_queue_t * q,
if (req->nr_segments + next->nr_segments - 1 > SHpnt->sg_tablesize) {
return 0;
}
+#endif
/*
* The main question is whether the two segments at the boundaries
* would be considered one or two.
@@ -560,10 +621,32 @@ __inline static int __scsi_merge_requests_fn(request_queue_t * q,
* This one is OK. Let it go.
*/
req->nr_segments += next->nr_segments - 1;
+#ifdef DMA_CHUNK_SIZE
+ req->nr_hw_segments += next->nr_hw_segments - 1;
+#endif
return 1;
}
}
dont_combine:
+#ifdef DMA_CHUNK_SIZE
+ if (req->nr_segments + next->nr_segments > 64 &&
+ req->nr_segments + next->nr_segments > SHpnt->sg_tablesize) {
+ return 0;
+ }
+ /* If dynamic DMA mapping can merge last segment in req with
+ * first segment in next, then the check for hw segments was
+ * done above already, so we can always merge.
+ */
+ if (MERGEABLE_BUFFERS (req->bhtail, next->bh)) {
+ req->nr_hw_segments += next->nr_hw_segments - 1;
+ } else if (req->nr_hw_segments + next->nr_hw_segments > SHpnt->sg_tablesize) {
+ return 0;
+ } else {
+ req->nr_hw_segments += next->nr_hw_segments;
+ }
+ req->nr_segments += next->nr_segments;
+ return 1;
+#else
/*
* We know that the two requests at the boundary should not be combined.
* Make sure we can fix something that is the sum of the two.
@@ -579,6 +662,7 @@ __inline static int __scsi_merge_requests_fn(request_queue_t * q,
req->nr_segments += next->nr_segments;
return 1;
}
+#endif
}
/*
@@ -609,8 +693,10 @@ static int _FUNCTION(request_queue_t * q, \
return ret; \
}
+/* Version with use_clustering 0 and dma_host 1 is not necessary,
+ * since the only use of dma_host above is protected by use_clustering.
+ */
MERGEREQFCT(scsi_merge_requests_fn_, 0, 0)
-MERGEREQFCT(scsi_merge_requests_fn_d, 0, 1)
MERGEREQFCT(scsi_merge_requests_fn_c, 1, 0)
MERGEREQFCT(scsi_merge_requests_fn_dc, 1, 1)
/*
@@ -737,7 +823,7 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt,
* Next, walk the list, and fill in the addresses and sizes of
* each segment.
*/
- memset(sgpnt, 0, SCpnt->sglist_len);
+ memset(sgpnt, 0, SCpnt->use_sg * sizeof(struct scatterlist));
SCpnt->request_buffer = (char *) sgpnt;
SCpnt->request_bufflen = 0;
bhprev = NULL;
@@ -983,9 +1069,10 @@ void initialize_merge_fn(Scsi_Device * SDpnt)
* If the host has already selected a merge manager, then don't
* pick a new one.
*/
- if (q->merge_fn != NULL) {
+#if 0
+ if (q->merge_fn != NULL)
return;
- }
+#endif
/*
* If this host has an unlimited tablesize, then don't bother with a
* merge manager. The whole point of the operation is to make sure
@@ -1002,8 +1089,8 @@ void initialize_merge_fn(Scsi_Device * SDpnt)
q->merge_requests_fn = scsi_merge_requests_fn_;
SDpnt->scsi_init_io_fn = scsi_init_io_v;
} else if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma != 0) {
- q->merge_fn = scsi_merge_fn_d;
- q->merge_requests_fn = scsi_merge_requests_fn_d;
+ q->merge_fn = scsi_merge_fn_;
+ q->merge_requests_fn = scsi_merge_requests_fn_;
SDpnt->scsi_init_io_fn = scsi_init_io_vd;
} else if (CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma == 0) {
q->merge_fn = scsi_merge_fn_c;
diff --git a/drivers/scsi/scsi_obsolete.c b/drivers/scsi/scsi_obsolete.c
index eb3eb0ceb..ee1041d88 100644
--- a/drivers/scsi/scsi_obsolete.c
+++ b/drivers/scsi/scsi_obsolete.c
@@ -132,7 +132,6 @@ static void scsi_dump_status(void);
/*
* Flag bits for the internal_timeout array
*/
-#define NORMAL_TIMEOUT 0
#define IN_ABORT 1
#define IN_RESET 2
#define IN_RESET2 4
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
new file mode 100644
index 000000000..ed30ae091
--- /dev/null
+++ b/drivers/scsi/scsi_scan.c
@@ -0,0 +1,820 @@
+/*
+ * scsi_scan.c Copyright (C) 2000 Eric Youngdale
+ *
+ * Bus scan logic.
+ *
+ * This used to live in scsi.c, but that file was just a laundry basket
+ * full of misc stuff. This got separated out in order to make things
+ * clearer.
+ */
+
+#define __NO_VERSION__
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/blk.h>
+
+#include "scsi.h"
+#include "hosts.h"
+#include "constants.h"
+
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif
+
+/* The following devices are known not to tolerate a lun != 0 scan for
+ * one reason or another. Some will respond to all luns, others will
+ * lock up.
+ */
+
+#define BLIST_NOLUN 0x001
+#define BLIST_FORCELUN 0x002
+#define BLIST_BORKEN 0x004
+#define BLIST_KEY 0x008
+#define BLIST_SINGLELUN 0x010
+#define BLIST_NOTQ 0x020
+#define BLIST_SPARSELUN 0x040
+#define BLIST_MAX5LUN 0x080
+#define BLIST_ISDISK 0x100
+#define BLIST_ISROM 0x200
+#define BLIST_GHOST 0x400
+
+static void print_inquiry(unsigned char *data);
+static int scan_scsis_single(int channel, int dev, int lun, int *max_scsi_dev,
+ int *sparse_lun, Scsi_Device ** SDpnt, Scsi_Cmnd * SCpnt,
+ struct Scsi_Host *shpnt, char *scsi_result);
+
+struct dev_info {
+ const char *vendor;
+ const char *model;
+ const char *revision; /* Latest revision known to be bad. Not used yet */
+ unsigned flags;
+};
+
+/*
+ * This is what was previously known as the blacklist. The concept
+ * has been expanded so that we can specify other types of things we
+ * need to be aware of.
+ */
+static struct dev_info device_list[] =
+{
+ {"Aashima", "IMAGERY 2400SP", "1.03", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
+ {"CHINON", "CD-ROM CDS-431", "H42", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
+ {"CHINON", "CD-ROM CDS-535", "Q14", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
+ {"DENON", "DRD-25X", "V", BLIST_NOLUN}, /* Locks up if probed for lun != 0 */
+ {"HITACHI", "DK312C", "CM81", BLIST_NOLUN}, /* Responds to all lun - dtg */
+ {"HITACHI", "DK314C", "CR21", BLIST_NOLUN}, /* responds to all lun */
+ {"IMS", "CDD521/10", "2.06", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */
+ {"MAXTOR", "XT-3280", "PR02", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */
+ {"MAXTOR", "XT-4380S", "B3C", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */
+ {"MAXTOR", "MXT-1240S", "I1.2", BLIST_NOLUN}, /* Locks up when LUN>0 polled */
+ {"MAXTOR", "XT-4170S", "B5A", BLIST_NOLUN}, /* Locks-up sometimes when LUN>0 polled. */
+ {"MAXTOR", "XT-8760S", "B7B", BLIST_NOLUN}, /* guess what? */
+ {"MEDIAVIS", "RENO CD-ROMX2A", "2.03", BLIST_NOLUN}, /*Responds to all lun */
+ {"MICROP", "4110", "*", BLIST_NOTQ}, /* Buggy Tagged Queuing */
+ {"NEC", "CD-ROM DRIVE:841", "1.0", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */
+ {"PHILIPS", "PCA80SC", "V4-2", BLIST_NOLUN}, /* Responds to all lun */
+ {"RODIME", "RO3000S", "2.33", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
+ {"SANYO", "CRD-250S", "1.20", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1
+ * for aha152x controller, which causes
+ * SCSI code to reset bus.*/
+ {"SEAGATE", "ST157N", "\004|j", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1
+ * for aha152x controller, which causes
+ * SCSI code to reset bus.*/
+ {"SEAGATE", "ST296", "921", BLIST_NOLUN}, /* Responds to all lun */
+ {"SEAGATE", "ST1581", "6538", BLIST_NOLUN}, /* Responds to all lun */
+ {"SONY", "CD-ROM CDU-541", "4.3d", BLIST_NOLUN},
+ {"SONY", "CD-ROM CDU-55S", "1.0i", BLIST_NOLUN},
+ {"SONY", "CD-ROM CDU-561", "1.7x", BLIST_NOLUN},
+ {"SONY", "CD-ROM CDU-8012", "*", BLIST_NOLUN},
+ {"TANDBERG", "TDC 3600", "U07", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
+ {"TEAC", "CD-R55S", "1.0H", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
+ {"TEAC", "CD-ROM", "1.06", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1
+ * for seagate controller, which causes
+ * SCSI code to reset bus.*/
+ {"TEAC", "MT-2ST/45S2-27", "RV M", BLIST_NOLUN}, /* Responds to all lun */
+ {"TEXEL", "CD-ROM", "1.06", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1
+ * for seagate controller, which causes
+ * SCSI code to reset bus.*/
+ {"QUANTUM", "LPS525S", "3110", BLIST_NOLUN}, /* Locks sometimes if polled for lun != 0 */
+ {"QUANTUM", "PD1225S", "3110", BLIST_NOLUN}, /* Locks sometimes if polled for lun != 0 */
+ {"QUANTUM", "FIREBALL ST4.3S", "0F0C", BLIST_NOLUN}, /* Locks up when polled for lun != 0 */
+ {"MEDIAVIS", "CDR-H93MV", "1.31", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
+ {"SANKYO", "CP525", "6.64", BLIST_NOLUN}, /* causes failed REQ SENSE, extra reset */
+ {"HP", "C1750A", "3226", BLIST_NOLUN}, /* scanjet iic */
+ {"HP", "C1790A", "", BLIST_NOLUN}, /* scanjet iip */
+ {"HP", "C2500A", "", BLIST_NOLUN}, /* scanjet iicx */
+ {"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 */
+ {"RELISYS", "Scorpio", "*", BLIST_NOLUN}, /* responds to all LUN */
+ {"MICROTEK", "ScanMaker II", "5.61", BLIST_NOLUN}, /* responds to all LUN */
+
+/*
+ * Other types of devices that have special flags.
+ */
+ {"SONY", "CD-ROM CDU-8001", "*", BLIST_BORKEN},
+ {"TEXEL", "CD-ROM", "1.06", BLIST_BORKEN},
+ {"IOMEGA", "Io20S *F", "*", BLIST_KEY},
+ {"INSITE", "Floptical F*8I", "*", BLIST_KEY},
+ {"INSITE", "I325VM", "*", BLIST_KEY},
+ {"NRC", "MBR-7", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"NRC", "MBR-7.4", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"REGAL", "CDC-4X", "*", BLIST_MAX5LUN | BLIST_SINGLELUN},
+ {"NAKAMICH", "MJ-4.8S", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"NAKAMICH", "MJ-5.16S", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"PIONEER", "CD-ROM DRM-600", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"PIONEER", "CD-ROM DRM-602X", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"PIONEER", "CD-ROM DRM-604X", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"EMULEX", "MD21/S2 ESDI", "*", BLIST_SINGLELUN},
+ {"CANON", "IPUBJD", "*", BLIST_SPARSELUN},
+ {"nCipher", "Fastness Crypto", "*", BLIST_FORCELUN},
+ {"NEC", "PD-1 ODX654P", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"MATSHITA", "PD-1", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
+ {"CREATIVE","DVD-RAM RAM","*", BLIST_GHOST},
+ {"MATSHITA","PD-2 LF-D100","*", BLIST_GHOST},
+ {"HITACHI", "GF-1050","*", BLIST_GHOST}, /* Hitachi SCSI DVD-RAM */
+ {"TOSHIBA","CDROM","*", BLIST_ISROM},
+ {"TOSHIBA","DVD-RAM SD-W1101","*", BLIST_GHOST},
+ {"TOSHIBA","DVD-RAM SD-W1111","*", BLIST_GHOST},
+
+ /*
+ * Must be at end of list...
+ */
+ {NULL, NULL, NULL}
+};
+
+#ifdef CONFIG_SCSI_MULTI_LUN
+static int max_scsi_luns = 8;
+#else
+static int max_scsi_luns = 1;
+#endif
+
+#ifdef MODULE
+
+MODULE_PARM(max_scsi_luns, "i");
+MODULE_PARM_DESC(max_scsi_luns, "last scsi LUN (should be between 1 and 8)");
+
+#else
+
+static int __init scsi_luns_setup(char *str)
+{
+ int tmp;
+
+ if (get_option(&str, &tmp) == 1) {
+ max_scsi_luns = tmp;
+ return 1;
+ } else {
+ printk("scsi_luns_setup : usage max_scsi_luns=n "
+ "(n should be between 1 and 8)\n");
+ return 0;
+ }
+}
+
+__setup("max_scsi_luns=", scsi_luns_setup);
+
+#endif
+
+static void print_inquiry(unsigned char *data)
+{
+ int i;
+
+ printk(" Vendor: ");
+ for (i = 8; i < 16; i++) {
+ if (data[i] >= 0x20 && i < data[4] + 5)
+ printk("%c", data[i]);
+ else
+ printk(" ");
+ }
+
+ printk(" Model: ");
+ for (i = 16; i < 32; i++) {
+ if (data[i] >= 0x20 && i < data[4] + 5)
+ printk("%c", data[i]);
+ else
+ printk(" ");
+ }
+
+ printk(" Rev: ");
+ for (i = 32; i < 36; i++) {
+ if (data[i] >= 0x20 && i < data[4] + 5)
+ printk("%c", data[i]);
+ else
+ printk(" ");
+ }
+
+ printk("\n");
+
+ i = data[0] & 0x1f;
+
+ printk(" Type: %s ",
+ i < MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] : "Unknown ");
+ printk(" ANSI SCSI revision: %02x", data[2] & 0x07);
+ if ((data[2] & 0x07) == 1 && (data[3] & 0x0f) == 1)
+ printk(" CCS\n");
+ else
+ printk("\n");
+}
+
+static int get_device_flags(unsigned char *response_data)
+{
+ int i = 0;
+ unsigned char *pnt;
+ for (i = 0; 1; i++) {
+ if (device_list[i].vendor == NULL)
+ return 0;
+ pnt = &response_data[8];
+ while (*pnt && *pnt == ' ')
+ pnt++;
+ if (memcmp(device_list[i].vendor, pnt,
+ strlen(device_list[i].vendor)))
+ continue;
+ pnt = &response_data[16];
+ while (*pnt && *pnt == ' ')
+ pnt++;
+ if (memcmp(device_list[i].model, pnt,
+ strlen(device_list[i].model)))
+ continue;
+ return device_list[i].flags;
+ }
+ return 0;
+}
+
+/*
+ * Detecting SCSI devices :
+ * We scan all present host adapter's busses, from ID 0 to ID (max_id).
+ * We use the INQUIRY command, determine device type, and pass the ID /
+ * lun address of all sequential devices to the tape driver, all random
+ * devices to the disk driver.
+ */
+void scan_scsis(struct Scsi_Host *shpnt,
+ unchar hardcoded,
+ unchar hchannel,
+ unchar hid,
+ unchar hlun)
+{
+ int channel;
+ int dev;
+ int lun;
+ int max_dev_lun;
+ Scsi_Cmnd *SCpnt;
+ unsigned char *scsi_result;
+ unsigned char scsi_result0[256];
+ Scsi_Device *SDpnt;
+ Scsi_Device *SDtail;
+ int sparse_lun;
+
+ scsi_result = NULL;
+ SCpnt = (Scsi_Cmnd *) kmalloc(sizeof(Scsi_Cmnd),
+ GFP_ATOMIC | GFP_DMA);
+ if (SCpnt) {
+ memset(SCpnt, 0, sizeof(Scsi_Cmnd));
+ SDpnt = (Scsi_Device *) kmalloc(sizeof(Scsi_Device),
+ GFP_ATOMIC);
+ if (SDpnt) {
+ memset(SDpnt, 0, sizeof(Scsi_Device));
+ /*
+ * Register the queue for the device. All I/O requests will come
+ * in through here. We also need to register a pointer to
+ * ourselves, since the queue handler won't know what device
+ * the queue actually represents. We could look it up, but it
+ * is pointless work.
+ */
+ blk_init_queue(&SDpnt->request_queue, scsi_get_request_handler(SDpnt, shpnt));
+ blk_queue_headactive(&SDpnt->request_queue, 0);
+ SDpnt->request_queue.queuedata = (void *) SDpnt;
+ /* Make sure we have something that is valid for DMA purposes */
+ scsi_result = ((!shpnt->unchecked_isa_dma)
+ ? &scsi_result0[0] : kmalloc(512, GFP_DMA));
+ }
+ }
+ if (scsi_result == NULL) {
+ printk("Unable to obtain scsi_result buffer\n");
+ goto leave;
+ }
+ /*
+ * We must chain ourself in the host_queue, so commands can time out
+ */
+ SCpnt->next = NULL;
+ SDpnt->device_queue = SCpnt;
+ SDpnt->host = shpnt;
+ SDpnt->online = TRUE;
+
+ initialize_merge_fn(SDpnt);
+
+ /*
+ * Initialize the object that we will use to wait for command blocks.
+ */
+ init_waitqueue_head(&SDpnt->scpnt_wait);
+
+ /*
+ * Next, hook the device to the host in question.
+ */
+ SDpnt->prev = NULL;
+ SDpnt->next = NULL;
+ if (shpnt->host_queue != NULL) {
+ SDtail = shpnt->host_queue;
+ while (SDtail->next != NULL)
+ SDtail = SDtail->next;
+
+ SDtail->next = SDpnt;
+ SDpnt->prev = SDtail;
+ } else {
+ shpnt->host_queue = SDpnt;
+ }
+
+ /*
+ * We need to increment the counter for this one device so we can track when
+ * things are quiet.
+ */
+ atomic_inc(&shpnt->host_active);
+ atomic_inc(&SDpnt->device_active);
+
+ if (hardcoded == 1) {
+ Scsi_Device *oldSDpnt = SDpnt;
+ struct Scsi_Device_Template *sdtpnt;
+ channel = hchannel;
+ if (channel > shpnt->max_channel)
+ goto leave;
+ dev = hid;
+ if (dev >= shpnt->max_id)
+ goto leave;
+ lun = hlun;
+ if (lun >= shpnt->max_lun)
+ goto leave;
+ scan_scsis_single(channel, dev, lun, &max_dev_lun, &sparse_lun,
+ &SDpnt, SCpnt, shpnt, scsi_result);
+ if (SDpnt != oldSDpnt) {
+
+ /* it could happen the blockdevice hasn't yet been inited */
+ for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
+ if (sdtpnt->init && sdtpnt->dev_noticed)
+ (*sdtpnt->init) ();
+
+ for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) {
+ if (sdtpnt->attach) {
+ (*sdtpnt->attach) (oldSDpnt);
+ if (oldSDpnt->attached) {
+ scsi_build_commandblocks(oldSDpnt);
+ if (0 == oldSDpnt->has_cmdblocks) {
+ printk("scan_scsis: DANGER, no command blocks\n");
+ /* What to do now ?? */
+ }
+ }
+ }
+ }
+ scsi_resize_dma_pool();
+
+ for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) {
+ if (sdtpnt->finish && sdtpnt->nr_dev) {
+ (*sdtpnt->finish) ();
+ }
+ }
+ }
+ } else {
+ /* Actual LUN. PC ordering is 0->n IBM/spec ordering is n->0 */
+ int order_dev;
+
+ for (channel = 0; channel <= shpnt->max_channel; channel++) {
+ for (dev = 0; dev < shpnt->max_id; ++dev) {
+ if (shpnt->reverse_ordering)
+ /* Shift to scanning 15,14,13... or 7,6,5,4, */
+ order_dev = shpnt->max_id - dev - 1;
+ else
+ order_dev = dev;
+
+ if (shpnt->this_id != order_dev) {
+
+ /*
+ * We need the for so our continue, etc. work fine. We put this in
+ * a variable so that we can override it during the scan if we
+ * detect a device *KNOWN* to have multiple logical units.
+ */
+ max_dev_lun = (max_scsi_luns < shpnt->max_lun ?
+ max_scsi_luns : shpnt->max_lun);
+ sparse_lun = 0;
+ for (lun = 0; lun < max_dev_lun; ++lun) {
+ if (!scan_scsis_single(channel, order_dev, lun, &max_dev_lun,
+ &sparse_lun, &SDpnt, SCpnt, shpnt,
+ scsi_result)
+ && !sparse_lun)
+ break; /* break means don't probe further for luns!=0 */
+ } /* for lun ends */
+ } /* if this_id != id ends */
+ } /* for dev ends */
+ } /* for channel ends */
+ } /* if/else hardcoded */
+
+ /*
+ * We need to decrement the counter for this one device
+ * so we know when everything is quiet.
+ */
+ atomic_dec(&shpnt->host_active);
+ atomic_dec(&SDpnt->device_active);
+
+ leave:
+
+ { /* Unchain SCpnt from host_queue */
+ Scsi_Device *prev, *next;
+ Scsi_Device *dqptr;
+
+ for (dqptr = shpnt->host_queue; dqptr != SDpnt; dqptr = dqptr->next)
+ continue;
+ if (dqptr) {
+ prev = dqptr->prev;
+ next = dqptr->next;
+ if (prev)
+ prev->next = next;
+ else
+ shpnt->host_queue = next;
+ if (next)
+ next->prev = prev;
+ }
+ }
+
+ /* Last device block does not exist. Free memory. */
+ if (SDpnt != NULL)
+ kfree((char *) SDpnt);
+
+ if (SCpnt != NULL)
+ kfree((char *) SCpnt);
+
+ /* If we allocated a buffer so we could do DMA, free it now */
+ if (scsi_result != &scsi_result0[0] && scsi_result != NULL) {
+ kfree(scsi_result);
+ } {
+ Scsi_Device *sdev;
+ Scsi_Cmnd *scmd;
+
+ SCSI_LOG_SCAN_BUS(4, printk("Host status for host %p:\n", shpnt));
+ for (sdev = shpnt->host_queue; sdev; sdev = sdev->next) {
+ SCSI_LOG_SCAN_BUS(4, printk("Device %d %p: ", sdev->id, sdev));
+ for (scmd = sdev->device_queue; scmd; scmd = scmd->next) {
+ SCSI_LOG_SCAN_BUS(4, printk("%p ", scmd));
+ }
+ SCSI_LOG_SCAN_BUS(4, printk("\n"));
+ }
+ }
+}
+
+/*
+ * The worker for scan_scsis.
+ * Returning 0 means Please don't ask further for lun!=0, 1 means OK go on.
+ * Global variables used : scsi_devices(linked list)
+ */
+int scan_scsis_single(int channel, int dev, int lun, int *max_dev_lun,
+ int *sparse_lun, Scsi_Device ** SDpnt2, Scsi_Cmnd * SCpnt,
+ struct Scsi_Host *shpnt, char *scsi_result)
+{
+ unsigned char scsi_cmd[MAX_COMMAND_SIZE];
+ struct Scsi_Device_Template *sdtpnt;
+ Scsi_Device *SDtail, *SDpnt = *SDpnt2;
+ int bflags, type = -1;
+ static int ghost_channel=-1, ghost_dev=-1;
+ int org_lun = lun;
+
+ SDpnt->host = shpnt;
+ SDpnt->id = dev;
+ SDpnt->lun = lun;
+ SDpnt->channel = channel;
+ SDpnt->online = TRUE;
+
+
+ if ((channel == ghost_channel) && (dev == ghost_dev) && (lun == 1)) {
+ SDpnt->lun = 0;
+ } else {
+ ghost_channel = ghost_dev = -1;
+ }
+
+
+ /* Some low level driver could use device->type (DB) */
+ SDpnt->type = -1;
+
+ /*
+ * Assume that the device will have handshaking problems, and then fix this
+ * field later if it turns out it doesn't
+ */
+ SDpnt->borken = 1;
+ SDpnt->was_reset = 0;
+ SDpnt->expecting_cc_ua = 0;
+ SDpnt->starved = 0;
+
+ scsi_cmd[0] = TEST_UNIT_READY;
+ scsi_cmd[1] = lun << 5;
+ scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[4] = scsi_cmd[5] = 0;
+
+ SCpnt->host = SDpnt->host;
+ SCpnt->device = SDpnt;
+ SCpnt->target = SDpnt->id;
+ SCpnt->lun = SDpnt->lun;
+ SCpnt->channel = SDpnt->channel;
+
+ scsi_wait_cmd (SCpnt, (void *) scsi_cmd,
+ (void *) NULL,
+ 0, SCSI_TIMEOUT + 4 * HZ, 5);
+
+ SCSI_LOG_SCAN_BUS(3, printk("scsi: scan_scsis_single id %d lun %d. Return code 0x%08x\n",
+ dev, lun, SCpnt->result));
+ SCSI_LOG_SCAN_BUS(3, print_driverbyte(SCpnt->result));
+ SCSI_LOG_SCAN_BUS(3, print_hostbyte(SCpnt->result));
+ SCSI_LOG_SCAN_BUS(3, printk("\n"));
+
+ if (SCpnt->result) {
+ if (((driver_byte(SCpnt->result) & DRIVER_SENSE) ||
+ (status_byte(SCpnt->result) & CHECK_CONDITION)) &&
+ ((SCpnt->sense_buffer[0] & 0x70) >> 4) == 7) {
+ if (((SCpnt->sense_buffer[2] & 0xf) != NOT_READY) &&
+ ((SCpnt->sense_buffer[2] & 0xf) != UNIT_ATTENTION) &&
+ ((SCpnt->sense_buffer[2] & 0xf) != ILLEGAL_REQUEST || lun > 0))
+ return 1;
+ } else
+ return 0;
+ }
+ SCSI_LOG_SCAN_BUS(3, printk("scsi: performing INQUIRY\n"));
+ /*
+ * Build an INQUIRY command block.
+ */
+ scsi_cmd[0] = INQUIRY;
+ scsi_cmd[1] = (lun << 5) & 0xe0;
+ scsi_cmd[2] = 0;
+ scsi_cmd[3] = 0;
+ scsi_cmd[4] = 255;
+ scsi_cmd[5] = 0;
+ SCpnt->cmd_len = 0;
+
+ scsi_wait_cmd (SCpnt, (void *) scsi_cmd,
+ (void *) scsi_result,
+ 256, SCSI_TIMEOUT, 3);
+
+ SCSI_LOG_SCAN_BUS(3, printk("scsi: INQUIRY %s with code 0x%x\n",
+ SCpnt->result ? "failed" : "successful", SCpnt->result));
+
+ if (SCpnt->result)
+ return 0; /* assume no peripheral if any sort of error */
+
+ /*
+ * Check the peripheral qualifier field - this tells us whether LUNS
+ * are supported here or not.
+ */
+ if ((scsi_result[0] >> 5) == 3) {
+ return 0; /* assume no peripheral if any sort of error */
+ }
+
+ /*
+ * Get any flags for this device.
+ */
+ bflags = get_device_flags (scsi_result);
+
+
+ /* The Toshiba ROM was "gender-changed" here as an inline hack.
+ This is now much more generic.
+ This is a mess: What we really want is to leave the scsi_result
+ alone, and just change the SDpnt structure. And the SDpnt is what
+ we want print_inquiry to print. -- REW
+ */
+ if (bflags & BLIST_ISDISK) {
+ scsi_result[0] = TYPE_DISK;
+ scsi_result[1] |= 0x80; /* removable */
+ }
+
+ if (bflags & BLIST_ISROM) {
+ scsi_result[0] = TYPE_ROM;
+ scsi_result[1] |= 0x80; /* removable */
+ }
+
+ if (bflags & BLIST_GHOST) {
+ if ((ghost_channel == channel) && (ghost_dev == dev) && (org_lun == 1)) {
+ lun=1;
+ } else {
+ ghost_channel = channel;
+ ghost_dev = dev;
+ scsi_result[0] = TYPE_MOD;
+ scsi_result[1] |= 0x80; /* removable */
+ }
+ }
+
+
+ memcpy(SDpnt->vendor, scsi_result + 8, 8);
+ memcpy(SDpnt->model, scsi_result + 16, 16);
+ memcpy(SDpnt->rev, scsi_result + 32, 4);
+
+ SDpnt->removable = (0x80 & scsi_result[1]) >> 7;
+ SDpnt->online = TRUE;
+ SDpnt->lockable = SDpnt->removable;
+ SDpnt->changed = 0;
+ SDpnt->access_count = 0;
+ SDpnt->busy = 0;
+ SDpnt->has_cmdblocks = 0;
+ /*
+ * Currently, all sequential devices are assumed to be tapes, all random
+ * devices disk, with the appropriate read only flags set for ROM / WORM
+ * treated as RO.
+ */
+ switch (type = (scsi_result[0] & 0x1f)) {
+ case TYPE_TAPE:
+ case TYPE_DISK:
+ case TYPE_MOD:
+ case TYPE_PROCESSOR:
+ case TYPE_SCANNER:
+ case TYPE_MEDIUM_CHANGER:
+ case TYPE_ENCLOSURE:
+ SDpnt->writeable = 1;
+ break;
+ case TYPE_WORM:
+ case TYPE_ROM:
+ SDpnt->writeable = 0;
+ break;
+ default:
+ printk("scsi: unknown type %d\n", type);
+ }
+
+ SDpnt->device_blocked = FALSE;
+ SDpnt->device_busy = 0;
+ SDpnt->single_lun = 0;
+ SDpnt->soft_reset =
+ (scsi_result[7] & 1) && ((scsi_result[3] & 7) == 2);
+ SDpnt->random = (type == TYPE_TAPE) ? 0 : 1;
+ SDpnt->type = (type & 0x1f);
+
+ print_inquiry(scsi_result);
+
+ for (sdtpnt = scsi_devicelist; sdtpnt;
+ sdtpnt = sdtpnt->next)
+ if (sdtpnt->detect)
+ SDpnt->attached +=
+ (*sdtpnt->detect) (SDpnt);
+
+ SDpnt->scsi_level = scsi_result[2] & 0x07;
+ if (SDpnt->scsi_level >= 2 ||
+ (SDpnt->scsi_level == 1 &&
+ (scsi_result[3] & 0x0f) == 1))
+ SDpnt->scsi_level++;
+
+ /*
+ * Accommodate drivers that want to sleep when they should be in a polling
+ * loop.
+ */
+ SDpnt->disconnect = 0;
+
+
+ /*
+ * Set the tagged_queue flag for SCSI-II devices that purport to support
+ * tagged queuing in the INQUIRY data.
+ */
+ SDpnt->tagged_queue = 0;
+ if ((SDpnt->scsi_level >= SCSI_2) &&
+ (scsi_result[7] & 2) &&
+ !(bflags & BLIST_NOTQ)) {
+ SDpnt->tagged_supported = 1;
+ SDpnt->current_tag = 0;
+ }
+ /*
+ * Some revisions of the Texel CD ROM drives have handshaking problems when
+ * used with the Seagate controllers. Before we know what type of device
+ * we're talking to, we assume it's borken and then change it here if it
+ * turns out that it isn't a TEXEL drive.
+ */
+ if ((bflags & BLIST_BORKEN) == 0)
+ SDpnt->borken = 0;
+
+ /*
+ * 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.
+ */
+ if (bflags & BLIST_SINGLELUN)
+ SDpnt->single_lun = 1;
+
+ /*
+ * These devices need this "key" to unlock the devices so we can use it
+ */
+ if ((bflags & BLIST_KEY) != 0) {
+ printk("Unlocked floptical drive.\n");
+ SDpnt->lockable = 0;
+ scsi_cmd[0] = MODE_SENSE;
+ scsi_cmd[1] = (lun << 5) & 0xe0;
+ scsi_cmd[2] = 0x2e;
+ scsi_cmd[3] = 0;
+ scsi_cmd[4] = 0x2a;
+ scsi_cmd[5] = 0;
+ SCpnt->cmd_len = 0;
+ scsi_wait_cmd (SCpnt, (void *) scsi_cmd,
+ (void *) scsi_result, 0x2a,
+ SCSI_TIMEOUT, 3);
+ }
+ /*
+ * Detach the command from the device. It was just a temporary to be used while
+ * scanning the bus - the real ones will be allocated later.
+ */
+ SDpnt->device_queue = NULL;
+
+ /*
+ * This device was already hooked up to the host in question,
+ * so at this point we just let go of it and it should be fine. We do need to
+ * allocate a new one and attach it to the host so that we can further scan the bus.
+ */
+ SDpnt = (Scsi_Device *) kmalloc(sizeof(Scsi_Device), GFP_ATOMIC);
+ *SDpnt2 = SDpnt;
+ if (!SDpnt) {
+ printk("scsi: scan_scsis_single: Cannot malloc\n");
+ return 0;
+ }
+ memset(SDpnt, 0, sizeof(Scsi_Device));
+
+ /*
+ * Register the queue for the device. All I/O requests will come
+ * in through here. We also need to register a pointer to
+ * ourselves, since the queue handler won't know what device
+ * the queue actually represents. We could look it up, but it
+ * is pointless work.
+ */
+ blk_init_queue(&SDpnt->request_queue, scsi_get_request_handler(SDpnt, shpnt));
+ blk_queue_headactive(&SDpnt->request_queue, 0);
+ SDpnt->request_queue.queuedata = (void *) SDpnt;
+ SDpnt->host = shpnt;
+ initialize_merge_fn(SDpnt);
+
+ /*
+ * And hook up our command block to the new device we will be testing
+ * for.
+ */
+ SDpnt->device_queue = SCpnt;
+ SDpnt->online = TRUE;
+
+ /*
+ * Initialize the object that we will use to wait for command blocks.
+ */
+ init_waitqueue_head(&SDpnt->scpnt_wait);
+
+ /*
+ * Since we just found one device, there had damn well better be one in the list
+ * already.
+ */
+ if (shpnt->host_queue == NULL)
+ panic("scan_scsis_single: Host queue == NULL\n");
+
+ SDtail = shpnt->host_queue;
+ while (SDtail->next) {
+ SDtail = SDtail->next;
+ }
+
+ /* Add this device to the linked list at the end */
+ SDtail->next = SDpnt;
+ SDpnt->prev = SDtail;
+ SDpnt->next = NULL;
+
+ /*
+ * Some scsi devices cannot be polled for lun != 0 due to firmware bugs
+ */
+ if (bflags & BLIST_NOLUN)
+ return 0; /* break; */
+
+ /*
+ * If this device is known to support sparse multiple units, override the
+ * other settings, and scan all of them.
+ */
+ if (bflags & BLIST_SPARSELUN) {
+ *max_dev_lun = 8;
+ *sparse_lun = 1;
+ return 1;
+ }
+ /*
+ * If this device is known to support multiple units, override the other
+ * settings, and scan all of them.
+ */
+ if (bflags & BLIST_FORCELUN) {
+ *max_dev_lun = 8;
+ return 1;
+ }
+ /*
+ * REGAL CDC-4X: avoid hang after LUN 4
+ */
+ if (bflags & BLIST_MAX5LUN) {
+ *max_dev_lun = 5;
+ return 1;
+ }
+
+ /*
+ * If this device is Ghosted, scan upto two luns. (It physically only
+ * has one). -- REW
+ */
+ if (bflags & BLIST_GHOST) {
+ *max_dev_lun = 2;
+ return 1;
+ }
+
+
+ /*
+ * We assume the device can't handle lun!=0 if: - it reports scsi-0 (ANSI
+ * SCSI Revision 0) (old drives like MAXTOR XT-3280) or - it reports scsi-1
+ * (ANSI SCSI Revision 1) and Response Data Format 0
+ */
+ if (((scsi_result[2] & 0x07) == 0)
+ ||
+ ((scsi_result[2] & 0x07) == 1 &&
+ (scsi_result[3] & 0x0f) == 0))
+ return 0;
+ return 1;
+}
+
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index b615f8a38..0790a1978 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -640,17 +640,6 @@ static int check_scsidisk_media_change(kdev_t full_dev)
return retval;
}
-static void sd_init_done(Scsi_Cmnd * SCpnt)
-{
- struct request *req;
-
- req = &SCpnt->request;
- req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
-
- if (req->sem != NULL) {
- up(req->sem);
- }
-}
static int sd_init_onedisk(int i)
{
unsigned char cmd[10];
@@ -698,7 +687,7 @@ static int sd_init_onedisk(int i)
SCpnt->sense_buffer[2] = 0;
scsi_wait_cmd (SCpnt, (void *) cmd, (void *) buffer,
- 0/*512*/, sd_init_done, SD_TIMEOUT, MAX_RETRIES);
+ 0/*512*/, SD_TIMEOUT, MAX_RETRIES);
the_result = SCpnt->result;
retries++;
@@ -724,7 +713,7 @@ static int sd_init_onedisk(int i)
SCpnt->sense_buffer[2] = 0;
scsi_wait_cmd(SCpnt, (void *) cmd, (void *) buffer,
- 512, sd_init_done, SD_TIMEOUT, MAX_RETRIES);
+ 512, SD_TIMEOUT, MAX_RETRIES);
}
spintime = 1;
spintime_value = jiffies;
@@ -754,7 +743,7 @@ static int sd_init_onedisk(int i)
SCpnt->sense_buffer[2] = 0;
scsi_wait_cmd(SCpnt, (void *) cmd, (void *) buffer,
- 8, sd_init_done, SD_TIMEOUT, MAX_RETRIES);
+ 8, SD_TIMEOUT, MAX_RETRIES);
the_result = SCpnt->result;
retries--;
@@ -905,7 +894,7 @@ static int sd_init_onedisk(int i)
/* same code as READCAPA !! */
scsi_wait_cmd(SCpnt, (void *) cmd, (void *) buffer,
- 512, sd_init_done, SD_TIMEOUT, MAX_RETRIES);
+ 512, SD_TIMEOUT, MAX_RETRIES);
the_result = SCpnt->result;
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 0abc06cf3..e683405b7 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -456,18 +456,6 @@ static int sr_attach(Scsi_Device * SDp)
}
-static void sr_init_done(Scsi_Cmnd * SCpnt)
-{
- struct request *req;
-
- req = &SCpnt->request;
- req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
-
- if (req->sem != NULL) {
- up(req->sem);
- }
-}
-
void get_sectorsize(int i)
{
unsigned char cmd[10];
@@ -494,7 +482,7 @@ void get_sectorsize(int i)
/* Do the command and wait.. */
scsi_wait_cmd(SCpnt, (void *) cmd, (void *) buffer,
- 512, sr_init_done, SR_TIMEOUT, MAX_RETRIES);
+ 512, SR_TIMEOUT, MAX_RETRIES);
the_result = SCpnt->result;
retries--;
@@ -671,11 +659,11 @@ static int sr_packet(struct cdrom_device_info *cdi, struct cdrom_generic_command
/* do the locking and issue the command */
SCpnt->request.rq_dev = cdi->dev;
- /* scsi_do_cmd sets the command length */
+ /* scsi_wait_cmd sets the command length */
SCpnt->cmd_len = 0;
scsi_wait_cmd(SCpnt, (void *) cgc->cmd, (void *) buffer, cgc->buflen,
- sr_init_done, SR_TIMEOUT, MAX_RETRIES);
+ SR_TIMEOUT, MAX_RETRIES);
if ((cgc->stat = SCpnt->result))
cgc->sense = (struct request_sense *) SCpnt->sense_buffer;
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index 5032d7f86..9d08b209b 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -30,23 +30,6 @@ extern void get_sectorsize(int);
/* In fact, it is very slow if it has to spin up first */
#define IOCTL_TIMEOUT 30*HZ
-static void sr_ioctl_done(Scsi_Cmnd * SCpnt)
-{
- struct request *req;
-
- req = &SCpnt->request;
- req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
-
- if (SCpnt->buffer && req->buffer && SCpnt->buffer != req->buffer) {
- memcpy(req->buffer, SCpnt->buffer, SCpnt->bufflen);
- scsi_free(SCpnt->buffer, (SCpnt->bufflen + 511) & ~511);
- SCpnt->buffer = req->buffer;
- }
- if (req->sem != NULL) {
- up(req->sem);
- }
-}
-
/* We do our own retries because we want to know what the specific
error code is. Normally the UNIT_ATTENTION code will automatically
clear after one error */
@@ -55,6 +38,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen
{
Scsi_Cmnd *SCpnt;
Scsi_Device *SDev;
+ struct request *req;
int result, err = 0, retries = 0;
char *bounce_buffer;
@@ -79,7 +63,14 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen
scsi_wait_cmd(SCpnt, (void *) sr_cmd, (void *) buffer, buflength,
- sr_ioctl_done, IOCTL_TIMEOUT, IOCTL_RETRIES);
+ IOCTL_TIMEOUT, IOCTL_RETRIES);
+
+ req = &SCpnt->request;
+ if (SCpnt->buffer && req->buffer && SCpnt->buffer != req->buffer) {
+ memcpy(req->buffer, SCpnt->buffer, SCpnt->bufflen);
+ scsi_free(SCpnt->buffer, (SCpnt->bufflen + 511) & ~511);
+ SCpnt->buffer = req->buffer;
+ }
result = SCpnt->result;
@@ -262,14 +253,14 @@ int sr_reset(struct cdrom_device_info *cdi)
int sr_select_speed(struct cdrom_device_info *cdi, int speed)
{
- u_char sr_cmd[12];
+ u_char sr_cmd[MAX_COMMAND_SIZE];
if (speed == 0)
speed = 0xffff; /* set to max */
else
speed *= 177; /* Nx to kbyte/s */
- memset(sr_cmd, 0, 12);
+ memset(sr_cmd, 0, MAX_COMMAND_SIZE);
sr_cmd[0] = GPCMD_SET_SPEED; /* SET CD SPEED */
sr_cmd[1] = (scsi_CDs[MINOR(cdi->dev)].device->lun) << 5;
sr_cmd[2] = (speed >> 8) & 0xff; /* MSB for speed (in kbytes/sec) */
@@ -370,14 +361,14 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
int sr_read_cd(int minor, unsigned char *dest, int lba, int format, int blksize)
{
- unsigned char cmd[12];
+ unsigned char cmd[MAX_COMMAND_SIZE];
#ifdef DEBUG
printk("sr%d: sr_read_cd lba=%d format=%d blksize=%d\n",
minor, lba, format, blksize);
#endif
- memset(cmd, 0, 12);
+ memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = GPCMD_READ_CD; /* READ_CD */
cmd[1] = (scsi_CDs[minor].device->lun << 5) | ((format & 7) << 2);
cmd[2] = (unsigned char) (lba >> 24) & 0xff;
@@ -408,7 +399,7 @@ int sr_read_cd(int minor, unsigned char *dest, int lba, int format, int blksize)
int sr_read_sector(int minor, int lba, int blksize, unsigned char *dest)
{
- unsigned char cmd[12]; /* the scsi-command */
+ unsigned char cmd[MAX_COMMAND_SIZE]; /* the scsi-command */
int rc;
/* we try the READ CD command first... */
@@ -429,7 +420,7 @@ int sr_read_sector(int minor, int lba, int blksize, unsigned char *dest)
printk("sr%d: sr_read_sector lba=%d blksize=%d\n", minor, lba, blksize);
#endif
- memset(cmd, 0, 12);
+ memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = GPCMD_READ_10;
cmd[1] = (scsi_CDs[minor].device->lun << 5);
cmd[2] = (unsigned char) (lba >> 24) & 0xff;
diff --git a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c
index 56f4f004d..77be00ea3 100644
--- a/drivers/scsi/sr_vendor.c
+++ b/drivers/scsi/sr_vendor.c
@@ -106,7 +106,7 @@ void sr_vendor_init(int minor)
int sr_set_blocklength(int minor, int blocklength)
{
unsigned char *buffer; /* the buffer for the ioctl */
- unsigned char cmd[12]; /* the scsi-command */
+ unsigned char cmd[MAX_COMMAND_SIZE]; /* the scsi-command */
struct ccs_modesel_head *modesel;
int rc, density = 0;
@@ -122,7 +122,7 @@ int sr_set_blocklength(int minor, int blocklength)
#ifdef DEBUG
printk("sr%d: MODE SELECT 0x%x/%d\n", minor, density, blocklength);
#endif
- memset(cmd, 0, 12);
+ memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = MODE_SELECT;
cmd[1] = (scsi_CDs[minor].device->lun << 5) | (1 << 4);
cmd[4] = 12;
@@ -153,7 +153,7 @@ int sr_cd_check(struct cdrom_device_info *cdi)
{
unsigned long sector;
unsigned char *buffer; /* the buffer for the ioctl */
- unsigned char cmd[12]; /* the scsi-command */
+ unsigned char cmd[MAX_COMMAND_SIZE]; /* the scsi-command */
int rc, no_multi, minor;
minor = MINOR(cdi->dev);
@@ -171,7 +171,7 @@ int sr_cd_check(struct cdrom_device_info *cdi)
switch (VENDOR_ID) {
case VENDOR_SCSI3:
- memset(cmd, 0, 12);
+ memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = READ_TOC;
cmd[1] = (scsi_CDs[minor].device->lun << 5);
cmd[8] = 12;
@@ -196,7 +196,7 @@ int sr_cd_check(struct cdrom_device_info *cdi)
#ifdef CONFIG_BLK_DEV_SR_VENDOR
case VENDOR_NEC:{
unsigned long min, sec, frame;
- memset(cmd, 0, 12);
+ memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = 0xde;
cmd[1] = (scsi_CDs[minor].device->lun << 5) | 0x03;
cmd[2] = 0xb0;
@@ -221,7 +221,7 @@ int sr_cd_check(struct cdrom_device_info *cdi)
/* we request some disc information (is it a XA-CD ?,
* where starts the last session ?) */
- memset(cmd, 0, 12);
+ memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = 0xc7;
cmd[1] = (scsi_CDs[minor].device->lun << 5) | 3;
rc = sr_do_ioctl(minor, cmd, buffer, 4, 1);
@@ -244,7 +244,7 @@ int sr_cd_check(struct cdrom_device_info *cdi)
}
case VENDOR_WRITER:
- memset(cmd, 0, 12);
+ memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = READ_TOC;
cmd[1] = (scsi_CDs[minor].device->lun << 5);
cmd[8] = 0x04;
diff --git a/drivers/sgi/char/graphics.c b/drivers/sgi/char/graphics.c
index 310acbdc5..9fe649b03 100644
--- a/drivers/sgi/char/graphics.c
+++ b/drivers/sgi/char/graphics.c
@@ -1,4 +1,4 @@
-/* $Id: graphics.c,v 1.20 2000/01/29 01:42:19 ralf Exp $
+/* $Id: graphics.c,v 1.21 2000/02/05 06:47:30 ralf Exp $
*
* gfx.c: support for SGI's /dev/graphics, /dev/opengl
*
@@ -254,15 +254,7 @@ sgi_graphics_nopage (struct vm_area_struct *vma, unsigned long address, int
*/
static struct vm_operations_struct graphics_mmap = {
- NULL, /* no special mmap-open */
- NULL, /* no special mmap-close */
- NULL, /* no special mmap-unmap */
- NULL, /* no special mmap-protect */
- NULL, /* no special mmap-sync */
- NULL, /* no special mmap-advise */
- sgi_graphics_nopage, /* our magic no-page fault handler */
- NULL, /* no special mmap-wppage */
- NULL /* no special mmap-swapout */
+ nopage: sgi_graphics_nopage, /* our magic no-page fault handler */
};
int
diff --git a/drivers/sgi/char/shmiq.c b/drivers/sgi/char/shmiq.c
index f182e227f..153df30be 100644
--- a/drivers/sgi/char/shmiq.c
+++ b/drivers/sgi/char/shmiq.c
@@ -1,4 +1,4 @@
-/* $Id: shmiq.c,v 1.16 2000/01/29 01:42:19 ralf Exp $
+/* $Id: shmiq.c,v 1.17 2000/02/05 06:47:30 ralf Exp $
*
* shmiq.c: shared memory input queue driver
* written 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -296,15 +296,7 @@ shmiq_nopage (struct vm_area_struct *vma, unsigned long address, int write_acces
}
static struct vm_operations_struct qcntl_mmap = {
- NULL, /* no special mmap-open */
- NULL, /* no special mmap-close */
- NULL, /* no special mmap-unmap */
- NULL, /* no special mmap-protect */
- NULL, /* no special mmap-sync */
- NULL, /* no special mmap-advise */
- shmiq_nopage, /* our magic no-page fault handler */
- NULL, /* no special mmap-wppage */
- NULL /* no special mmap-swapout */
+ nopage: shmiq_nopage, /* our magic no-page fault handler */
};
static int
diff --git a/drivers/sound/ad1848.c b/drivers/sound/ad1848.c
index 8de63a068..498db82f0 100644
--- a/drivers/sound/ad1848.c
+++ b/drivers/sound/ad1848.c
@@ -71,7 +71,8 @@ typedef struct
#define MD_4232 5
#define MD_C930 6
#define MD_IWAVE 7
-#define MD_4235 8 /* Crystal Audio CS4235 */
+#define MD_4235 8 /* Crystal Audio CS4235 */
+#define MD_1845_SSCAPE 9 /* Ensoniq Soundscape PNP*/
/* Mixer parameters */
int recmask;
@@ -100,6 +101,7 @@ ad1848_port_info;
static int nr_ad1848_devs = 0;
int deskpro_xl = 0;
+int deskpro_m = 0;
#ifdef CONFIG_SOUND_SPRO
int soundpro = 1;
#else
@@ -117,7 +119,7 @@ static int timer_installed = -1;
#endif
-static int ad_format_mask[9 /*devc->model */ ] =
+static int ad_format_mask[10 /*devc->model */ ] =
{
0,
AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW,
@@ -127,7 +129,8 @@ static int ad_format_mask[9 /*devc->model */ ] =
AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM,
AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM,
AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM,
- AFMT_U8 | AFMT_S16_LE /* CS4235 */
+ AFMT_U8 | AFMT_S16_LE /* CS4235 */,
+ AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW /* Ensoniq Soundscape*/
};
static ad1848_info adev_info[MAX_AUDIO_DEV];
@@ -140,7 +143,7 @@ static ad1848_info adev_info[MAX_AUDIO_DEV];
static struct {
unsigned char flags;
#define CAP_F_TIMER 0x01
-} capabilities [9 /*devc->model */ ] = {
+} capabilities [10 /*devc->model */ ] = {
{0}
,{0} /* MD_1848 */
,{CAP_F_TIMER} /* MD_4231 */
@@ -149,7 +152,8 @@ static struct {
,{CAP_F_TIMER} /* MD_4232 */
,{0} /* MD_C930 */
,{CAP_F_TIMER} /* MD_IWAVE */
- ,{0} /* MD_4235 */
+ ,{0} /* MD_4235 */
+ ,{CAP_F_TIMER} /* MD_1845_SSCAPE */
};
static int ad1848_open(int dev, int mode);
@@ -231,7 +235,7 @@ static void wait_for_calibration(ad1848_info * devc)
while (timeout > 0 && (ad_read(devc, 11) & 0x20))
timeout--;
if (ad_read(devc, 11) & 0x20)
- if (devc->model != MD_1845)
+ if ( (devc->model != MD_1845) || (devc->model != MD_1845_SSCAPE))
printk(KERN_WARNING "ad1848: Auto calibration timed out(3).\n");
}
@@ -555,6 +559,7 @@ static void ad1848_mixer_reset(ad1848_info * devc)
case MD_4231:
case MD_4231A:
case MD_1845:
+ case MD_1845_SSCAPE:
devc->supported_devices = MODE2_MIXER_DEVICES;
break;
@@ -751,7 +756,7 @@ static int ad1848_set_speed(int dev, int arg)
if (arg <= 0)
return portc->speed;
- if (devc->model == MD_1845) /* AD1845 has different timer than others */
+ if (devc->model == MD_1845 || devc->model == MD_1845_SSCAPE) /* AD1845 has different timer than others */
{
if (arg < 4000)
arg = 4000;
@@ -1087,7 +1092,7 @@ static int ad1848_prepare_for_output(int dev, int bsize, int bcount)
ad_enter_MCE(devc); /* Enables changes to the format select reg */
- if (devc->model == MD_1845) /* Use alternate speed select registers */
+ if (devc->model == MD_1845 || devc->model == MD_1845_SSCAPE) /* Use alternate speed select registers */
{
fs &= 0xf0; /* Mask off the rate select bits */
@@ -1157,7 +1162,7 @@ static int ad1848_prepare_for_input(int dev, int bsize, int bcount)
ad_enter_MCE(devc); /* Enables changes to the format select reg */
- if (devc->model == MD_1845) /* Use alternate speed select registers */
+ if ((devc->model == MD_1845) || (devc->model == MD_1845_SSCAPE)) /* Use alternate speed select registers */
{
fs &= 0xf0; /* Mask off the rate select bits */
@@ -1193,7 +1198,7 @@ static int ad1848_prepare_for_input(int dev, int bsize, int bcount)
while (timeout < 10000 && inb(devc->base) == 0x80)
timeout++;
- if (devc->model != MD_1848 && devc->model != MD_1845)
+ if (devc->model != MD_1848 && devc->model != MD_1845 && devc->model != MD_1845_SSCAPE)
{
/*
* CS4231 compatible devices don't have separate sampling rate selection
@@ -1405,13 +1410,17 @@ static void ad1848_init_hw(ad1848_info * devc)
if (devc->model > MD_1848)
{
- ad_write(devc, 12, ad_read(devc, 12) | 0x40); /* Mode2 = enabled */
+ if (devc->model == MD_1845_SSCAPE)
+ ad_write(devc, 12, ad_read(devc, 12) | 0x50);
+ else
+ ad_write(devc, 12, ad_read(devc, 12) | 0x40); /* Mode2 = enabled */
if (devc->model == MD_IWAVE)
ad_write(devc, 12, 0x6c); /* Select codec mode 3 */
- for (i = 16; i < 32; i++)
- ad_write(devc, i, init_values[i]);
+ if (devc-> model != MD_1845_SSCAPE)
+ for (i = 16; i < 32; i++)
+ ad_write(devc, i, init_values[i]);
if (devc->model == MD_IWAVE)
ad_write(devc, 16, 0x30); /* Playback and capture counters enabled */
@@ -1423,7 +1432,7 @@ static void ad1848_init_hw(ad1848_info * devc)
else
ad_write(devc, 9, ad_read(devc, 9) | 0x04); /* Single DMA mode */
- if (devc->model == MD_1845)
+ if (devc->model == MD_1845 || devc->model == MD_1845_SSCAPE)
ad_write(devc, 27, ad_read(devc, 27) | 0x08); /* Alternate freq select enabled */
if (devc->model == MD_IWAVE)
@@ -1462,6 +1471,7 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp)
int interwave = 0;
int ad1847_flag = 0;
int cs4248_flag = 0;
+ int sscape_flag = 0;
int i;
@@ -1474,6 +1484,13 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp)
interwave = 1;
*ad_flags = 0;
}
+
+ if (*ad_flags == 0x87654321)
+ {
+ sscape_flag = 1;
+ *ad_flags = 0;
+ }
+
if (*ad_flags == 0x12345677)
{
cs4248_flag = 1;
@@ -1821,6 +1838,9 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp)
devc->chip_name = "AD1847";
+ if (sscape_flag == 1)
+ devc->model = MD_1845_SSCAPE;
+
return 1;
}
@@ -1979,7 +1999,7 @@ int ad1848_control(int cmd, int arg)
switch (cmd)
{
case AD1848_SET_XTAL: /* Change clock frequency of AD1845 (only ) */
- if (devc->model != MD_1845)
+ if (devc->model != MD_1845 || devc->model != MD_1845_SSCAPE)
return -EINVAL;
ad_enter_MCE(devc);
ad_write(devc, 29, (ad_read(devc, 29) & 0x1f) | (arg << 5));
@@ -2146,6 +2166,34 @@ interrupt_again: /* Jump back here if int status doesn't reset */
/*
* Experimental initialization sequence for the integrated sound system
+ * of the Compaq Deskpro M.
+ */
+
+static int init_deskpro_m(struct address_info *hw_config)
+{
+ unsigned char tmp;
+
+ if ((tmp = inb(0xc44)) == 0xff)
+ {
+ DDB(printk("init_deskpro_m: Dead port 0xc44\n"));
+ return 0;
+ }
+
+ outb(0x10, 0xc44);
+ outb(0x40, 0xc45);
+ outb(0x00, 0xc46);
+ outb(0xe8, 0xc47);
+ outb(0x14, 0xc44);
+ outb(0x40, 0xc45);
+ outb(0x00, 0xc46);
+ outb(0xe8, 0xc47);
+ outb(0x10, 0xc44);
+
+ return 1;
+}
+
+/*
+ * Experimental initialization sequence for the integrated sound system
* of Compaq Deskpro XL.
*/
@@ -2370,6 +2418,12 @@ int probe_ms_sound(struct address_info *hw_config)
return 0;
}
+ if (deskpro_m) /* Compaq Deskpro M */
+ {
+ if (!init_deskpro_m(hw_config))
+ return 0;
+ }
+
/*
* Check if the IO port returns valid signature. The original MS Sound
* system returns 0x04 while some cards (AudioTrix Pro for example)
@@ -2558,7 +2612,7 @@ static unsigned int ad1848_tmr_start(int dev, unsigned int usecs)
* the timer divider.
*/
- if (devc->model == MD_1845)
+ if (devc->model == MD_1845 || devc->model == MD_1845_SSCAPE)
xtal_nsecs = 10050;
else if (ad_read(devc, 8) & 0x01)
xtal_nsecs = 9920;
@@ -2659,6 +2713,7 @@ MODULE_PARM(dma, "i"); /* First DMA channel */
MODULE_PARM(dma2, "i"); /* Second DMA channel */
MODULE_PARM(type, "i"); /* Card type */
MODULE_PARM(deskpro_xl, "i"); /* Special magic for Deskpro XL boxen */
+MODULE_PARM(deskpro_m, "i"); /* Special magic for Deskpro M box */
MODULE_PARM(soundpro, "i"); /* More special magic for SoundPro chips */
int io = -1;
diff --git a/drivers/sound/audio.c b/drivers/sound/audio.c
index 716e738e4..b15a9423c 100644
--- a/drivers/sound/audio.c
+++ b/drivers/sound/audio.c
@@ -228,7 +228,7 @@ int audio_write(int dev, struct file *file, const char *buf, int count)
{
/* Handle nonblocking mode */
if ((file->f_flags & O_NONBLOCK) && err == -EAGAIN)
- return p; /* No more space. Return # of accepted bytes */
+ return p? p : -EAGAIN; /* No more space. Return # of accepted bytes */
return err;
}
l = c;
@@ -308,12 +308,12 @@ int audio_read(int dev, struct file *file, char *buf, int count)
* Nonblocking mode handling. Return current # of bytes
*/
- if ((file->f_flags & O_NONBLOCK) && buf_no == -EAGAIN)
- return p;
-
if (p > 0) /* Avoid throwing away data */
return p; /* Return it instead */
+ if ((file->f_flags & O_NONBLOCK) && buf_no == -EAGAIN)
+ return -EAGAIN;
+
return buf_no;
}
if (l > c)
diff --git a/drivers/sound/cmpci.c b/drivers/sound/cmpci.c
index c7bbffca6..e01aa2429 100644
--- a/drivers/sound/cmpci.c
+++ b/drivers/sound/cmpci.c
@@ -2315,7 +2315,7 @@ static int four_ch = 0;
#ifdef CONFIG_SOUND_CMPCI_REAR
static int rear_out = 1;
#else
-static int read_out = 0;
+static int rear_out = 0;
#endif
int __init init_cmpci(void)
@@ -2377,6 +2377,7 @@ int __init init_cmpci(void)
s->iobase = pcidev->resource[0].start;
s->iosynth = 0x388;
s->iomidi = 0x330;
+ spin_lock_init(&s->lock);
if (s->iobase == 0)
continue;
s->irq = pcidev->irq;
diff --git a/drivers/sound/dmasound.c b/drivers/sound/dmasound.c
index c6ec28253..410a8fbd9 100644
--- a/drivers/sound/dmasound.c
+++ b/drivers/sound/dmasound.c
@@ -2891,10 +2891,13 @@ static void ata_sq_interrupt(int irq, void *dummy, struct pt_regs *fp)
* Amiga
*/
+#define StopDMA() custom.aud[0].audvol = custom.aud[1].audvol = 0; \
+ custom.aud[2].audvol = custom.aud[3].audvol = 0; \
+ custom.dmacon = AMI_AUDIO_OFF;
static void *AmiAlloc(unsigned int size, int flags)
{
- return(amiga_chip_alloc((long)size));
+ return amiga_chip_alloc((long)size, "dmasound");
}
static void AmiFree(void *obj, unsigned int size)
@@ -2905,7 +2908,7 @@ static void AmiFree(void *obj, unsigned int size)
static int __init AmiIrqInit(void)
{
/* turn off DMA for audio channels */
- custom.dmacon = AMI_AUDIO_OFF;
+ StopDMA();
/* Register interrupt handler. */
if (request_irq(IRQ_AMIGA_AUD0, ami_sq_interrupt, 0,
@@ -2918,7 +2921,7 @@ static int __init AmiIrqInit(void)
static void AmiIrqCleanUp(void)
{
/* turn off DMA for audio channels */
- custom.dmacon = AMI_AUDIO_OFF;
+ StopDMA();
/* release the interrupt */
free_irq(IRQ_AMIGA_AUD0, ami_sq_interrupt);
}
@@ -2927,7 +2930,7 @@ static void AmiIrqCleanUp(void)
static void AmiSilence(void)
{
/* turn off DMA for audio channels */
- custom.dmacon = AMI_AUDIO_OFF;
+ StopDMA();
}
@@ -3008,6 +3011,15 @@ static int AmiSetVolume(int volume)
custom.aud[0].audvol = sound.volume_left;
sound.volume_right = VOLUME_VOXWARE_TO_AMI((volume & 0xff00) >> 8);
custom.aud[1].audvol = sound.volume_right;
+ if (sound.hard.size == 16) {
+ if (sound.volume_left == 64 && sound.volume_right == 64) {
+ custom.aud[2].audvol = 1;
+ custom.aud[3].audvol = 1;
+ } else {
+ custom.aud[2].audvol = 0;
+ custom.aud[3].audvol = 0;
+ }
+ }
return(VOLUME_AMI_TO_VOXWARE(sound.volume_left) |
(VOLUME_AMI_TO_VOXWARE(sound.volume_right) << 8));
}
@@ -3047,6 +3059,9 @@ static void ami_sq_play_next_frame(int index)
ch0 = start;
ch1 = start;
}
+
+ custom.aud[0].audvol = sound.volume_left;
+ custom.aud[1].audvol = sound.volume_right;
if (sound.hard.size == 8) {
custom.aud[0].audlc = (u_short *)ZTWO_PADDR(ch0);
custom.aud[0].audlen = size;
@@ -3070,8 +3085,11 @@ static void ami_sq_play_next_frame(int index)
custom.aud[3].audlc = (u_short *)ZTWO_PADDR(ch3);
custom.aud[3].audlen = size;
custom.dmacon = AMI_AUDIO_14;
- } else
+ } else {
+ custom.aud[2].audvol = 0;
+ custom.aud[3].audvol = 0;
custom.dmacon = AMI_AUDIO_8;
+ }
}
sq.front = (sq.front+1) % sq.max_count;
sq.active |= AMI_PLAY_LOADED;
@@ -3118,6 +3136,8 @@ static void ami_sq_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
int minframes = 1;
+ custom.intena = IF_AUD0;
+
if (!sq.active) {
/* Playing was interrupted and sq_reset() has already cleared
* the sq variables, so better don't do anything here.
@@ -3141,7 +3161,9 @@ static void ami_sq_interrupt(int irq, void *dummy, struct pt_regs *fp)
if (!sq.active)
/* No frame is playing, disable audio DMA */
- custom.dmacon = AMI_AUDIO_OFF;
+ StopDMA();
+
+ custom.intena = IF_SETCLR | IF_AUD0;
if (sq.count >= minframes)
/* Try to play the next frame */
diff --git a/drivers/sound/esssolo1.c b/drivers/sound/esssolo1.c
index 255efbc2b..93cfe4772 100644
--- a/drivers/sound/esssolo1.c
+++ b/drivers/sound/esssolo1.c
@@ -71,6 +71,7 @@
/*****************************************************************************/
+#include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/string.h>
diff --git a/drivers/sound/msnd_pinnacle.c b/drivers/sound/msnd_pinnacle.c
index dd1b596f4..0217f3a85 100644
--- a/drivers/sound/msnd_pinnacle.c
+++ b/drivers/sound/msnd_pinnacle.c
@@ -46,6 +46,7 @@
# include <linux/init.h>
#endif
#include <asm/irq.h>
+#include <asm/io.h>
#include "sound_config.h"
#include "sound_firmware.h"
#ifdef MSND_CLASSIC
diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c
index 43c7ad8a6..4bbfe051a 100644
--- a/drivers/sound/soundcard.c
+++ b/drivers/sound/soundcard.c
@@ -164,7 +164,7 @@ static int sound_proc_get_info(char *buffer, char **start, off_t offset, int len
#define MODULEPROCSTRING "Driver compiled into kernel"
#endif
- down(&uts_sem);
+ down_read(&uts_sem);
len = sprintf(buffer, "OSS/Free:" SOUND_VERSION_STRING "\n"
"Load type: " MODULEPROCSTRING "\n"
@@ -172,7 +172,7 @@ static int sound_proc_get_info(char *buffer, char **start, off_t offset, int len
"Config options: %x\n\nInstalled drivers: \n",
system_utsname.sysname, system_utsname.nodename, system_utsname.release,
system_utsname.version, system_utsname.machine, SELECTED_SOUND_OPTIONS);
- up(&uts_sem);
+ up_read(&uts_sem);
for (i = 0; (i < num_sound_drivers) && (pos <= offset + length); i++) {
if (!sound_drivers[i].card_type)
diff --git a/drivers/usb/Config.in b/drivers/usb/Config.in
index b0a372455..aa8c6adb2 100644
--- a/drivers/usb/Config.in
+++ b/drivers/usb/Config.in
@@ -9,7 +9,7 @@ if [ ! "$CONFIG_USB" = "n" ]; then
comment 'USB Controllers'
dep_tristate ' UHCI (Intel PIIX4, VIA, ...) support' CONFIG_USB_UHCI $CONFIG_USB
- dep_tristate ' OHCI-HCD (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI_HCD $CONFIG_USB
+ dep_tristate ' OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB
comment 'Miscellaneous USB options'
bool ' Preliminary USB device filesystem' CONFIG_USB_DEVICEFS
@@ -22,17 +22,19 @@ comment 'USB Devices'
dep_tristate ' USB Serial Converter support' CONFIG_USB_SERIAL $CONFIG_USB
if [ "$CONFIG_USB_SERIAL" != "n" ]; then
bool ' USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC
- bool ' USB ConnectTech WhiteHEAT Serial Driver' CONFIG_USB_SERIAL_WHITEHEAT
bool ' USB Handspring Visor Driver' CONFIG_USB_SERIAL_VISOR
- bool ' USB Belkin Single Port Serial Driver' CONFIG_USB_SERIAL_BELKIN
- bool ' USB Peracom Single Port Serial Driver' CONFIG_USB_SERIAL_PERACOM
+ bool ' USB ConnectTech WhiteHEAT Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_WHITEHEAT
+ bool ' USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI
+ bool ' USB Belkin Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_BELKIN
+ bool ' USB Peracom Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_PERACOM
fi
dep_tristate ' USB CPiA Camera support' CONFIG_USB_CPIA $CONFIG_USB
+ dep_tristate ' USB IBM (Xirlink) C-it Camera support' CONFIG_USB_IBMCAM $CONFIG_USB
dep_tristate ' USB OV511 Camera support' CONFIG_USB_OV511 $CONFIG_USB
dep_tristate ' USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
- dep_tristate ' USB SCSI (mass storage) support' CONFIG_USB_SCSI $CONFIG_USB
- if [ "$CONFIG_USB_SCSI" != "n" ]; then
- bool ' USB SCSI verbose debug' CONFIG_USB_SCSI_DEBUG
+ dep_tristate ' USB Mass Storage support' CONFIG_USB_STORAGE $CONFIG_USB
+ if [ "$CONFIG_USB_STORAGE" != "n" ]; then
+ bool ' USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG
fi
dep_tristate ' USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT
dep_tristate ' DABUSB driver' CONFIG_USB_DABUSB $CONFIG_USB
@@ -48,7 +50,12 @@ comment 'USB HID'
dep_tristate ' Keyboard support' CONFIG_INPUT_KEYBDEV $CONFIG_USB
dep_tristate ' Mouse support' CONFIG_INPUT_MOUSEDEV $CONFIG_USB
if [ "$CONFIG_INPUT_MOUSEDEV" != "n" ]; then
- bool ' Mix all mice into one device' CONFIG_INPUT_MOUSEDEV_MIX
+ bool ' Mix all mice into one device' CONFIG_INPUT_MOUSEDEV_MIX
+ bool ' Support for digitizers' CONFIG_INPUT_MOUSEDEV_DIGITIZER
+ if [ "$CONFIG_INPUT_MOUSEDEV_DIGITIZER" != "n" ]; then
+ int ' Horizontal screen resolution' CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024
+ int ' Vertical screen resolution' CONFIG_INPUT_MOUSEDEV_SCREEN_Y 768
+ fi
fi
dep_tristate ' Joystick support' CONFIG_INPUT_JOYDEV $CONFIG_USB
dep_tristate ' Event interface support' CONFIG_INPUT_EVDEV $CONFIG_USB
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 9eb62b6a1..ee2cee37a 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -21,19 +21,17 @@ export-objs := usb.o input.o
# Multipart objects.
-list-multi := usbcore.o usb-uhci.o usb-ohci-hcd.o
+list-multi := usbcore.o
usbcore-objs := usb.o usb-debug.o usb-core.o hub.o
-usb-uhci-objs := uhci.o uhci-debug.o
-usb-ohci-hcd-objs := ohci-hcd.o
-usb-scsi-objs := usb_scsi.o
+usb-storage-objs := usb_storage.o
# Optional parts of multipart objects.
ifeq ($(CONFIG_USB_DEVICEFS),y)
usbcore-objs += devio.o inode.o drivers.o devices.o
endif
-ifeq ($(CONFIG_USB_SCSI_DEBUG),y)
- usb-scsi-objs += usb_scsi_debug.o
+ifeq ($(CONFIG_USB_STORAGE_DEBUG),y)
+ usb-storage-objs += usb_storage_debug.o
endif
# Object file lists.
@@ -47,7 +45,7 @@ obj- :=
obj-$(CONFIG_USB) += usbcore.o
obj-$(CONFIG_USB_UHCI) += usb-uhci.o
-obj-$(CONFIG_USB_OHCI_HCD) += usb-ohci-hcd.o
+obj-$(CONFIG_USB_OHCI) += usb-ohci.o
obj-$(CONFIG_USB_MOUSE) += usbmouse.o input.o
obj-$(CONFIG_USB_HID) += hid.o input.o
@@ -65,8 +63,9 @@ obj-$(CONFIG_USB_PRINTER) += printer.o
obj-$(CONFIG_USB_SERIAL) += usb-serial.o
obj-$(CONFIG_USB_AUDIO) += audio.o
obj-$(CONFIG_USB_CPIA) += cpia.o
+obj-$(CONFIG_USB_IBMCAM) += ibmcam.o
obj-$(CONFIG_USB_DC2XX) += dc2xx.o
-obj-$(CONFIG_USB_SCSI) += usb-scsi.o
+obj-$(CONFIG_USB_STORAGE) += usb-storage.o
obj-$(CONFIG_USB_USS720) += uss720.o
obj-$(CONFIG_USB_DABUSB) += dabusb.o
obj-$(CONFIG_USB_OV511) += ov511.o
@@ -106,11 +105,5 @@ include $(TOPDIR)/Rules.make
usbcore.o: $(usbcore-objs)
$(LD) -r -o $@ $(usbcore-objs)
-usb-uhci.o: $(usb-uhci-objs)
- $(LD) -r -o $@ $(usb-uhci-objs)
-
-usb-ohci-hcd.o: $(usb-ohci-hcd-objs)
- $(LD) -r -o $@ $(usb-ohci-hcd-objs)
-
-usb-scsi.o: $(usb-scsi-objs)
- $(LD) -r -o $@ $(usb-scsi-objs)
+usb-storage.o: $(usb-storage-objs)
+ $(LD) -r -o $@ $(usb-storage-objs)
diff --git a/drivers/usb/audio.c b/drivers/usb/audio.c
index 8be39a9b3..35181ee90 100644
--- a/drivers/usb/audio.c
+++ b/drivers/usb/audio.c
@@ -3129,10 +3129,12 @@ static void usb_audio_processingunit(struct consmixstate *state, unsigned char *
static void usb_audio_featureunit(struct consmixstate *state, unsigned char *ftr)
{
- struct usb_device *dev = state->s->usbdev;
struct mixerchannel *ch;
unsigned short chftr, mchftr;
+#if 0
+ struct usb_device *dev = state->s->usbdev;
unsigned char data[1];
+#endif
usb_audio_recurseunit(state, ftr[4]);
if (state->nrchannels == 0) {
diff --git a/drivers/usb/bitstream.h b/drivers/usb/bitstream.h
deleted file mode 100644
index 5d272b130..000000000
--- a/drivers/usb/bitstream.h
+++ /dev/null
@@ -1,1508 +0,0 @@
-static unsigned char bitstream[] = {
-0x00,0x09,0x0F,0xF0,0x0F,0xF0,0x0F,0xF0,
-0x0F,0xF0,0x00,0x00,0x01,0x61,0x00,0x0D,
-0x64,0x61,0x62,0x75,0x73,0x62,0x74,0x72,
-0x2E,0x6E,0x63,0x64,0x00,0x62,0x00,0x0B,
-0x73,0x31,0x30,0x78,0x6C,0x76,0x71,0x31,
-0x30,0x30,0x00,0x63,0x00,0x0B,0x31,0x39,
-0x39,0x39,0x2F,0x30,0x39,0x2F,0x32,0x34,
-0x00,0x64,0x00,0x09,0x31,0x30,0x3A,0x34,
-0x32,0x3A,0x34,0x36,0x00,0x65,0x00,0x00,
-0x2E,0xC0,0xFF,0x20,0x17,0x5F,0x9F,0x5B,
-0xFE,0xFB,0xBB,0xB7,0xBB,0xBB,0xFB,0xBF,
-0xAF,0xEF,0xFB,0xDF,0xB7,0xFB,0xFB,0x7F,
-0xBF,0xB7,0xEF,0xF2,0xFF,0xFB,0xFE,0xFF,
-0xFF,0xEF,0xFF,0xFE,0xFF,0xBF,0xFF,0xFF,
-0xFF,0xFF,0xAF,0xFF,0xFA,0xFF,0xFF,0xFF,
-0xC9,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFB,0xFF,0xA3,0xFF,0xFB,
-0xFE,0xFF,0xBF,0xEF,0xE3,0xFE,0xFF,0xBF,
-0xE3,0xFE,0xFF,0xBF,0x6F,0xFB,0xF6,0xFF,
-0xBF,0xFF,0x47,0xFF,0xFF,0x9F,0xEE,0xF9,
-0xFE,0xCF,0x9F,0xEF,0xFB,0xCF,0x9B,0xEE,
-0xF8,0xFE,0xEF,0x8F,0xEE,0xFB,0xFE,0x0B,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xBF,0xFF,0xFF,0xFB,0xFF,0xFF,
-0xBF,0xFF,0xFF,0xFC,0x17,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0x7F,
-0xFF,0xFF,0xFB,0xFF,0xFF,0x7F,0xFF,0xFF,
-0xFC,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0xFF,
-0xFF,0xFD,0xFF,0xFF,0xDB,0xFF,0xFD,0xFF,
-0x77,0xFF,0xFD,0xFF,0xFF,0xDF,0xFE,0xFD,
-0xFF,0xFF,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFD,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,
-0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xE3,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,
-0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0x67,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0x7F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0x2F,0xFF,
-0xF3,0xFD,0xFF,0x7F,0xDE,0xF7,0xFD,0xFF,
-0x7F,0xF7,0x7D,0xFF,0x7F,0xDF,0xF7,0xBD,
-0xFF,0x7F,0xFF,0x1F,0xFF,0xEF,0xFB,0xFE,
-0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xEF,0xFB,
-0xFE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFF,
-0x3F,0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,
-0x9F,0xE7,0xFA,0x7F,0x9F,0xE7,0xF9,0xFE,
-0x7F,0x9F,0xE7,0xFF,0xFC,0x7F,0xBF,0xBF,
-0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xB7,
-0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,
-0xFF,0xE0,0xFD,0xF9,0xFE,0x7F,0x9F,0xE7,
-0xF9,0xFE,0x7F,0x9D,0xF9,0xFE,0x7D,0x9D,
-0xE7,0xF9,0xFE,0x7F,0x9F,0xED,0xED,0xFF,
-0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,
-0xDF,0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,
-0x7F,0xDF,0xFF,0x9B,0xFF,0xEF,0xFB,0xFE,
-0xFB,0xBF,0xEF,0xBB,0xFE,0xFF,0xAF,0xBB,
-0xBE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFF,
-0xB7,0xBF,0xDB,0xF6,0xBD,0xBF,0x6B,0xDB,
-0xF6,0xF9,0xBF,0x5B,0xD6,0xF9,0xBF,0x6F,
-0xDB,0xF6,0xFD,0xBF,0xFF,0x0E,0xFF,0xFF,
-0xFF,0xFF,0x5F,0xFF,0xF7,0xFF,0xFF,0x7F,
-0xF7,0xBD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xDF,0x9F,0xFF,0xFF,0xFF,0xFE,0xFF,
-0xFF,0xEF,0xFE,0xFE,0xFF,0xFF,0x77,0xFF,
-0xFB,0xFB,0xFF,0xFF,0xFF,0xFF,0xF8,0x3F,
-0xFF,0xFD,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xF4,0x7F,0xFF,0xFE,0xFD,
-0xBE,0xFF,0xDF,0xFE,0xFF,0xFF,0xEF,0x7F,
-0xFF,0xCF,0xFF,0xCF,0xFF,0xFF,0xFF,0xDF,
-0xE6,0xFF,0xFF,0x7F,0xDF,0xF7,0xDD,0x7F,
-0x7F,0xDF,0xF7,0xFF,0x7F,0xDF,0xD7,0xFD,
-0xFF,0x7F,0xDF,0xF7,0xFF,0xCD,0xFF,0xF2,
-0xFF,0xFF,0x4F,0x7F,0xF4,0xFF,0xFF,0xFF,
-0xE7,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xBB,0xFF,0xEF,0xFF,0xFE,0xFF,
-0xFF,0xFF,0xEF,0xFF,0xFF,0xEF,0xFF,0xFB,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x65,
-0xEF,0xFF,0xFF,0x7F,0xFF,0xFD,0xEF,0xFF,
-0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFE,0xCF,0xDF,0xFE,0xFF,
-0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xF3,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFE,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBF,0xFF,
-0xFF,0xFF,0xE3,0x7F,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xEF,0xEB,0xFF,0xFE,0xBF,0xFF,
-0xEB,0xFF,0xFC,0x7F,0xFF,0xFF,0xFF,0xEE,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF,
-0xD6,0xFF,0xFD,0xBF,0xFF,0xFB,0xFF,0xFE,
-0xFD,0xFF,0xFF,0xFD,0xEF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xDE,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xBF,0xFF,0xFD,0xFF,0x7F,0xBF,
-0xFF,0x5F,0xDF,0xFF,0xFF,0xBF,0x77,0xFF,
-0xFF,0xFF,0x7F,0xD7,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xDF,0xEF,
-0xFF,0xFF,0xFE,0xFB,0xFF,0xFF,0xDF,0xBF,
-0xFF,0xFF,0xFF,0xFF,0xED,0xFF,0xB7,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xAF,0x7F,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xDF,0xBF,0xDF,0xF3,0xFD,0xFB,0xFF,0x5B,
-0xFD,0xFF,0xBF,0xEF,0xF7,0xFF,0xFF,0x7D,
-0xFF,0xFF,0xFF,0xFF,0xF8,0x3B,0xFF,0xBF,
-0x6F,0xFF,0xFE,0xFF,0xBF,0xFF,0xEB,0x7D,
-0xFF,0xEF,0xFB,0xFE,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xF2,0x7F,0xFC,0xFF,0x3F,0xDF,0xED,
-0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0x5F,0xF7,
-0xB5,0xFF,0xEF,0xFF,0xFF,0xFF,0xE0,0x3F,
-0x9F,0x9E,0xFF,0xFF,0xEF,0xFF,0xDF,0xFF,
-0xBF,0x5F,0xBF,0xCF,0xF3,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0x69,0xAF,0x33,0xFD,0xFF,
-0xFB,0xFF,0xFF,0xFF,0xFF,0xFC,0xFF,0x7F,
-0xD9,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xF5,
-0xA3,0xDF,0x6E,0xDE,0xFF,0xFF,0xBD,0xFF,
-0xFF,0xFE,0xFF,0xFF,0xFF,0xFE,0xE7,0xFD,
-0xFF,0xFF,0xFF,0xF9,0xEF,0xC6,0xFE,0xB7,
-0xAD,0xE5,0xF9,0xFF,0xFF,0xFF,0xCF,0xFF,
-0xFF,0xFF,0xCD,0xFB,0x7F,0xFF,0xFF,0xFF,
-0xF9,0xF6,0x0F,0xDF,0xEC,0xCF,0x7F,0xFF,
-0xFB,0x7F,0xFF,0xFF,0xFF,0xFD,0xFF,0xFE,
-0xF9,0xFD,0x7F,0xFF,0x7F,0xFF,0xF9,0x5B,
-0xFF,0x73,0xDC,0xFD,0x7B,0xDF,0xFF,0xFF,
-0xFF,0x7B,0xFF,0xFF,0xF7,0x53,0xD6,0xFF,
-0xFF,0xFF,0xFF,0xD8,0x9F,0xFE,0xFF,0xEF,
-0x7F,0xEE,0xFF,0xFF,0xFF,0xFB,0xED,0xED,
-0xFD,0xFF,0xFE,0xFF,0xFF,0xFB,0x7F,0xFF,
-0xE2,0x7F,0xFF,0x6F,0xD8,0x57,0xF7,0xFF,
-0xFF,0xFF,0xDF,0xFF,0xE8,0xFF,0xFF,0xFD,
-0xFF,0xFF,0xFC,0x7F,0xFF,0xE4,0xFF,0xFB,
-0xEF,0xFB,0xFE,0xDF,0xB7,0xED,0xFF,0xFE,
-0xDF,0x7F,0xFF,0xFE,0x7F,0xB7,0xFF,0xFF,
-0xFF,0xFF,0x89,0xFF,0xFF,0xCF,0xF3,0xFE,
-0x7F,0xFF,0xEF,0xFF,0xFE,0x7E,0x7F,0xFB,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF1,
-0xFF,0xEB,0x7A,0xD5,0xBF,0x6F,0xDB,0xBE,
-0xFD,0xB7,0xD8,0xF6,0xE5,0xBF,0x6F,0xFB,
-0xFE,0xF5,0xBD,0x7E,0x06,0xFF,0xDF,0xF7,
-0xFB,0xF6,0xFF,0x3F,0xFF,0xDB,0xFF,0xFF,
-0x6F,0xFB,0xF7,0xFF,0xFF,0xFF,0xFB,0xFE,
-0xF7,0xAF,0xFF,0xB7,0xED,0xEF,0xF7,0xFE,
-0xFF,0xFF,0xDF,0xFF,0xFE,0xFF,0xEF,0xFF,
-0xFF,0xFF,0xFF,0xBF,0xF7,0xFC,0x1F,0xEE,
-0xFB,0xFE,0xBD,0xFF,0x7F,0x5F,0xD7,0xFD,
-0xFB,0x43,0xFF,0xFF,0xFD,0xFF,0x5F,0xFF,
-0xF7,0xFF,0xF9,0x3F,0xFF,0xCF,0xF3,0xFD,
-0xF7,0x7E,0xEF,0xA7,0xF9,0xFE,0x8F,0xA7,
-0xE9,0xF3,0x7E,0x9F,0xFB,0xF8,0xFF,0xFF,
-0x3F,0xFD,0x7F,0x5F,0xDF,0xFD,0xFF,0xFF,
-0x5F,0xFF,0xFD,0x5F,0xFF,0xFF,0x7F,0xFD,
-0x7F,0xFD,0x9F,0xFF,0xE0,0xFF,0xFA,0xF8,
-0xBE,0x6F,0x9F,0xE6,0xF8,0xBE,0x3F,0x9A,
-0xF9,0xBE,0x6F,0x9F,0xE2,0xF9,0xFE,0x6F,
-0x9F,0xF9,0xFF,0xF5,0xFD,0x7F,0xCF,0xDF,
-0xFD,0xFD,0x7F,0xFF,0xF5,0xFF,0xFF,0xFF,
-0xF7,0xF5,0xFD,0x0F,0xDB,0xFF,0xD3,0xFF,
-0xEB,0xFA,0xFF,0xFF,0xBF,0xFF,0xFA,0xFF,
-0xFF,0xCB,0xFB,0xFE,0xFF,0xFF,0xEB,0xFA,
-0xFE,0xFF,0xFF,0xB7,0xFF,0xFF,0xFF,0xFF,
-0xBF,0xFF,0xDF,0xF5,0xFF,0xFF,0xD7,0xFF,
-0xFF,0xFF,0xDF,0xD7,0xF5,0xFF,0x7F,0xFE,
-0x4F,0xFF,0xFD,0xFF,0x7F,0x7F,0xFF,0xAD,
-0xEB,0xFB,0xFF,0xAD,0xFF,0xFF,0xFF,0xFF,
-0xAF,0xEB,0xFB,0xFF,0xFC,0x0D,0xFF,0xFF,
-0xDF,0xD2,0xFD,0xFF,0xFF,0xFD,0xF6,0xFF,
-0xFF,0x7F,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,
-0xFF,0xFB,0x3F,0x7D,0xEB,0x32,0xFE,0xBF,
-0x2F,0xEB,0xFA,0xAE,0xBD,0xE0,0xFA,0x7E,
-0xBF,0xAD,0xEB,0xFA,0xFE,0xBF,0xF5,0x7F,
-0xFF,0xDE,0xFE,0xE3,0xFB,0xFF,0xFF,0xFF,
-0xDF,0xEF,0x4F,0xDF,0xFF,0x7F,0xDF,0xFF,
-0xF7,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xEF,
-0xFB,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xDF,
-0xED,0xFB,0xDF,0xFF,0xBF,0xFF,0xFF,0xFF,
-0x81,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,
-0xFF,0xFF,0xFE,0xDD,0xFE,0xEF,0xFD,0xFF,
-0xFF,0xFB,0xFE,0xF7,0xFF,0x93,0xFD,0xFB,
-0x7E,0xFF,0xFE,0x87,0xE9,0xFF,0x7F,0xB3,
-0x9F,0xFE,0xFE,0xFF,0xAF,0xFD,0xFE,0x7E,
-0x3F,0xFE,0x67,0xFF,0xFF,0xF7,0xFF,0xFF,
-0xFC,0xF7,0xDF,0xFD,0xFF,0x7F,0xFF,0xFF,
-0x7F,0x6D,0xFF,0xFF,0xFE,0xFF,0xFF,0x2F,
-0xFF,0xBF,0xFF,0xFF,0xEE,0xFF,0xBE,0xFF,
-0xFF,0xFE,0xFF,0xEF,0xFF,0xFF,0xFE,0xFF,
-0xEF,0xFF,0xFF,0xFA,0x5F,0xFF,0xFF,0xFB,
-0xFF,0xFF,0xEF,0xFF,0xFB,0xFE,0xFD,0xFF,
-0xFE,0xFF,0xFB,0xFF,0xFF,0xFF,0x7F,0xFF,
-0xFE,0xBF,0xDF,0xFF,0xFB,0xFF,0xFF,0xF7,
-0xFC,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xF2,0x7F,0xFF,
-0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,
-0xF3,0xFF,0xFF,0xFF,0xEF,0xFB,0xFF,0xFF,
-0xFF,0xDF,0xE2,0xFF,0xFF,0xFB,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFB,0xE7,0xFF,0xFD,
-0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xED,
-0xEF,0xFD,0xFF,0xFF,0xDF,0xD7,0xF5,0xFD,
-0x7F,0x5D,0xFD,0xFF,0x7F,0xDF,0x97,0xF4,
-0xFD,0x7B,0x5F,0xFF,0xC9,0xFF,0xFB,0xFE,
-0xFF,0xBF,0xFF,0x5F,0xFF,0xFF,0xF7,0xFF,
-0xEF,0xFD,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xF7,0xFF,0xD7,0xFD,0x7D,0x7F,0xFF,
-0xFF,0xFF,0xFF,0xEF,0xDF,0xF7,0xFD,0xFF,
-0xBB,0xFF,0xFF,0x7F,0xFF,0xFE,0xE3,0xFF,
-0xF9,0xFE,0x7F,0xBF,0xEF,0xFB,0xFE,0xFF,
-0xBF,0xF9,0xFE,0xFF,0x9F,0xEF,0xF9,0xFE,
-0xFF,0xBF,0xF3,0xDA,0xFF,0x37,0xCD,0xF3,
-0x7C,0xDF,0x37,0xCD,0xF3,0x7F,0x37,0xCD,
-0xF3,0x7C,0xDF,0x37,0xCC,0xF3,0x7F,0x5A,
-0xBD,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,0xFD,
-0xBF,0x6F,0xDE,0xFD,0xBF,0x6F,0xDB,0xF6,
-0xFD,0xBF,0x6F,0xFE,0xF1,0x6F,0xEB,0x7A,
-0xDE,0xB7,0xAD,0xEB,0x7A,0xDE,0xB7,0xAF,
-0x7A,0xDE,0xB7,0xAD,0xEB,0x7A,0xDE,0xB7,
-0xFF,0x7E,0xFF,0xFE,0xCD,0xB3,0x6C,0xDB,
-0x36,0xCD,0xB3,0x6C,0xDE,0xCD,0xB3,0x6C,
-0xDB,0x36,0xCD,0xB3,0x6C,0xDF,0xC9,0xBF,
-0xF7,0xBD,0xEF,0x7A,0x9E,0xA7,0xA9,0xEA,
-0x7A,0xB7,0xBD,0xEA,0x7B,0xDE,0xA7,0xBD,
-0xCA,0x72,0x8D,0x91,0xFF,0xEF,0xFB,0xFE,
-0xFF,0xBF,0xEF,0xFB,0xFE,0xF7,0xEF,0xFB,
-0xFE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFE,
-0x87,0xFF,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,
-0xFD,0xBF,0x6F,0xF6,0xFD,0xBF,0x6F,0xDB,
-0xF6,0xFD,0xBF,0x6F,0xFE,0x4F,0xFF,0xBF,
-0xEF,0xBB,0xEE,0xFB,0xBE,0xEF,0xBB,0xEF,
-0xBE,0xEF,0xBB,0xEE,0xFB,0xBE,0xEF,0xBB,
-0xEF,0xFC,0x5F,0xFF,0xFF,0xFF,0x3F,0xCF,
-0xF3,0xFC,0xFF,0x3F,0xCF,0xFC,0xFF,0x3F,
-0xCF,0xF3,0xFC,0xFF,0x3F,0xCF,0xFD,0x9F,
-0xFE,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,
-0xEB,0xFE,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,
-0xAF,0xEB,0xFF,0xE1,0x6F,0xFD,0xFF,0x7F,
-0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFD,0xFF,
-0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,
-0x7A,0xBF,0xFB,0xFE,0xDF,0xB7,0xED,0xFB,
-0x7E,0xDF,0xB7,0xFB,0x7E,0xDF,0xB7,0xED,
-0xFB,0x7E,0xDF,0xB7,0xFF,0xC9,0xFF,0xFF,
-0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,
-0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEE,
-0xFB,0xFE,0xBB,0xFF,0xFE,0xFF,0xBF,0xEF,
-0xFB,0xFE,0xFF,0xBF,0xEF,0xFE,0xFF,0xBF,
-0xEF,0xFB,0xFE,0xFF,0x3F,0xCF,0xFF,0xE7,
-0xFE,0xFF,0xF5,0xFD,0x77,0x5D,0xD7,0x35,
-0xDD,0x77,0xD7,0xF5,0xCD,0x7B,0x5D,0xD7,
-0xF5,0xDD,0x77,0xFE,0x27,0xFF,0xFF,0x8B,
-0xE2,0xF8,0xBE,0x2F,0x8B,0xE2,0xF9,0xAF,
-0x8B,0xE2,0xF8,0xBE,0x2F,0x8B,0xE2,0xF9,
-0xFE,0x1F,0xFF,0x5F,0xD7,0xF5,0xFD,0x7F,
-0x5F,0xD7,0xF5,0xFF,0x5F,0xD7,0xF5,0xFD,
-0x7F,0x5F,0xD7,0xF5,0xFF,0xFA,0x3F,0xFE,
-0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,0xEB,
-0xEC,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,
-0xEB,0xFF,0xFE,0x7F,0xFD,0x7F,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,
-0xFF,0xFA,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,
-0xF7,0xFC,0xFF,0xDF,0xF7,0xFD,0xFF,0x7F,
-0xDF,0xF7,0xFD,0xFF,0xF5,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0x02,0xFF,0xFE,0xBF,0xAB,0xEB,0xFA,
-0xBE,0xBF,0x23,0xEB,0xDE,0x1F,0xAF,0xEA,
-0xFA,0xFE,0xAF,0xAF,0xEB,0xFD,0x97,0xFF,
-0xF3,0xFC,0x7B,0x1F,0xCF,0xF1,0xFC,0x7F,
-0x1F,0xF1,0xFC,0x77,0x1F,0xCD,0xF1,0xFC,
-0xFF,0x1F,0xFE,0x87,0xFF,0xAF,0xEF,0xFA,
-0xFE,0xFF,0xAF,0xEF,0xFA,0xFD,0xBF,0x2B,
-0xFB,0x7E,0xBF,0xBF,0xEB,0xFB,0xFB,0xFB,
-0xDF,0xFF,0xFB,0xF7,0xFF,0xFF,0x7F,0xF7,
-0xF7,0xFF,0xFD,0xDF,0xFE,0xFC,0xDF,0xFF,
-0xDF,0xFF,0xFD,0xFF,0xDA,0xBF,0xFF,0xBB,
-0xEF,0xFB,0xF9,0xFF,0xBE,0xEF,0xFB,0xFB,
-0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,
-0xFF,0xF7,0x7F,0xFD,0xD7,0xFF,0xFF,0x7F,
-0xFF,0xFF,0xFF,0xFE,0xF7,0xFF,0xFE,0xFF,
-0xF7,0xFF,0xFF,0x7F,0xFF,0xFF,0xEC,0xFF,
-0xFF,0xFE,0xDF,0xBF,0xFF,0xFB,0xFE,0xFF,
-0xBB,0x68,0xAE,0x1F,0xAE,0xFB,0xFB,0xFF,
-0xFF,0xBF,0xFF,0xD5,0xFF,0x7F,0xFF,0xFF,
-0xF7,0xFE,0xFE,0xFF,0xBF,0xEF,0x9F,0xFD,
-0x7F,0xFF,0xCB,0xFF,0xFF,0xDF,0xFF,0xFF,
-0xBB,0xF7,0xBF,0xFF,0xFF,0xFF,0xFF,0xDF,
-0xFF,0xBF,0xFB,0xFF,0xFF,0xFF,0xDE,0x3F,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xA7,0xFF,0xFF,
-0xFF,0xFF,0xEF,0xFF,0x7F,0xFB,0xFD,0xFB,
-0x7F,0xFF,0xFF,0xFF,0xFF,0xCF,0xF3,0x7C,
-0xFF,0x7F,0x8D,0x7F,0xFF,0xFF,0xFF,0xFF,
-0xFB,0xFF,0xF7,0xFB,0xFE,0xFD,0xFF,0xFF,
-0xFF,0xFF,0xF7,0xFD,0xFF,0x7F,0xFD,0x1F,
-0xFD,0xFF,0xFF,0xFF,0xFF,0xBF,0xDF,0xFF,
-0xFF,0xFE,0x5C,0xFF,0x6D,0xFF,0x7F,0xAB,
-0xE7,0xF1,0xFF,0xFD,0x9F,0xFF,0xFF,0xAD,
-0xEB,0x7A,0x3F,0x1F,0xFF,0xFF,0xFE,0xBF,
-0xAF,0xF3,0xDE,0xF5,0xFF,0x8F,0xFB,0xDF,
-0xE6,0x7F,0xFF,0xDF,0xF3,0xFD,0xFF,0x7E,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xF7,0xF3,
-0x7F,0xDF,0xF7,0xEF,0xFF,0xF6,0x3F,0x9F,
-0xDF,0xFF,0xFF,0xEE,0xFF,0xFF,0xEF,0xFB,
-0xFF,0xFF,0xF9,0xFB,0xFE,0x4F,0xBF,0xEF,
-0xBB,0xFF,0x69,0xAF,0xAF,0xFC,0xFF,0x3F,
-0xDD,0xFF,0xFC,0xBF,0x8F,0xFF,0xFD,0xF3,
-0xBF,0xED,0x9E,0xFC,0xBF,0x6F,0xF5,0xD3,
-0xDF,0xFF,0xDB,0xD6,0xF5,0xEF,0xFD,0xFE,
-0xFF,0xB9,0xFF,0x1F,0xD2,0xA9,0xAF,0xFF,
-0xDB,0xF7,0xBF,0xEF,0x46,0xFF,0xFF,0xAD,
-0xEB,0x7A,0xDF,0xEF,0xF7,0xFF,0x7F,0xF7,
-0x9F,0xED,0xFF,0x7F,0xFF,0xAD,0xEB,0x7F,
-0xF5,0x6F,0xFF,0xFD,0xFB,0xD6,0xF4,0xF7,
-0xFB,0xF9,0x7E,0x7F,0xFF,0x5F,0xC2,0xFE,
-0xBF,0xFD,0xFB,0x33,0xDF,0xF9,0x5B,0xFF,
-0xFF,0xDD,0x67,0x7D,0xCF,0xEF,0xDB,0xEC,
-0xFF,0x77,0xDD,0xF7,0xFD,0xFF,0xFF,0xDE,
-0xA7,0xBF,0xD4,0x9F,0xFF,0xFF,0xBF,0xEF,
-0xFE,0xFF,0xDF,0xEF,0xBB,0xFF,0xFF,0xEF,
-0xEB,0xFA,0xFF,0xEF,0xBD,0xFB,0xFF,0xE2,
-0x7F,0xFF,0xDF,0xDF,0xF7,0xFD,0xBF,0xBB,
-0x73,0xF7,0xFD,0x7F,0xDF,0xDE,0xF7,0xBF,
-0xEA,0xDB,0xF6,0xFF,0xD6,0xFF,0xFF,0x66,
-0xFF,0xBE,0xFF,0xBF,0x6B,0xD9,0xF6,0xDF,
-0xFF,0xFB,0x7E,0x7F,0xB7,0x7E,0xFF,0xFE,
-0xFF,0xCD,0xFF,0xFE,0x7F,0xFF,0xFC,0xFD,
-0x3F,0xFB,0xFB,0xF7,0xFF,0xFF,0xFB,0xF6,
-0x7D,0xFE,0x7F,0xFF,0xFC,0xFF,0xB9,0xFF,
-0xF9,0xFA,0xFE,0xBF,0xAF,0x5B,0xD6,0xED,
-0xAD,0x7B,0xF6,0xF9,0xBF,0xEF,0xF8,0xFA,
-0xFE,0xBF,0xFE,0xE6,0xFF,0xFF,0xF7,0xFD,
-0xFF,0x7F,0xBF,0xEF,0xF3,0xFF,0xFF,0x6F,
-0xF7,0xFE,0xFF,0xFF,0xF7,0xFD,0xFE,0xF7,
-0xEF,0xFF,0xFB,0xEF,0xFB,0x7E,0xDE,0xFE,
-0xFF,0xBF,0xFF,0xFE,0xFF,0xFF,0xFB,0xFF,
-0xFF,0xEF,0xFB,0x6F,0xFC,0x1F,0xFE,0xE7,
-0xFF,0xFF,0xFF,0xEF,0xFF,0xD3,0xB4,0xBB,
-0xFF,0xFF,0xFD,0xBF,0x6F,0xE3,0xFE,0xFF,
-0xBF,0xFC,0xBF,0xF7,0xCF,0xF7,0xFD,0xFF,
-0x2F,0xDF,0xAB,0xEA,0xFF,0xDF,0xE7,0xEA,
-0x9A,0xAF,0xEF,0xFB,0xFE,0xFF,0xF5,0x3F,
-0xFD,0x7E,0xFF,0xD7,0xF5,0xFB,0xFF,0xFD,
-0xF7,0xFF,0x7F,0xFE,0xF7,0xFD,0xFF,0xD7,
-0xFF,0xD7,0x7F,0xEE,0x7F,0xFA,0x79,0xFE,
-0x2F,0x8B,0xE6,0xF9,0xFE,0x3F,0x9E,0xF9,
-0xBE,0x2F,0x0B,0xE7,0xF9,0xFE,0x2F,0x9F,
-0xFD,0xFF,0xFE,0x7D,0x7F,0x5F,0xD7,0xFF,
-0xFF,0x7F,0xFF,0xFD,0xFF,0x7F,0x5F,0x97,
-0xFF,0xFD,0x7F,0x5F,0xFF,0xE3,0xFF,0xFF,
-0xFA,0xFE,0xBF,0xAF,0xFB,0xFB,0xFF,0xFF,
-0xCF,0xEB,0xFE,0xBF,0xAF,0xFF,0xFA,0xFE,
-0xBF,0xFF,0x87,0xFF,0xFF,0xF5,0xFF,0xFF,
-0xFF,0xFF,0xFD,0xFF,0x7F,0xFF,0xFF,0xFF,
-0xFB,0xFF,0xFF,0xF5,0xFF,0xFF,0xFE,0x0F,
-0xFF,0xFD,0xEB,0xFF,0xFF,0xF7,0xFF,0xEF,
-0x7B,0xDF,0xFE,0xFF,0xFF,0xDF,0xF7,0xFD,
-0xEB,0x7F,0xDF,0xFF,0x5F,0xFF,0xFF,0xFF,
-0xFF,0xFD,0xBF,0xFF,0x7E,0xFA,0xBF,0xC7,
-0xDB,0xF7,0xBD,0x3F,0xFB,0xFF,0xF6,0xFF,
-0xFA,0xAF,0xFF,0xEB,0xFA,0xFE,0x3F,0x2F,
-0xEA,0xFA,0x3E,0xAD,0xC9,0xBA,0xF6,0xAD,
-0xAF,0xEB,0xFA,0xF6,0xBF,0xFE,0x7F,0xFF,
-0xFF,0xFD,0xFF,0xF1,0x7F,0x3F,0xCF,0xF1,
-0xEF,0xFF,0x7F,0xFF,0xBC,0xDF,0xDF,0xF7,
-0xDD,0xFF,0xE0,0x7F,0xFF,0xFF,0xFE,0xFF,
-0xFA,0xEC,0xBB,0x7F,0x5F,0xFF,0xFB,0xEC,
-0xFF,0xEF,0xB7,0xFF,0xF7,0xFF,0xFF,0xB5,
-0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xEE,0xDF,
-0x5F,0xDF,0xDE,0xFF,0xAE,0xE7,0x77,0xFF,
-0xFF,0xDF,0xF7,0xFF,0xE3,0xFF,0xFA,0xBB,
-0xFE,0xFF,0xAF,0xFD,0xFB,0xFE,0xBF,0xAB,
-0xF9,0xFE,0xFF,0xBF,0x7F,0xBF,0xFE,0xBD,
-0xFE,0xD7,0xFF,0x9F,0xFD,0xFF,0xBE,0xEF,
-0xFF,0xEE,0xFD,0xBB,0x5B,0xEF,0xFF,0x7F,
-0xEF,0xFF,0xEF,0xFF,0x7F,0xFF,0x4F,0xFF,
-0xEF,0xFB,0xBC,0xFC,0xFF,0xFF,0xFF,0xFE,
-0xFE,0xFD,0xFA,0xFE,0xFB,0xFF,0xFD,0xF3,
-0xFB,0xFF,0xF8,0x5F,0xFF,0xFF,0xD7,0xF5,
-0xFD,0xDF,0xEF,0xFF,0xF3,0xDC,0x5F,0xCE,
-0xF5,0xBD,0xFF,0xFF,0xD7,0xFF,0xFF,0xF9,
-0x3F,0xFF,0xDF,0xF7,0xFF,0xFE,0xFF,0xFD,
-0xFF,0xFB,0xFF,0xF7,0xB9,0x7D,0xFE,0xDF,
-0xFF,0xFF,0xFF,0xFF,0xF9,0x7F,0xFF,0xFE,
-0xFF,0xFF,0x7F,0xFF,0xFE,0xFF,0xFF,0xF7,
-0xF6,0xFF,0xBF,0xF1,0xF8,0xFF,0xFF,0xFF,
-0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xEF,0xEF,0xFF,0xFF,
-0x9B,0xFB,0x7F,0xFF,0xFF,0xFF,0xC1,0xFF,
-0xDF,0xFF,0x3F,0x5F,0xD7,0xBF,0xEF,0xBB,
-0xDE,0xEE,0xFF,0x7F,0xDF,0xFF,0xFE,0xF5,
-0x7F,0xDF,0xFF,0x99,0xFF,0xFF,0xFA,0xFF,
-0xBF,0xFD,0xEB,0x7A,0xFF,0xB7,0xFE,0xFE,
-0xFF,0xFF,0xEF,0xFF,0xFF,0xFD,0xBF,0xFF,
-0x97,0xFF,0xFD,0xF7,0xFF,0x7F,0xF7,0xFF,
-0xFF,0xFD,0x5F,0xFE,0xF3,0xF9,0xDF,0xDF,
-0xFF,0xFF,0xFC,0xFF,0xFF,0x83,0xFF,0xFF,
-0xFE,0xFF,0x9E,0xEC,0xFB,0xEE,0xFF,0x9F,
-0xBF,0xEF,0xFF,0xFE,0xED,0x7B,0xFF,0xFF,
-0xFF,0xF1,0x5A,0xFF,0xFF,0xFD,0xFF,0x7C,
-0x69,0x3B,0xDF,0xFF,0x7F,0x1F,0xDF,0xFF,
-0xFD,0xBA,0xFF,0xFF,0xFB,0xFF,0x5B,0xBD,
-0xFF,0xFF,0xFF,0xFF,0xD7,0xB6,0xED,0xE9,
-0xFF,0xD6,0xBD,0x6F,0x5F,0xFB,0xFF,0xEF,
-0xFF,0x5F,0xFE,0xF6,0x6F,0xFF,0xFF,0xFF,
-0xFF,0xF7,0xEB,0x7A,0xDF,0xFF,0x9F,0x7F,
-0x7F,0xFF,0xB7,0xFF,0xFF,0xFE,0xDF,0xFF,
-0x6C,0xFF,0xFB,0xFF,0xBB,0x6F,0xEB,0xFE,
-0xCC,0xF7,0xA5,0xFA,0x5C,0xF5,0x75,0xBB,
-0xB7,0xDF,0xFE,0x6F,0x5F,0xC5,0xBF,0xFD,
-0x7B,0xFE,0xFF,0x95,0xE7,0x29,0xCF,0x4F,
-0xF5,0x91,0xEE,0x6B,0xDF,0xEF,0xFD,0x54,
-0xF5,0xBD,0xB1,0xFF,0xEF,0xEE,0xFB,0xBE,
-0xBF,0xAF,0xFE,0xDE,0xBD,0x6F,0xDA,0xF2,
-0xFF,0xAF,0xBE,0xFF,0xFF,0xFD,0x7E,0xA7,
-0xFF,0xF7,0xFF,0xBF,0xEF,0x7B,0xF6,0xFD,
-0xBD,0x4A,0xF2,0x85,0x85,0xBF,0x5B,0xFE,
-0xB5,0xFD,0xFA,0xFF,0x4F,0xFF,0xFE,0xDF,
-0xFF,0xED,0xFF,0xBF,0xFF,0xBF,0x7F,0xFE,
-0xFF,0xB7,0x6D,0xFF,0xF7,0xBF,0xBF,0xEF,
-0xFD,0x1F,0xFF,0xFE,0x7D,0xFF,0x67,0xFF,
-0xFF,0xFF,0x3F,0x7F,0xFE,0xBF,0xFF,0xE7,
-0xDF,0xE7,0xFF,0xEF,0x6B,0xFC,0x1F,0xFF,
-0xBF,0xEF,0xFB,0xFE,0xDE,0xBF,0xAF,0xFA,
-0xFF,0xB6,0xEF,0xF9,0xFE,0xFF,0x8F,0xEF,
-0xDB,0xEF,0xAB,0x6F,0xFB,0xFE,0xFF,0xFF,
-0xEF,0xFD,0xFF,0x7F,0xFF,0xFF,0xDE,0xFF,
-0xFF,0xEF,0xFF,0xFF,0xFF,0x3F,0xFF,0x6C,
-0xFF,0xBF,0xFB,0xFF,0xFE,0xFF,0xFB,0xFE,
-0xDF,0xFF,0xFF,0xEF,0xFF,0xFF,0xBF,0xFF,
-0xFF,0xFE,0xFB,0xFF,0xD5,0x7F,0xFF,0xFF,
-0xEF,0xFB,0xFF,0xFF,0xBF,0xEF,0x43,0xB5,
-0xFD,0x6F,0xCF,0xD6,0xBE,0x3F,0x7F,0xDB,
-0xFE,0xC3,0xFF,0xFD,0xFF,0xAF,0xEB,0xFB,
-0xFC,0xFF,0x3E,0xEF,0xE8,0xFA,0xBD,0xCD,
-0xAA,0xFE,0xFE,0x7D,0xCF,0xFF,0xB7,0xFF,
-0xF7,0xFF,0xFF,0xFF,0xFD,0xFF,0x75,0xCD,
-0x52,0xD7,0xFD,0xFB,0xF7,0xDD,0xFB,0xEF,
-0xEB,0xFF,0xFF,0x4F,0xFF,0xBF,0x9F,0xE7,
-0xF9,0xFC,0x7F,0x8B,0xC3,0xF9,0xAF,0x8F,
-0xE7,0xE9,0xBE,0x7F,0x9F,0xE6,0xF9,0xFC,
-0x5F,0xFF,0xFF,0xF7,0xFD,0xFF,0x7A,0x5F,
-0xD7,0xED,0xFF,0xFF,0xD7,0xFF,0xDD,0x7F,
-0xE7,0xFF,0xFC,0xFF,0xFC,0x3F,0xFF,0xFF,
-0xFF,0xFB,0xFF,0xFE,0xBF,0xAF,0xFF,0xFD,
-0xFF,0xEF,0xFF,0xEB,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xF7,0x7F,0xFF,0x7F,0xDF,0xFF,0xFD,
-0xFD,0x7F,0xFE,0xF7,0xFD,0x7F,0xDF,0xFF,
-0xFD,0xFF,0xFF,0xDF,0xFB,0xFF,0xEE,0xFF,
-0xFB,0xFF,0xF7,0xFD,0xFF,0x7A,0xDF,0xF5,
-0xFD,0xFA,0xDF,0xF7,0xFC,0xFF,0x7F,0xDF,
-0xBF,0xED,0xFF,0xC9,0xFF,0xDF,0xFF,0xBF,
-0x2F,0xFB,0xFF,0xBC,0xAD,0xFF,0xF7,0xFF,
-0xFF,0xEF,0xD3,0xFF,0x7D,0xBF,0x6F,0xFF,
-0xFA,0xFF,0xFE,0xBF,0xAE,0xEA,0xFA,0xBE,
-0xAD,0xA5,0xEB,0xCE,0xBF,0xA7,0xEB,0x5A,
-0xDE,0xBD,0xAF,0x6B,0xFD,0x57,0xFF,0xFF,
-0xF4,0x7F,0x1F,0x7F,0xFD,0xFF,0x7F,0x36,
-0xF0,0xDF,0x79,0xFF,0xFF,0xFF,0xF7,0xFD,
-0xBF,0xFF,0x87,0xFF,0xFB,0xF3,0xFC,0xFF,
-0xFF,0xFF,0xFF,0x7E,0xFF,0xBF,0xDF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,0xF8,0x9F,
-0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFD,
-0xF7,0xFC,0xBD,0xFF,0xFE,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFB,0xF9,0xBF,0xFF,0xFF,0xEB,
-0xE2,0xFE,0xFF,0xBF,0xEF,0xA9,0xBA,0x2F,
-0xEB,0xF9,0xFE,0x77,0xDF,0xF7,0xFF,0xFF,
-0xF9,0x7F,0xFF,0xFF,0x7F,0xEF,0xD7,0xFF,
-0xFD,0xFF,0xFB,0xF5,0xFF,0xBF,0x6F,0xDF,
-0xFF,0xFF,0xFD,0xFF,0xFF,0xF0,0xFF,0xFF,
-0xFF,0x3F,0xCF,0xFF,0xBA,0xEE,0x9B,0xBF,
-0xEE,0xD7,0xFE,0xCD,0xEF,0xFF,0xDF,0xBF,
-0xFF,0xFF,0xC5,0xFF,0xFF,0xFD,0x7F,0x4F,
-0xFD,0xF6,0xD9,0xFF,0x4F,0xD6,0xFD,0xBF,
-0x6E,0xFF,0xFF,0xF4,0x7F,0xFF,0x7F,0x8B,
-0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xF9,0xFE,
-0x37,0xFF,0xD9,0xFB,0xF5,0xAF,0xFD,0xFF,
-0xFF,0xFB,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,
-0xFB,0xF7,0xFF,0xFD,0xFF,0x7C,0xFA,0x7E,
-0x4F,0xFC,0xDF,0x1D,0xC7,0xFF,0xFF,0xFF,
-0xFF,0xAE,0xFF,0xFF,0xFF,0xFF,0xFD,0xFB,
-0xFF,0xFF,0xFE,0xFE,0xFC,0xFF,0x7F,0x7F,
-0xBF,0xEF,0xFE,0xFF,0xFF,0xFF,0x5F,0xFD,
-0xFF,0xFF,0xFF,0xFD,0x6F,0x5A,0xD7,0x7B,
-0xBE,0x5F,0xFE,0x39,0xFF,0xF7,0xFF,0xF7,
-0xFD,0xFE,0xAA,0x1F,0xFF,0xFF,0xFF,0xFF,
-0xFE,0xFE,0xAB,0xAF,0xFD,0xFE,0xBF,0xFF,
-0xF7,0xFF,0x7F,0xFE,0x8F,0xE3,0xFB,0xEE,
-0x7F,0xFF,0xFF,0xFF,0xFF,0xEB,0xFB,0xFF,
-0xFD,0xBF,0xEF,0xDF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFB,0xE4,0x3F,0xFF,0xDF,
-0xFF,0xFF,0xFF,0xFF,0xF3,0xEF,0xBB,0xFB,
-0xBF,0xEF,0xBB,0xFF,0xD7,0xBF,0xFF,0xFF,
-0xFF,0x29,0xAF,0xF7,0xFF,0xFF,0xFB,0xFF,
-0xFB,0xE6,0xFF,0x0F,0xFB,0x3F,0xDF,0x0F,
-0xFF,0xAF,0xFF,0xFF,0xFF,0xF5,0xC3,0xDF,
-0x5F,0xFF,0xFF,0xFF,0xFE,0x6B,0xCA,0xBE,
-0xBC,0xFF,0x9F,0xF2,0xBF,0xFF,0xFE,0xFA,
-0xFF,0xFF,0xEF,0x16,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFC,0xDF,0x97,0xFD,0x79,0xFF,0x37,
-0xE7,0x7F,0xFF,0xFF,0xB5,0xFF,0xFF,0xF6,
-0x2F,0xFF,0xFD,0xFB,0xFE,0xFF,0xFF,0xFD,
-0x5F,0x57,0x5F,0xFF,0xDB,0x52,0xDF,0xFF,
-0xFD,0xBF,0xFF,0xFF,0xFC,0xDB,0xFF,0x7B,
-0xB5,0xFD,0x7F,0xFF,0x71,0x9C,0x6E,0xFF,
-0xF6,0x35,0xA5,0x9B,0xFF,0xFF,0xFD,0xFF,
-0xFF,0xDB,0x9E,0x7F,0xFE,0xEF,0xFB,0xFF,
-0xFF,0xBD,0xEF,0xFF,0xDE,0xB7,0xF9,0x4B,
-0xFF,0xF5,0xEF,0xFF,0xFF,0xFF,0xE8,0x7E,
-0xFF,0xEA,0xDF,0xF7,0xFF,0xFD,0x69,0x5B,
-0xFC,0x9F,0xEF,0x78,0xD6,0xFF,0xEB,0xEF,
-0xFF,0xFF,0xFF,0xE8,0xFF,0xFF,0xED,0xFF,
-0xFF,0xFF,0xFF,0xE3,0xF9,0xF6,0xBF,0xFF,
-0xFF,0xFE,0xDF,0xFF,0x7F,0xFF,0xFF,0xFF,
-0xD1,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF,
-0xE7,0xF9,0xFF,0xBF,0x7F,0xD9,0xFF,0xFD,
-0xFE,0x7F,0xFF,0xFE,0xFF,0xF9,0xFF,0xFB,
-0xD6,0xDF,0xBF,0xEF,0x5B,0xD6,0xFF,0xBF,
-0xFB,0xF6,0xFF,0xBF,0xEF,0xF8,0xF6,0xDD,
-0xBE,0xFE,0x16,0xFF,0xBF,0xEF,0xFF,0xFE,
-0xFF,0xBF,0xEF,0xFF,0xFF,0xFF,0x6F,0xFB,
-0xFF,0xFF,0xFF,0x6F,0xF3,0xFF,0xF7,0xEF,
-0xFB,0xFF,0xBF,0xFF,0xEF,0xFE,0xFF,0xBF,
-0xFF,0xFF,0xFF,0xBE,0xBF,0xFF,0xEF,0xFF,
-0x7F,0xEF,0xFF,0xFD,0x17,0xFB,0x7B,0xFF,
-0xFF,0xFD,0x7F,0xDB,0xF6,0xF4,0x7F,0xFA,
-0xFE,0xF5,0xBF,0xEB,0xE3,0xF7,0xFF,0xFF,
-0xE9,0xBF,0xFF,0xAF,0xF7,0xFD,0xF3,0x7E,
-0x8F,0xA3,0xEA,0xFF,0xCB,0xF3,0xEE,0xFF,
-0xBF,0xEF,0xF7,0xF9,0xFF,0xFE,0x7F,0xFF,
-0xFF,0xFF,0xFF,0xF5,0xFB,0xF6,0xFF,0xF5,
-0x2F,0xFE,0xFB,0xD7,0xBF,0xFF,0xBE,0xDF,
-0x9F,0xFF,0xF0,0xFF,0xFF,0xF9,0xFE,0x7F,
-0x8F,0xA3,0xF8,0xFE,0x6F,0x9F,0xF9,0xF6,
-0x2F,0x9F,0xE7,0xF9,0xFE,0x2F,0x9F,0xE1,
-0xFF,0xFF,0xFF,0x7F,0xDF,0xF7,0xF5,0xFD,
-0x7F,0x7F,0xF5,0xFF,0x9F,0x5F,0xFB,0xFE,
-0xFF,0x7F,0xFF,0xFF,0xCB,0xFF,0xFF,0xFB,
-0xFE,0xFF,0xBF,0xAF,0xFB,0xFE,0xFF,0xDF,
-0xFE,0xFE,0xBF,0xF7,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xC7,0xFF,0xFF,0xFD,0xFF,0x7F,0xDD,
-0xF7,0xFD,0xFF,0xFF,0xD7,0xFF,0xFD,0x7F,
-0xFF,0xFB,0xFD,0xFF,0xFF,0xFE,0xEF,0x7F,
-0xFD,0xEF,0xFB,0xFE,0xFB,0xFD,0xFF,0x7F,
-0xDF,0xFD,0xFF,0x7A,0xDF,0xF7,0xFD,0xFF,
-0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xD3,0xF7,
-0xFF,0xFF,0x6F,0xDB,0xFF,0xFF,0xEF,0xCB,
-0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
-0x29,0xFF,0xE8,0xDA,0x76,0x9F,0xAF,0x6A,
-0xDA,0xFE,0x35,0xEB,0xDA,0xD6,0xBF,0xAB,
-0xEB,0x7A,0xDE,0xBF,0xD7,0x7F,0xFF,0xFE,
-0xFF,0xBF,0xEF,0xFD,0xDF,0x77,0xBF,0xFD,
-0x37,0xEF,0xFF,0xEF,0xFF,0x3F,0xFF,0xFF,
-0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xF7,0x7E,
-0xDF,0xFF,0xFF,0xFF,0xFA,0xB7,0x7F,0xFF,
-0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x89,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0x9F,0xFB,0xFF,0xFF,0xFF,0xE7,0xFF,
-0xFF,0xFF,0xFF,0xAA,0xFF,0xAB,0xFB,0xFA,
-0xEF,0xBF,0xFF,0xDF,0xFA,0x7B,0xB9,0xFE,
-0xFE,0xFF,0xFD,0xFF,0xF7,0xFE,0x3F,0xFF,
-0xB7,0xFF,0xF7,0xEE,0xFF,0x7F,0xEF,0xFF,
-0xFF,0x7F,0xFF,0x1F,0xFB,0xFF,0xBF,0xFB,
-0xFE,0xFF,0xBD,0xFF,0xFF,0x2F,0xFF,0xBF,
-0xFF,0x7F,0xDF,0xFA,0xFF,0xFF,0xFC,0xEE,
-0xF5,0xF3,0xBE,0xFB,0x0F,0xEF,0xF3,0xBE,
-0xEF,0xFC,0x5F,0xFF,0x5A,0xFF,0xF7,0xDF,
-0xFF,0xFF,0xFE,0xD5,0xFC,0x5F,0xFB,0xF2,
-0xFF,0xFF,0x2F,0xBB,0xF3,0xFF,0xFF,0xBF,
-0xFF,0xEF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,
-0xBF,0xFF,0xFF,0xFD,0x7B,0xFF,0xDF,0xB9,
-0xFF,0xFB,0xFF,0xD8,0x7F,0xFF,0xFF,0xFF,
-0xFB,0xFF,0xFC,0x7F,0x1F,0xBF,0xE0,0xDF,
-0xF7,0xEF,0xFF,0xFD,0x7F,0xFE,0xDF,0xFF,
-0xE0,0xFF,0xFF,0xFD,0xEF,0xFB,0xFF,0xFE,
-0xF7,0xDF,0xFF,0xEB,0x5F,0xFF,0xF7,0xFF,
-0xFF,0xFF,0xFF,0xBF,0xFF,0xFD,0xFF,0xFD,
-0xFF,0xFF,0xFF,0xF7,0xFD,0xFF,0x3B,0xDC,
-0xFD,0x6D,0x7B,0x5F,0x57,0xF5,0xFD,0x7F,
-0x5F,0xFF,0xB1,0xFF,0xEB,0xFF,0xFF,0xFF,
-0xFB,0xFB,0xFE,0xFF,0xBF,0xFB,0xBE,0xFF,
-0xBF,0xEF,0xFB,0xFE,0xFF,0xAF,0xFE,0xF7,
-0xDF,0xDF,0xFF,0xFF,0xFF,0x7F,0xCF,0xF3,
-0xF8,0xFF,0xD7,0xFB,0xFF,0x5F,0xBF,0xF7,
-0xFB,0xFF,0x7F,0xFE,0x23,0xFF,0xFF,0xFE,
-0x7F,0xF3,0xFF,0xFB,0xFE,0xFF,0xFF,0xF3,
-0xFF,0xFF,0xF5,0xF9,0xFF,0x3F,0xFF,0xFF,
-0xF0,0x9A,0xFF,0xBE,0x7F,0xFF,0xFC,0xF9,
-0xFF,0xFD,0xAF,0xEB,0xFE,0xBF,0xFF,0xCF,
-0xF3,0xFE,0x7F,0xFF,0xFF,0x5B,0xBD,0xFF,
-0xBC,0xEB,0xFF,0xD7,0xD4,0xAF,0xAF,0xFD,
-0xFF,0xCF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7,
-0xFD,0xFE,0xFF,0x6F,0xFF,0xFB,0xFF,0xFF,
-0xFF,0xFD,0x7F,0x5E,0xFD,0xBF,0xDB,0xF6,
-0xFD,0xBF,0x6F,0xFB,0xEE,0xFD,0xFF,0x7A,
-0xFF,0xFA,0xFB,0xFF,0x3F,0xFB,0xB7,0x5F,
-0xD6,0xF7,0x1F,0x71,0xDC,0x77,0x1D,0xC7,
-0x31,0xDC,0x77,0xDF,0xF9,0xBF,0xF5,0x5B,
-0xF4,0xD7,0x9D,0xAE,0xFF,0xBF,0xFD,0xBF,
-0xDB,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,0xFE,
-0x3D,0x81,0xFF,0xEB,0xFE,0xFE,0xFE,0xFF,
-0xEB,0x7A,0xDF,0x7D,0x77,0x7D,0xF5,0x79,
-0xDF,0x57,0xDD,0xF5,0x7D,0x7E,0xE6,0xFF,
-0xD6,0x3F,0xBF,0x7F,0xFF,0xD4,0xF5,0x3F,
-0xBF,0xFB,0xBE,0xEF,0xB3,0xEE,0xFB,0x9E,
-0xEF,0xBB,0xFE,0x8B,0xFF,0xFE,0xDF,0xB7,
-0xED,0xFF,0xF7,0xFD,0xFE,0xFF,0xEF,0xBB,
-0xEE,0xFF,0xBE,0xEF,0xBB,0xEE,0xEB,0xFC,
-0x1F,0xFF,0xFF,0xFD,0xFF,0xE7,0xFF,0xF7,
-0xFD,0xFF,0xEF,0xFE,0xFF,0xBF,0xEF,0xFB,
-0xFE,0xFF,0xBF,0xEB,0xFA,0x1F,0xFF,0xB7,
-0xEF,0x5B,0xFE,0xFF,0xAF,0xEB,0xDD,0xE7,
-0xDE,0x77,0x9D,0xE7,0x79,0xDE,0x77,0x9D,
-0xBF,0xE6,0x6F,0xFF,0xFE,0xFF,0xBF,0xEF,
-0xFB,0xFE,0xFD,0xBF,0x6F,0xF6,0xFD,0xBF,
-0x6F,0xDB,0xF6,0xFD,0xBF,0xFF,0x7E,0xFF,
-0xFF,0xFB,0xFE,0xFE,0xFF,0xEF,0xFB,0xFD,
-0xEF,0x7E,0xF7,0xBD,0xEF,0x7B,0xDE,0xF7,
-0xBD,0xEF,0xFF,0xD5,0xFF,0xBF,0xFF,0xEF,
-0xFE,0xFF,0xFC,0x3F,0x0F,0xE7,0xFE,0x7F,
-0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,0xFE,
-0xF3,0xFF,0xFE,0xDF,0xAD,0xDF,0x67,0xEE,
-0xFB,0xBF,0xEF,0xFE,0xFF,0xBF,0xEF,0xFB,
-0xFE,0xFF,0xBF,0xEF,0xFF,0x23,0xFF,0xFF,
-0xFF,0xFF,0x7F,0xFF,0xF3,0xBC,0xDB,0xFE,
-0xFB,0xFF,0xFB,0xBE,0xF7,0xFB,0xFF,0x7F,
-0xDF,0xFF,0xCF,0xFB,0xFF,0x9F,0xE3,0xF9,
-0xBE,0x3F,0x8F,0xE7,0x79,0xFF,0x9D,0xE7,
-0xF9,0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x5F,
-0xFF,0xCF,0xF7,0xFF,0xFF,0xFF,0xDF,0xF7,
-0xFE,0x7F,0xE7,0xF9,0xFE,0x7F,0xFF,0xFF,
-0xFB,0xFE,0xFF,0xFF,0xBF,0xFF,0xBF,0xBF,
-0xFF,0xFE,0xFF,0xBF,0xEF,0xFF,0xFD,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFD,0xFF,
-0xFF,0x3F,0xFF,0xBF,0xFF,0xF7,0xFF,0xFF,
-0x7F,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xE8,0xEF,0xFF,
-0x5F,0xF7,0xBF,0xF9,0xFE,0xDF,0xB7,0xFD,
-0xFF,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7,
-0xFD,0xFF,0xDD,0xFF,0xF2,0xFF,0xBF,0xFF,
-0xFF,0xBF,0xFF,0xFF,0x2F,0xF2,0xFF,0xBF,
-0x2F,0x7B,0xD2,0xF7,0xBF,0x2F,0xFF,0xBB,
-0xFF,0xEE,0x8F,0xAF,0xEB,0xFA,0xFE,0x3F,
-0xA7,0x69,0xCE,0x8F,0xA4,0xEA,0xFA,0xEE,
-0xB7,0xAE,0xEB,0xFD,0xC7,0xFF,0xF7,0xF7,
-0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3E,0xF3,
-0x74,0xFF,0x3F,0x4F,0xFF,0xE7,0xFF,0x3F,
-0xFE,0xA7,0xFF,0xFF,0xDF,0xF7,0xB7,0xFF,
-0xF7,0xFF,0xBA,0xEF,0x37,0xEB,0xFB,0xFE,
-0xBF,0xFB,0xFE,0xF3,0xFF,0xF9,0xDF,0xFF,
-0xBF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,
-0xFD,0xDF,0xFF,0xFD,0xFF,0xFF,0xFB,0xFE,
-0xFD,0xFF,0xFB,0xBF,0xFE,0x3F,0xED,0xFF,
-0xDF,0xBE,0x3D,0xA7,0xFB,0xFA,0x3F,0xE6,
-0xE1,0xFE,0xFE,0x3F,0xEF,0xE3,0xDF,0xF5,
-0x7F,0xFE,0xFF,0x7E,0xFF,0xFF,0xFF,0xFF,
-0xEF,0x6F,0xF6,0xFF,0x7D,0xEF,0xD7,0xDE,
-0xFF,0x7D,0xEF,0xFF,0xF2,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0x7B,0xDE,0xFB,0xE6,0xEE,
-0xEF,0x37,0x6E,0xF3,0x7E,0xEB,0x37,0xEF,
-0xFF,0xC1,0xFF,0xFE,0xFF,0xF7,0xEF,0xFF,
-0xFF,0xFF,0xBF,0x3F,0xD2,0xDF,0xBF,0x2F,
-0x7B,0xE2,0xFF,0xFE,0x3B,0xBD,0xDB,0xFF,
-0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFE,
-0xFF,0xFB,0xFF,0xFF,0xBF,0xFF,0xFB,0xDF,
-0xFF,0xBF,0xFF,0xB7,0xFF,0xFF,0xBF,0xEF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,
-0x7F,0xFF,0x1F,0xEF,0xF1,0xFD,0xFF,0xF6,
-0xAF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,
-0xFF,0xFF,0xFE,0x9F,0xFF,0xFF,0xFF,0x77,
-0xEF,0xF7,0xFB,0xFF,0xFE,0x5F,0xFF,0xFF,
-0xBF,0xCF,0xFB,0xF7,0xDD,0xF7,0xF5,0xFF,
-0x5F,0xD5,0xF5,0xFD,0x7F,0x5F,0xD7,0xF5,
-0xFF,0xFB,0x0F,0xFF,0xFF,0xA9,0xEA,0x7A,
-0xFF,0xAF,0x8F,0xFE,0xDF,0xAF,0xEF,0xFB,
-0xFE,0xFF,0xBF,0xEF,0xFB,0xDF,0xE5,0x5F,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xBD,0x57,0xFF,
-0xFF,0x6F,0x77,0xBF,0xF7,0xFB,0xFF,0x7F,
-0xBF,0xF7,0xFF,0xFC,0xBF,0xFF,0x9F,0xFF,
-0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xFF,0x1F,
-0xCF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFF,0xFB,
-0x65,0xAF,0xF3,0x7C,0xFF,0x3F,0xDF,0xFF,
-0xFD,0xE9,0xFE,0x7F,0xE7,0xFF,0xFE,0x7F,
-0xFF,0xFF,0xFF,0xFF,0xFD,0xE3,0xDF,0xFB,
-0xDB,0xF6,0xFD,0xEF,0x5B,0xFB,0xFF,0xDF,
-0xFC,0xFF,0x3F,0xDF,0xF3,0xFD,0xFF,0x7F,
-0xDF,0xEF,0x66,0xFF,0xDF,0xAD,0xEB,0x7A,
-0xDE,0xF7,0xF7,0xE7,0xD9,0xFD,0x9F,0x67,
-0xD9,0xF6,0x7D,0x9F,0xE7,0xDF,0xF5,0x47,
-0xFD,0x65,0x5B,0xD6,0xF4,0xFE,0xFF,0xEF,
-0xFF,0x6D,0xF6,0xDD,0xB7,0x6D,0xDB,0x76,
-0xDC,0xB7,0x7D,0xFA,0x9B,0xF6,0x6D,0x9D,
-0x67,0x59,0xDF,0xF7,0xDD,0xFF,0xEB,0xFE,
-0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,0xE3,
-0xD1,0x9F,0xFF,0xBD,0xBF,0xEF,0xFE,0xF7,
-0xBF,0xBF,0xF7,0xD7,0x7F,0xDD,0xF7,0x9D,
-0xDF,0x7F,0xDF,0xF7,0xFF,0xE0,0x7F,0xFD,
-0xC1,0xDF,0xF7,0xFD,0xC7,0x7F,0x7F,0xFB,
-0xFF,0xBB,0xEC,0xFB,0x3E,0xFF,0xBF,0xEC,
-0xFB,0xFF,0xD8,0x7F,0xBF,0x6C,0xFF,0xBE,
-0xFF,0xBF,0xED,0xFF,0xEF,0xFE,0xFB,0xBF,
-0xEF,0xFB,0xFE,0xFF,0xBF,0xEE,0xFF,0xC5,
-0xFF,0xAF,0x6F,0xFF,0xFC,0xFD,0x3F,0xE7,
-0xFF,0xFE,0xFF,0xEF,0xFB,0xFE,0xFF,0xBF,
-0xEF,0xFB,0xFE,0xBF,0x89,0xFE,0xFA,0xBA,
-0xFE,0xBF,0xAF,0xFB,0xF6,0xF5,0xD9,0x7D,
-0x97,0x65,0xD9,0x74,0x5D,0x97,0x65,0xD3,
-0xFE,0xD6,0xFF,0xBF,0xF7,0xFD,0xFF,0x7F,
-0xBF,0xCF,0xFB,0xFE,0xFF,0xEF,0xFB,0xFE,
-0xFF,0xBF,0xEF,0xFB,0xFF,0xF6,0x8F,0xFB,
-0xFF,0xEF,0xFB,0x7E,0xDB,0xFE,0xFF,0xBE,
-0xEF,0xEE,0xFB,0xBE,0xEF,0xBB,0xEE,0xFB,
-0xBE,0xFF,0xFF,0xDF,0xFF,0x43,0xFF,0xFF,
-0xFB,0xEF,0x5F,0xB7,0xFE,0x7F,0xE7,0xF9,
-0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0xF9,
-0xBF,0xFE,0xAF,0x77,0xFD,0xFF,0x2F,0xAF,
-0xA7,0xFE,0xFF,0xEF,0xFB,0xFE,0xFF,0xBF,
-0xEF,0xFB,0xFE,0xFF,0xF1,0x7F,0xEF,0xDF,
-0xFF,0x97,0xF5,0xEF,0xFF,0xDF,0xFF,0xFF,
-0xBF,0xFF,0xBF,0xFF,0xFF,0xFE,0xFF,0xFF,
-0xFF,0xE0,0xFF,0xFF,0xF9,0xFE,0x2F,0x8B,
-0xE3,0xF8,0xBE,0x77,0x9F,0xF9,0xDA,0x77,
-0x9D,0xE7,0x79,0xDE,0x77,0x9F,0xDD,0xFF,
-0xFD,0xFD,0x7F,0x5F,0xD7,0xFD,0xFF,0x7F,
-0xE7,0xFE,0x7F,0x97,0xE7,0xFB,0xFE,0xFF,
-0xBF,0xEF,0xFF,0xAB,0xFF,0xEF,0xFA,0xFE,
-0xBF,0xAF,0xFF,0xFA,0xFF,0xFF,0xDF,0xFF,
-0xFB,0xFF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,
-0x67,0xFF,0xF7,0xF5,0xFF,0xFF,0xFF,0xDF,
-0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xBD,
-0xEB,0xFF,0xFF,0xF7,0xAD,0xEB,0xFF,0xDF,
-0xFD,0xFF,0x3F,0xDF,0xF7,0xFD,0xFF,0x7F,
-0xDF,0xFF,0x5F,0xFF,0xF7,0xFF,0xFF,0xFD,
-0xBF,0xFF,0xCB,0xF4,0xFF,0x7F,0xD3,0xF7,
-0xFD,0x3F,0x7F,0xD3,0xF7,0xFF,0xFC,0x3F,
-0xFF,0xEA,0xFA,0xBE,0xAF,0xAB,0xEB,0xBA,
-0xF4,0x95,0x6B,0x52,0xD4,0xAD,0x2F,0x4A,
-0xD2,0xF6,0xBF,0xD2,0x7F,0xF7,0x3F,0xFF,
-0xFF,0xF3,0x7F,0xFF,0xFF,0xF7,0xFF,0xBA,
-0xDF,0xFB,0xFD,0xFF,0xBF,0xFF,0xFB,0xFF,
-0xF8,0x7F,0xEA,0xFF,0xFE,0xFE,0xDF,0xFF,
-0xF7,0xFF,0x7F,0xBB,0xFF,0xFF,0xBF,0xDF,
-0xFB,0xFF,0xFF,0xBF,0xFF,0xB1,0x7F,0xFF,
-0xFB,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,
-0xCF,0xFE,0xFF,0xFF,0xEF,0xFF,0xF7,0xFF,
-0xFF,0xFF,0xF1,0xFF,0x69,0xBE,0xFA,0xBF,
-0xAF,0xE2,0xFF,0xFE,0xFD,0xAF,0xF3,0xFE,
-0xFF,0xBF,0xEF,0xFB,0xFC,0xFF,0xFF,0x07,
-0xFD,0x95,0xDB,0xDF,0x7F,0xDF,0xAF,0xFF,
-0xF7,0xAF,0x36,0xFE,0xBF,0x65,0xEB,0xF6,
-0xFE,0x9F,0x6F,0xFE,0x07,0xFF,0xCF,0xFF,
-0xF8,0xFE,0xFF,0xCF,0xFF,0xF6,0xFA,0xE7,
-0xFB,0xFE,0xFF,0xBB,0xED,0xF9,0xFF,0xFF,
-0xFF,0x5F,0xFF,0xFF,0xFF,0x75,0xFF,0xEF,
-0x7E,0xFD,0xE0,0xE8,0x5E,0xD3,0xE5,0xF9,
-0x3E,0x5F,0xD7,0xF7,0xFF,0xFA,0x2F,0xFB,
-0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0x7F,
-0x7F,0xD7,0xF5,0x7D,0x5F,0x57,0xD5,0xF5,
-0xEF,0xFF,0xF3,0x7F,0xFC,0x7F,0xFF,0xC7,
-0xF1,0xFF,0xFF,0x1F,0xCF,0xB0,0xFF,0x3F,
-0xCF,0xF3,0xFC,0xFF,0x3F,0xCE,0xFF,0xE4,
-0xFF,0xDF,0x7F,0xFE,0xF7,0xBB,0xFF,0xFF,
-0xDF,0xEF,0xEE,0xFF,0xBF,0xEF,0xFB,0xFE,
-0xBF,0xBF,0xEF,0xFF,0xD1,0xFF,0xFF,0xFF,
-0xFD,0xFB,0xFF,0xFD,0xFF,0xFB,0x9F,0xE9,
-0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0xBF,
-0xFF,0xB3,0xFF,0xFF,0xF7,0xFF,0xFF,0xAF,
-0xF7,0xFF,0xB6,0x3F,0xEB,0xFA,0xFE,0xBF,
-0xAF,0xEB,0xFA,0xFE,0xBF,0xFE,0xA7,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,
-0xFE,0x9F,0xF7,0xF9,0xFF,0x7F,0x9F,0xE7,
-0xFF,0xFF,0xFE,0xAF,0x6F,0xFF,0xFF,0xFF,
-0x9F,0xFF,0xDF,0xFF,0x7D,0x5F,0xDD,0xFF,
-0xFB,0xBF,0xE7,0xBB,0xFF,0xFB,0xDF,0x6D,
-0x5F,0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xEB,0xF7,0xFF,0xE7,0xEF,0xF7,0xFF,0xFF,
-0x7F,0xFF,0xF7,0xFF,0xFC,0x8F,0xFF,0xEF,
-0xFD,0xFE,0xFF,0xBE,0xF4,0xF2,0x7D,0xD7,
-0xCF,0xFF,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xCF,0x6B,0xFF,0xBF,0x3F,0xFB,0xF2,
-0xFC,0x7F,0xEB,0xFF,0x9F,0xFA,0xFF,0xFF,
-0x3F,0xFF,0xF3,0xFF,0xFF,0xFD,0x70,0xF7,
-0xFF,0xFF,0xBF,0xFF,0xFB,0xD7,0xFE,0xF5,
-0x77,0xFF,0x15,0xDD,0x77,0xFD,0xFF,0x7F,
-0xDF,0xF7,0xFB,0xCD,0xBF,0xFF,0xFD,0xFF,
-0xFF,0xDF,0x37,0xCD,0xF9,0xEC,0xFE,0xEF,
-0xBB,0xF4,0xFB,0x3F,0x4F,0xB3,0xFF,0xFD,
-0xCB,0xFF,0xE9,0x7E,0x54,0x9F,0xE5,0x4B,
-0xB7,0xFF,0xDD,0x7D,0xC7,0x71,0xDD,0x77,
-0x5D,0xD7,0x75,0xCD,0x7F,0xD6,0xFF,0xD3,
-0xF6,0xF9,0x3F,0x6D,0x95,0xAF,0x7F,0xFE,
-0xFF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,
-0xFE,0xF6,0xC7,0xFF,0xAD,0x7B,0xCA,0xFF,
-0xBF,0xBF,0xEF,0xFD,0xE3,0xDF,0xB7,0xED,
-0xFB,0x7E,0xDF,0x37,0xED,0xE3,0xFB,0xDF,
-0xFF,0x52,0x5C,0x15,0xFD,0xCF,0x7F,0xDF,
-0xFE,0xEF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEC,
-0x7B,0xFE,0xFF,0xFE,0x3E,0x7F,0xDA,0xF7,
-0xFD,0xFF,0x7F,0xFF,0xFF,0xFB,0xEF,0xBB,
-0x6F,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFF,
-0xF7,0x7D,0xFF,0xD8,0xFF,0xFD,0xBF,0x7F,
-0xFB,0xFF,0xFF,0x9F,0xFB,0xFE,0x7F,0x9F,
-0xE7,0xF9,0xFE,0x7F,0x9F,0xEA,0x7F,0xF6,
-0xBF,0xBD,0x6A,0x5A,0xF6,0xE5,0xBF,0x77,
-0x5F,0x6D,0xDD,0x77,0x5D,0xD7,0x75,0xDD,
-0x77,0xFF,0xA5,0xBF,0xCF,0xFB,0xFF,0xFF,
-0xBF,0xCF,0xFB,0xFD,0xFF,0xBF,0xF3,0xFE,
-0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFD,0xAB,
-0xFF,0xBF,0xBF,0xFF,0xFB,0xFF,0x7F,0xEF,
-0xFF,0xBE,0xFB,0xEE,0xFB,0xBE,0xEF,0xBB,
-0xEE,0xFB,0xBF,0xFF,0xB5,0xFF,0xD0,0xBC,
-0xFD,0x2F,0x4B,0xF7,0xFF,0xFF,0x9F,0xF9,
-0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,
-0xFA,0x8F,0xFD,0xAB,0xFA,0xDA,0xBF,0xAF,
-0xB3,0xFD,0xFF,0xBF,0xFB,0xFE,0xFF,0xBF,
-0xEF,0xFB,0xFE,0xF7,0xBF,0xFF,0x9F,0xFF,
-0x77,0xF7,0xBD,0xFD,0x77,0xDF,0xFF,0x7E,
-0xDF,0xED,0xBB,0xFE,0xFF,0xBE,0xEF,0xFB,
-0xFE,0xFF,0xFA,0x3F,0xFF,0xBE,0x6F,0x8F,
-0xE6,0xF9,0xFE,0x7F,0x9F,0xC7,0xFE,0x7F,
-0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,0xFB,
-0x7F,0xFF,0x7F,0xCF,0xFF,0xFD,0xFF,0xFF,
-0xDF,0xFB,0xAF,0xBF,0xEF,0xFF,0xFE,0xFF,
-0x9F,0xEF,0xFB,0xFF,0xFC,0xFF,0xFB,0xFE,
-0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xF7,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xF5,0xFF,0xFF,0xFF,0x3F,0xDF,0xF7,
-0xFF,0xFF,0x7F,0xEF,0xFE,0xFF,0xBF,0xFF,
-0xFB,0xFF,0xFF,0xBF,0xEF,0xFF,0xB3,0x7F,
-0xFF,0x7B,0x5E,0xF7,0xFD,0xFF,0x7B,0x7F,
-0xF7,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,
-0xDF,0xF7,0xFF,0x17,0xFF,0xFF,0xFF,0x7F,
-0xFF,0xFF,0xDD,0xF6,0xFC,0xBF,0xCB,0xF2,
-0xBC,0xBF,0x2F,0xCB,0xF2,0xFC,0xBF,0xFE,
-0x8F,0xFF,0xFA,0x7E,0xBF,0xA7,0xEB,0xDA,
-0xFC,0xBF,0xAF,0x7A,0xFE,0xBF,0xAF,0xEA,
-0xFA,0xFE,0xBF,0xAF,0xF4,0xDF,0xFE,0xFF,
-0xF3,0x3C,0x7F,0x3E,0xFF,0xCF,0xF8,0xBF,
-0x8F,0xE3,0xF8,0xFE,0x3F,0x8F,0xE7,0xE8,
-0xFF,0xFC,0x9F,0xFF,0xFF,0xCF,0xEB,0xB3,
-0xE7,0xFB,0x7B,0xF3,0xFE,0xFF,0xCF,0xDB,
-0xFB,0xFB,0xBF,0x6F,0x6F,0xDF,0xEC,0x7F,
-0xFF,0xFF,0xF7,0xFD,0xFD,0xFF,0xFF,0xFF,
-0xFF,0xB2,0xBF,0xFF,0xDE,0xFD,0xBD,0xEF,
-0xFB,0xF6,0xDF,0xEA,0xE7,0xDB,0xFE,0xBB,
-0xFF,0xEB,0xFB,0xBF,0x9F,0x8F,0xE8,0xFE,
-0x3F,0x8F,0xA3,0xF8,0xFE,0x3F,0x8F,0xFF,
-0xF8,0x7E,0xFD,0xFD,0x7F,0xFF,0xFB,0xCD,
-0xFF,0xFD,0xFF,0x5F,0xEF,0xFD,0xFF,0xFF,
-0xDF,0xF7,0xFD,0xFF,0xBE,0x90,0xFF,0xFF,
-0xEE,0xFF,0x3F,0xBF,0xF3,0xBB,0xFE,0xB7,
-0xAB,0xFA,0xFE,0xAF,0xAD,0xEA,0xFA,0xDE,
-0xAB,0xFF,0x63,0xFF,0xFE,0xF2,0xFF,0xB3,
-0xFF,0xDF,0xEE,0x7D,0xFF,0x03,0xF1,0xF4,
-0x3F,0x1F,0xC3,0xF1,0xEC,0x7F,0xFE,0x6F,
-0xFF,0xFB,0xFB,0xFF,0x9F,0xFF,0xBF,0xFF,
-0x7B,0x5F,0xFD,0xFF,0xDF,0xF7,0xFD,0xFD,
-0x7F,0x7F,0xDF,0xFE,0xCF,0xFB,0xFF,0xFF,
-0xAF,0xFB,0xFF,0x1F,0xEF,0xA5,0xFD,0xBF,
-0xDF,0xFB,0x7D,0xFF,0xBF,0xDF,0xFB,0xFF,
-0xFD,0x3B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,
-0xAF,0xF3,0xFF,0xFB,0x7F,0xBF,0xD7,0xFB,
-0xBF,0x7F,0xBB,0xF7,0xFF,0xF8,0x7F,0xFF,
-0xFA,0x5F,0xD7,0xFF,0xDF,0x7F,0xEF,0xFF,
-0xFF,0x7F,0xDB,0xF7,0xFD,0xFF,0x7F,0xDF,
-0xB7,0xFB,0xEC,0xFF,0xFF,0xF7,0xBF,0xEF,
-0xFD,0xFC,0xFB,0xFF,0xEF,0xF0,0xFE,0x3F,
-0x8F,0xE3,0xF8,0xFE,0x3F,0x8F,0xEF,0x8D,
-0xFF,0xFF,0xEF,0x7F,0xBF,0xFF,0xFB,0xFF,
-0xDB,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xEF,0xD8,0xFF,0x2E,0x7F,
-0xBE,0xEF,0xFE,0x6E,0xFF,0xBF,0xF9,0xFF,
-0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFC,0x66,0xBE,0x47,0xF3,0x7F,0xDF,0xFE,
-0x87,0x9F,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xD6,0x6F,0x7C,
-0xFB,0x4F,0xD2,0xFF,0xFD,0x2B,0xFE,0xFF,
-0xFF,0xFD,0x5F,0xD7,0xD5,0xF5,0x7D,0xFF,
-0xFF,0xFF,0xBF,0x9B,0xFF,0xFF,0xDF,0xB7,
-0xFF,0xFF,0xDF,0xFF,0x3F,0xCF,0xFE,0x7F,
-0xBF,0xEF,0xFB,0xFC,0xFF,0x3F,0xFF,0xD9,
-0xBF,0xFE,0x97,0xEC,0x8F,0xB7,0xFE,0x9B,
-0x7D,0xFD,0xB7,0xDD,0x77,0x1D,0xC7,0x71,
-0xDD,0x77,0x5D,0xD7,0xF3,0x6F,0xFD,0x3F,
-0x73,0xDD,0xAF,0xFD,0x7A,0xFF,0xFF,0xAF,
-0xFE,0xFD,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,
-0xEF,0x66,0x7F,0xFF,0xFF,0xBF,0xBF,0xFF,
-0xFB,0xFF,0xF7,0xDF,0xFD,0xFB,0x7D,0xDF,
-0xB7,0xCD,0xF3,0x7C,0x5F,0x3F,0x91,0x3F,
-0xFF,0x3D,0xEF,0x7B,0xFF,0xFC,0xFF,0xCA,
-0xEF,0xFE,0xFF,0xBD,0xEF,0xFB,0x1E,0xE7,
-0xBB,0xEC,0x7F,0xB3,0xFF,0xFD,0x9F,0xFF,
-0xFF,0xFE,0xFF,0xFF,0x7F,0xBF,0xFB,0xFE,
-0xFF,0xBF,0xEF,0xFB,0xEE,0xFB,0xBF,0xDF,
-0x67,0xFF,0xFF,0xBF,0xEF,0xDB,0xFF,0xBC,
-0xFE,0x7F,0xFB,0xFF,0x9F,0xEF,0xF9,0xFE,
-0x7F,0x9F,0xE7,0xF9,0xFE,0x87,0xFF,0xEE,
-0xFB,0xBE,0xE5,0xBF,0xEF,0xF9,0xD7,0x65,
-0xF7,0xDD,0xE7,0x7D,0xDF,0x77,0x5D,0xD7,
-0x7F,0xF8,0x9B,0xFE,0xFF,0xBF,0xEF,0xFB,
-0xFF,0xFF,0xBF,0xEF,0xFB,0xFF,0x7F,0xCF,
-0xF3,0xFC,0xFF,0xBF,0xEF,0xFF,0xDB,0x3F,
-0xEF,0xFB,0xFE,0xFF,0xDF,0xFF,0xFE,0xFB,
-0xBB,0xEF,0xBF,0xEF,0xBB,0xEE,0xFB,0xBE,
-0xEF,0xBB,0xFF,0xFC,0x7F,0xFD,0x3B,0x5B,
-0xD6,0xE5,0xFD,0x4F,0xC3,0xFB,0xFF,0xBF,
-0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFF,
-0xB4,0xFF,0xFA,0xBC,0x8F,0xB2,0xE9,0xD2,
-0x2E,0xCF,0xFB,0xFF,0xBF,0xEF,0xFB,0xFE,
-0xFF,0xBF,0xEF,0xFB,0xFF,0xEC,0xFF,0xFD,
-0xFD,0x7F,0xDF,0xF7,0xE4,0xDF,0x5F,0xFF,
-0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xC3,0xFF,0xEF,0xE6,0xF8,0xFE,
-0x3F,0x8B,0x83,0xF9,0xFE,0x7F,0xE7,0xF9,
-0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x17,
-0xFD,0xFF,0xFF,0xFF,0x7F,0x5F,0xF7,0x2C,
-0xFF,0xFF,0xFF,0xFE,0x7F,0xFF,0xE7,0xF9,
-0xFE,0x7F,0x9F,0xFE,0x2F,0xFF,0xFF,0xEF,
-0xFF,0xFE,0xBF,0xEF,0xAD,0xFF,0xFF,0x7F,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFE,0xDF,0xFF,0xDF,0xFF,0xFD,0xFD,0x7F,
-0xDF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0x3F,0xFE,
-0xF7,0xFD,0xEF,0x7A,0xFF,0xB1,0xBD,0xFF,
-0x7F,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,
-0xFF,0x7F,0xF3,0x27,0xFF,0xDF,0xFF,0xDD,
-0xFF,0xFC,0x9B,0xFF,0xCB,0xFC,0xBF,0x2F,
-0xCB,0xF2,0xFC,0xBF,0x2F,0xC9,0xFF,0xDE,
-0xFF,0xDF,0xAF,0xEB,0xDA,0xFE,0xBB,0xAF,
-0xEB,0xF8,0xF7,0xAF,0xE8,0xFA,0xFE,0xBF,
-0xAF,0xEB,0xF2,0xFF,0xFD,0xFF,0xFF,0xEF,
-0xBD,0xD7,0xBF,0xFF,0xFF,0xDE,0x8F,0xB8,
-0xDE,0x37,0x8D,0xA3,0x78,0xDA,0x3F,0x8F,
-0xFF,0xA1,0xFF,0xFF,0xFB,0xFB,0xFF,0xFF,
-0xFF,0xFF,0xA7,0xBD,0xFB,0x76,0xFD,0xBF,
-0xEF,0xDB,0xFE,0xBB,0xBF,0xFE,0x27,0x7F,
-0xFF,0xFE,0xFE,0xFD,0xF5,0xFF,0xEF,0xF5,
-0xDF,0x1F,0xE7,0xFD,0xFF,0x7F,0xDF,0xF7,
-0xFD,0xFF,0xFF,0xCD,0xFD,0xAE,0xFF,0xFA,
-0x3E,0x3F,0xAB,0xFD,0xF8,0x7E,0x8F,0xE3,
-0xF8,0xFE,0x3E,0x8F,0xE3,0xF8,0xFF,0xFE,
-0x1F,0xEF,0xDF,0xBF,0xFE,0xDE,0xDF,0xD9,
-0xFF,0xDF,0xBC,0xFF,0xFF,0x7F,0xFF,0xEF,
-0xFD,0x7F,0xDF,0xF7,0xF9,0x3F,0xFE,0xFF,
-0xFF,0x6F,0xFE,0xDE,0xBF,0xF7,0xED,0xEA,
-0xFD,0x8F,0x83,0xF8,0xEA,0x3F,0x8F,0xEF,
-0xFF,0xF4,0x7F,0xFF,0xEF,0xEF,0x7B,0xF3,
-0xF1,0x5F,0xFF,0xFF,0xF1,0x3B,0x7F,0xDF,
-0xF7,0xFD,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,
-0xFF,0xFF,0xF7,0xFF,0x6F,0xFF,0x7F,0xFF,
-0xFF,0xF7,0xDE,0xF7,0xBF,0xEF,0xFB,0xF7,
-0xFD,0xFF,0xFF,0xF5,0xFA,0xFF,0xFF,0xFB,
-0xE7,0xFF,0xF3,0xF8,0x7F,0xF3,0xDF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0xEF,
-0xBB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,
-0xFF,0x7F,0xFF,0x9F,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xCF,0xFF,0x37,0xFF,0xFF,
-0x7F,0xDF,0x77,0x5D,0xE7,0xFC,0xFF,0xBF,
-0xF7,0xF5,0xFB,0xFF,0xFF,0xD7,0xF5,0xFB,
-0xFF,0xFF,0x45,0xFD,0x7F,0xEA,0xFD,0xBE,
-0xBF,0xDF,0xF7,0xFF,0xFF,0xDB,0xFB,0xFE,
-0xFF,0xBF,0xEF,0xFF,0xFF,0xFF,0xFB,0x5F,
-0x7F,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFE,0xFF,0xEF,0xFD,0xFF,0x7F,0xDF,
-0xFF,0xEF,0xFB,0xF8,0x0F,0xF3,0xFF,0xF9,
-0x2E,0xFB,0xFE,0xFC,0xF3,0xEF,0xFF,0xFF,
-0xBF,0xFF,0xFB,0xE7,0xFF,0xFE,0x7E,0xFF,
-0xC0,0x6B,0xCF,0xFF,0x34,0xDF,0xF1,0xFD,
-0xFF,0xEF,0xFF,0xFF,0xFF,0xDF,0xF7,0xFD,
-0xCF,0x7F,0x9C,0xFD,0xFD,0x6C,0xF7,0xFF,
-0xF6,0xFD,0xEB,0x2B,0x9F,0xFF,0xFC,0xFE,
-0x7E,0xFF,0xFF,0xFF,0xFF,0xD7,0xF3,0xF7,
-0xFF,0xFB,0xE1,0xBF,0xFF,0xEB,0x7A,0xDE,
-0xD7,0xFB,0xFF,0xF9,0xFE,0xFF,0xFF,0xF3,
-0xDE,0x7F,0xFD,0xE7,0x7F,0xFF,0xFD,0xBB,
-0xFF,0xFF,0x7E,0xCC,0xF6,0xAF,0x5F,0x7F,
-0xFE,0xF4,0x7D,0xF7,0xFD,0xBB,0x6E,0xDB,
-0xB7,0xFF,0xF7,0xDF,0x66,0xFF,0xFF,0xF7,
-0x3D,0xCF,0xDE,0xBD,0xFF,0xFF,0xDE,0xDB,
-0x8D,0xF7,0x7E,0xDF,0xB7,0xEF,0x7F,0xFF,
-0xF6,0x87,0xFF,0xFF,0xEF,0xFE,0xDE,0xBF,
-0xFF,0xFF,0xFF,0xBB,0xEF,0xFD,0xFF,0x7B,
-0xDE,0xF7,0x3F,0xFF,0xBF,0xFB,0xDB,0xFF,
-0xF2,0xB6,0xFD,0xBD,0x7F,0xE7,0xFF,0xFF,
-0xFF,0x6F,0xF7,0xFF,0xFF,0xFF,0xFE,0x77,
-0xFF,0xBF,0xF8,0xAF,0xFF,0xDF,0xBF,0xFF,
-0xBF,0x7F,0xFB,0xFF,0xFF,0xFF,0xDB,0xFE,
-0xFF,0xBF,0xFF,0xFA,0xFF,0xFD,0xFF,0xF6,
-0x7F,0xFF,0x9F,0xFF,0xFF,0x3F,0xEF,0xF8,
-0xEE,0x7E,0x9F,0xBA,0xFE,0xBF,0x8F,0xEF,
-0xFE,0xFE,0xF9,0xFF,0xFA,0x7F,0xFE,0x7E,
-0xBF,0xAF,0xFB,0x96,0xFD,0x9F,0xEF,0x5E,
-0x65,0xBE,0xEF,0x5B,0xB6,0xFF,0xBE,0xE3,
-0xFF,0xB5,0xBF,0xFF,0xFD,0xFF,0x7F,0xFF,
-0xEF,0xDF,0xFE,0xFF,0xBF,0xFB,0xFE,0xFF,
-0xBF,0xCF,0xFF,0xFF,0xFF,0xFD,0x9B,0xFF,
-0xFE,0xFB,0xFE,0xDF,0xFF,0x7F,0xFF,0xF7,
-0xFE,0xFF,0xDF,0xFB,0xFB,0xFE,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xB7,0xFE,0xFA,0xFF,0xAB,
-0xEF,0xFF,0xFD,0xB5,0x7B,0x7F,0xFB,0xF7,
-0xFD,0xFF,0xFF,0xDD,0xFF,0xEF,0x8F,0xFF,
-0x2F,0xFF,0xFB,0x7C,0xFF,0x3F,0xDF,0x73,
-0xEB,0xFE,0x3F,0xFF,0xEF,0xFB,0xFE,0xFF,
-0xEF,0xFD,0xFF,0xBF,0xFD,0x0F,0xFF,0xFF,
-0xFF,0xF5,0xF9,0xFF,0x7F,0xD7,0xFD,0xFF,
-0xDF,0xFF,0xF7,0xFB,0xFF,0x7F,0xBF,0xFF,
-0xFF,0xF0,0x9F,0xFF,0xFE,0x7F,0x8B,0xE3,
-0xF9,0xDE,0x27,0x9B,0xE6,0xBE,0x7F,0x9B,
-0xC3,0xF8,0xDE,0x7F,0x9D,0xE7,0xFE,0x7F,
-0xFF,0xFF,0x5F,0xD7,0xFF,0xFF,0xFF,0x4F,
-0xFB,0xFF,0xFF,0x7F,0xFF,0xAF,0xFF,0x9F,
-0x7F,0xFB,0xFF,0xE8,0xFF,0xFF,0xFE,0xBF,
-0xAF,0xFF,0xFF,0xFE,0xBF,0xEF,0xF7,0xFF,
-0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,
-0xFC,0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xFF,
-0xFD,0x3F,0xCF,0xFF,0xFF,0xFF,0xFF,0xF7,
-0xFF,0xFD,0x7F,0xFF,0xFF,0x93,0xFF,0xFF,
-0x7A,0xDF,0xF7,0xFF,0xFF,0x7B,0x7F,0xB7,
-0xEF,0xFF,0xFF,0xFD,0xBF,0xFD,0xFB,0xFF,
-0xF7,0xFF,0xD7,0xFF,0xFF,0xFF,0xFC,0x9F,
-0x6F,0xCB,0xFF,0xF4,0xBB,0xDF,0xD6,0xFD,
-0xBF,0x2F,0xD3,0xF7,0xFF,0xDF,0xFF,0xCF,
-0xFF,0xFA,0xBE,0xBD,0xAF,0x6A,0xDA,0xBE,
-0xBB,0xAB,0x3A,0xBE,0x2D,0xAE,0xEB,0xDA,
-0xF6,0x3F,0xAD,0xF5,0xDD,0xFF,0xCF,0xF1,
-0xFF,0xF9,0x7F,0xFF,0x73,0xFE,0xFF,0xCF,
-0xC3,0xF4,0xF7,0x2F,0xF3,0xFF,0xFC,0xFF,
-0x7C,0x1F,0xFF,0x3F,0x4F,0xFF,0x7E,0xFF,
-0xEF,0xBD,0xF6,0xFE,0xFF,0x2B,0xEF,0xDC,
-0xFB,0xFD,0xFF,0xFB,0xFF,0xEA,0x7B,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFB,0xF7,0xDF,0xFF,
-0xE3,0x7D,0xFF,0xB7,0xFF,0xBF,0xFF,0xFF,
-0xDF,0xFF,0xF8,0xFF,0xBF,0xFF,0xBF,0xEB,
-0xE7,0xFA,0xFE,0x3D,0xBF,0xE9,0xFC,0xBF,
-0xFF,0xFA,0xFB,0xFE,0xFF,0xFF,0xFF,0xD9,
-0xFF,0xFF,0xFF,0xF6,0x7F,0xFF,0xF6,0x7D,
-0xFF,0xDF,0xCF,0xFD,0xBF,0xFB,0xEF,0x7E,
-0xFF,0x7F,0xFF,0xFF,0xD3,0xFF,0xFD,0xFB,
-0xFF,0xFB,0xFF,0xFF,0xFF,0xEF,0xFF,0xBF,
-0xFE,0xFF,0xF7,0xEF,0xFF,0xFF,0xFF,0xFB,
-0xFF,0x87,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,
-0x7B,0xFE,0xFF,0xFE,0x3B,0xF7,0xF7,0xFF,
-0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,
-0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xF7,
-0xFF,0xFF,0xAD,0xFF,0xFE,0xF7,0xFF,0xFF,
-0x5F,0xFF,0xFF,0xDF,0xFF,0xFD,0xFF,0xF5,
-0xFF,0xDF,0xFF,0xBD,0xFF,0xE9,0xFF,0xC7,
-0xF3,0xFF,0xFF,0xF7,0xFF,0xF3,0xFF,0xF8,
-0x3B,0xFF,0xFF,0x7B,0xDF,0xBF,0xFB,0xEF,
-0xFB,0xFF,0xFB,0xF7,0xF7,0xBB,0xFF,0xFF,
-0xFF,0xFF,0xFB,0xFF,0xFE,0x7F,0xF3,0x7F,
-0x5E,0xB7,0xBF,0xFD,0x7F,0xFF,0xF9,0x7F,
-0xFB,0xFF,0xEB,0xFD,0x7F,0x7F,0xFF,0xEF,
-0xFB,0xE0,0x3F,0xFE,0xBF,0xBF,0xDF,0xFF,
-0x7E,0xFF,0xF7,0xFF,0xFF,0xFE,0xBF,0xFF,
-0xDB,0x78,0xFF,0xFF,0xFF,0xEE,0xA1,0xBF,
-0xF5,0xDE,0xFB,0xF7,0xFF,0xFB,0xFF,0xFF,
-0xFF,0xFF,0xFB,0xFF,0xFF,0xD7,0xFF,0xFF,
-0xFF,0xFF,0xEF,0xF0,0xFF,0xFF,0xFF,0xF3,
-0xF7,0xFF,0xEF,0xFF,0xE7,0xCF,0xFF,0xFB,
-0xFF,0xEF,0xFF,0xFF,0x9F,0x9F,0xEF,0xFC,
-0x16,0xBF,0xFE,0xF3,0xE4,0xFF,0xFF,0xC6,
-0xFF,0xE7,0xFF,0xFF,0xFD,0xFF,0xBF,0xFF,
-0xFF,0x3F,0xFF,0xBF,0xD6,0xAF,0x7F,0xFE,
-0x6B,0x7E,0x7F,0xFF,0xAF,0xFF,0xFF,0xBF,
-0xFF,0x5F,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF,
-0xFF,0xBD,0xDB,0xFF,0xFE,0x5F,0xF2,0xFF,
-0xFF,0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xEF,0x7F,0xFF,0xFF,0xFF,0xFF,0xDE,0xBF,
-0xFF,0xFF,0xEF,0xFB,0x77,0xFE,0xBD,0x7F,
-0x5F,0xFF,0xFF,0xFF,0xDF,0x6F,0xED,0xFF,
-0xFD,0xFF,0x7F,0xFD,0x6F,0xFF,0xFF,0x77,
-0xDA,0xCF,0xFD,0x5F,0xFF,0xBF,0xFF,0xFF,
-0xDF,0x7F,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,
-0x66,0x7F,0xFF,0xFE,0xBF,0xE7,0xBF,0xFA,
-0xFF,0xFE,0xFF,0xFF,0xFF,0xDF,0xFF,0x59,
-0xEF,0xFF,0xEF,0xFB,0x7F,0x89,0xFF,0xFF,
-0xE9,0xFF,0x6F,0xFF,0xF5,0xFF,0xFF,0xFF,
-0xFF,0xFF,0x7F,0xF2,0xF7,0xFF,0xFF,0xEF,
-0xF8,0x7F,0xFB,0xFF,0xFD,0xFF,0xFF,0xD9,
-0xFF,0xEF,0xBB,0xFF,0xFF,0xFF,0xBF,0xEF,
-0xDE,0xFF,0xFF,0x9F,0x7F,0xDF,0xFF,0xF7,
-0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xAF,
-0xFF,0xFF,0xF7,0x3F,0xEB,0x9F,0xFE,0x7F,
-0x9E,0x7F,0x9F,0xFE,0x87,0xFF,0xED,0xDB,
-0x56,0xFF,0xBF,0xAF,0x0B,0xD2,0xFF,0xEF,
-0xDB,0x6E,0x7D,0xBD,0x6F,0xF8,0xFE,0x3F,
-0xFA,0x5B,0xFF,0xFD,0xBF,0xEF,0xFF,0xBF,
-0x6F,0xDB,0xE6,0xFF,0xFF,0x3F,0xFF,0xDF,
-0xFE,0xFF,0xFF,0xFF,0xFF,0xDA,0x3F,0xFF,
-0xFB,0xFE,0xFE,0xFF,0xFF,0xDF,0xF7,0xBD,
-0xFF,0xFD,0xFF,0xFE,0xFF,0xFB,0xFF,0xFF,
-0xFF,0xFF,0xF1,0x5F,0xFD,0x9F,0xDF,0xFD,
-0xFF,0xFD,0x7F,0xFF,0xFF,0xFF,0xFF,0x76,
-0xFA,0xFF,0xFF,0x7F,0xE3,0xF8,0xFF,0xAE,
-0xFF,0xFB,0x7E,0x9D,0x73,0xFF,0xFA,0x7F,
-0xDF,0xFF,0xFF,0x7F,0xFF,0xFB,0xCD,0xFF,
-0x7F,0xEF,0xFB,0xFF,0xFD,0xFF,0xF7,0x7F,
-0x7F,0xEF,0xFF,0xED,0xFF,0xFF,0xFF,0xB5,
-0xFF,0xBF,0xFF,0xBF,0xFD,0xEF,0xDB,0xF7,
-0xFF,0x93,0xFF,0xEF,0xE2,0xF9,0xBE,0x7F,
-0x8B,0xE7,0xF9,0xFE,0x6B,0xE7,0xF9,0xFE,
-0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x47,0xFF,
-0xFF,0xFD,0xFF,0x9F,0xFF,0xD7,0xFF,0xFF,
-0xFF,0xFF,0xF5,0xFF,0x9F,0xFF,0xF7,0xFE,
-0xFF,0xBF,0xFE,0x6F,0xFF,0xFF,0xFB,0xFF,
-0xFF,0xFF,0xAF,0xFF,0xFF,0xFF,0x7F,0xFB,
-0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,
-0xDF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xDF,
-0xFF,0xFF,0xFF,0x5F,0xFF,0xFF,0xFF,0xFF,
-0x5F,0xFB,0xFE,0xFF,0xF8,0x37,0xFF,0xFF,
-0xEF,0xFF,0x7F,0xFE,0xBF,0xFF,0xFF,0xFE,
-0xBF,0xFF,0xFF,0x7F,0xFF,0xBF,0xFD,0xFF,
-0x7F,0xFA,0x7F,0xFF,0xFF,0x6F,0xFF,0xFF,
-0x7D,0xFF,0xCF,0xFF,0xFF,0xFF,0x4F,0xFF,
-0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0xBF,
-0xFF,0xAE,0xEB,0xFA,0xFE,0xBB,0xAD,0xEB,
-0xFA,0xF7,0xAF,0x6B,0xFA,0xF6,0xBF,0x25,
-0xE9,0xF2,0x7F,0x45,0xFF,0xFF,0xFD,0xF7,
-0xF7,0xBF,0xFF,0xDF,0xFF,0xFF,0xBF,0xFB,
-0xFF,0xDF,0xF3,0xFF,0xF7,0x3F,0xCF,0xFF,
-0xA1,0xFF,0xFF,0xBF,0xE7,0xFF,0xFF,0x7F,
-0xFF,0x3D,0xFF,0xFF,0xFF,0xF7,0xFF,0x2F,
-0xFF,0xFB,0xF5,0x7F,0xFE,0x57,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,
-0x3F,0xFF,0xFE,0xFF,0xFF,0xFF,0xFD,0xFE,
-0xF7,0xEE,0xAF,0xFE,0xEE,0xE7,0xFA,0xFF,
-0xFE,0x9D,0xF9,0x5E,0xFE,0xFF,0xEB,0xFF,
-0xFF,0xDF,0xA7,0xFF,0xFF,0xFF,0xFC,0xDB,
-0xFF,0xFF,0xFF,0x7E,0xFB,0xFF,0xFF,0xEF,
-0xFB,0xFD,0xFF,0xDB,0xFF,0xFF,0xFF,0xEF,
-0xFF,0xFF,0xFF,0xFD,0xBF,0xFE,0xBF,0xFF,
-0x6F,0x7F,0xFF,0xF7,0xFF,0xFF,0xF9,0xFF,
-0xF7,0xFF,0xBF,0xDE,0xF7,0xFF,0xFF,0xFF,
-0xFA,0x7F,0xFD,0xBF,0x5F,0xFF,0xFF,0xBF,
-0xFF,0xED,0xFF,0xF7,0xBF,0xFF,0xFF,0xEF,
-0xFF,0xDF,0xFF,0xFF,0xFF,0xE6,0xFF,0xFB,
-0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,
-0xFD,0xFF,0xF5,0xFF,0xF6,0x7F,0xDF,0xBD,
-0xCF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,
-0xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3,
-0xFF,0xEE,0xBF,0xFF,0x7D,0xEF,0xFE,0xFF,
-0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFE,
-0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xB5,0xAE,
-0xFF,0xFF,0xB6,0xFE,0xBF,0xFF,0xFF,0xBF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0x27,0xFF,0xEF,0xFE,0x7F,0xDF,0xFF,
-0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFD,0xFF,0xF7,0xF9,0x9F,0xFF,
-0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,
-0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0x0F,0xFF,0xE7,0xBF,0xFE,
-0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFC,0xBF,
-0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xC4,
-0x6B,0xFF,0x29,0x1F,0xFB,0xAF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xEF,0x1B,0xFE,0xFF,0xFC,
-0x6F,0xFF,0xFF,0xFD,0x6A,0xF7,0xD7,0xF5,
-0xBF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFE,0xBF,0xFF,0xFF,0xFA,0xFF,0xFF,0xF7,
-0xFB,0xDD,0xBF,0xFF,0xE7,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x7F,0xFF,
-0xFF,0xF5,0xFF,0xFF,0xF7,0xFD,0xB3,0xEF,
-0xFD,0x7E,0x5D,0xFF,0xFD,0xFF,0xFF,0xFF,
-0xFD,0x7F,0xD2,0xF5,0xFB,0x7E,0xCB,0xB7,
-0xFF,0xFF,0xFF,0xC6,0xFF,0xFD,0xEE,0x63,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xFD,0x65,
-0x5B,0xDF,0xFF,0xD5,0xFF,0xFF,0xFF,0xF6,
-0xE7,0xBF,0xF7,0xA9,0xFF,0xFF,0xED,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,0xFF,0xFF,
-0xAF,0xFF,0xFF,0xFF,0xF8,0x1B,0xFF,0xE3,
-0xD0,0xBF,0xFF,0xE1,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xD7,0xFF,0xFF,0xFF,0x5F,0xFF,0xFF,
-0xFF,0xFF,0xAF,0xFF,0xDB,0x76,0xBF,0xFF,
-0x7F,0xFF,0xBF,0xEF,0xFE,0xFF,0xBF,0xEF,
-0xFB,0xFE,0xFF,0xFF,0xFF,0xBF,0xF2,0x7F,
-0xFF,0x9F,0xFE,0xBD,0xFE,0x7F,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xF7,0x3F,0xEC,0x7F,0xF6,0x95,0xBB,
-0xEF,0xF8,0xFE,0xFC,0xBF,0x2F,0xDA,0xFC,
-0xBF,0x2F,0xCB,0xF2,0xFC,0xBF,0xEF,0xFF,
-0xA9,0xBF,0xCF,0xFB,0xFF,0xFF,0xFF,0xFE,
-0xDD,0xB7,0x6D,0xF6,0xD9,0xB6,0x6D,0x9B,
-0x76,0xD9,0xBF,0xFB,0xFD,0xA3,0xFF,0xBF,
-0xEF,0xFF,0xEF,0xFF,0xFF,0xFF,0x7F,0xDF,
-0xFD,0xEF,0x7B,0xDE,0xF7,0xFD,0xEF,0x7F,
-0xFF,0xFF,0x05,0xFF,0xFA,0xFE,0x7F,0xEF,
-0xE3,0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xFF,
-0xFF,0x5F,0xFF,0xFF,0xFD,0x7F,0xFB,0xAF,
-0xFF,0x63,0xC8,0xFF,0xBF,0xEF,0xFF,0xFF,
-0xFA,0x7F,0xFF,0xFF,0xFF,0xFE,0x9F,0xF7,
-0xFF,0xFA,0xBF,0xFE,0x9F,0xFB,0x7F,0xFF,
-0xFF,0xEF,0xD7,0xFF,0xFF,0xF5,0xFF,0xFF,
-0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xBF,0xFF,
-0xF9,0xBF,0xFF,0xBE,0x27,0x9F,0xE7,0xF9,
-0xFE,0x7F,0x8B,0xE7,0xFE,0x7F,0x9F,0xE2,
-0xF9,0xFE,0x7F,0x9F,0xE7,0xF1,0x7F,0xFF,
-0xFF,0xFF,0xFB,0xFE,0xFF,0xFF,0xFF,0xD7,
-0xFF,0xFF,0xFF,0xFF,0xF5,0xFF,0xFF,0xFF,
-0xD7,0xFF,0xFA,0xFF,0xFE,0xFF,0xFF,0xFF,
-0xFD,0xFF,0xFF,0xFF,0xAF,0xF7,0xFF,0xFF,
-0xFF,0xEB,0xFF,0xFF,0xFF,0xAF,0xFF,0xC4,
-0xFF,0xF7,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,
-0xFF,0x5F,0xFF,0xFF,0xFF,0xFF,0xD7,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,0xFB,0x7A,
-0xDF,0xF7,0xFD,0xFF,0xFF,0xFE,0xBF,0xFF,
-0xFF,0x7F,0xFF,0xAF,0xFF,0xFF,0xFF,0xF7,
-0xEF,0xE3,0xFF,0xDD,0xD2,0xFF,0xDF,0xFF,
-0xFF,0xF2,0xFC,0xBF,0xCB,0xF6,0xFD,0xBF,
-0x2F,0xCB,0xFF,0x7F,0xDF,0xDE,0xAF,0xFF,
-0xDA,0xEE,0xBF,0xAF,0xE9,0xFA,0xF4,0xBD,
-0xAF,0x5A,0xAE,0xBB,0xAB,0x6B,0xDA,0xDE,
-0xBF,0xAD,0xD7,0x5E,0xFF,0xFF,0xBF,0xFC,
-0xFF,0xDF,0xFD,0xFF,0xFF,0xFF,0xFF,0xDF,
-0xF7,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFA,
-0x1F,0xFF,0xFE,0xFB,0xEF,0xBF,0xFD,0xFF,
-0xFD,0xBD,0x77,0xFF,0xFF,0xFF,0xFF,0x9D,
-0xEF,0xFF,0xFF,0xFF,0xEF,0x7D,0xFF,0xFB,
-0xFE,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEE,
-0xBF,0xE4,0xFB,0xFF,0xFE,0x3F,0xFE,0xFF,
-0xFF,0xFF,0xFF,0xAF,0xEA,0xFE,0xBF,0xAF,
-0xEB,0xFA,0xFE,0xFF,0xFF,0xFF,0x55,0xF6,
-0xFF,0xFE,0xF7,0xFF,0x7F,0xFF,0xEB,0xF7,
-0x5F,0xC5,0xFD,0x7F,0x5F,0xD7,0xF5,0xFF,
-0x6F,0xFB,0xFF,0x8A,0xFF,0xFF,0xFF,0xFF,
-0xEB,0xFF,0xFF,0xFF,0xFF,0xFB,0xBF,0xBF,
-0xEF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,
-0x77,0xDF,0xFB,0xFF,0xFD,0x7F,0xEF,0xFF,
-0xFF,0xFF,0xBF,0x7F,0xFF,0xDF,0xBF,0xFF,
-0xFB,0xFF,0xFF,0xFF,0xFE,0xEF,0xDF,0xFF,
-0xFE,0xFF,0x9F,0xEF,0x7D,0xFF,0xF7,0xFF,
-0x7F,0xFF,0xFF,0xDF,0xF7,0xFD,0xFF,0xEF,
-0xDF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFB,
-0xFD,0xFF,0xBF,0xDF,0xD1,0xFF,0xF8,0x3B,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0x7E,0xDB,0xFD,0xFF,0x77,0xDB,0xB7,0x7D,
-0xBF,0xFB,0xFF,0xF8,0x7F,0xED,0x7B,0x5E,
-0xFF,0xFE,0xFF,0xFF,0x4F,0xD7,0xFD,0x7F,
-0xDF,0xD7,0xF5,0xFF,0x7F,0xFF,0xFF,0xFF,
-0xF2,0x3F,0xFE,0xFF,0xBF,0xFF,0xFF,0xFF,
-0xFF,0xBF,0xEF,0xFE,0xFF,0x3B,0xEE,0xFF,
-0xFC,0xEF,0xFF,0xFF,0xFF,0x85,0xFF,0xFD,
-0xFE,0xFF,0xF5,0xFF,0xFF,0xFE,0xFF,0xDF,
-0xFB,0xFF,0x5F,0xBF,0xFF,0xFD,0xFF,0xFF,
-0xFF,0xFF,0xA8,0xFF,0xFF,0x9F,0x9E,0xFF,
-0xFF,0xFF,0x7F,0xF3,0xFF,0xFF,0xCF,0xFF,
-0xF7,0xFD,0xFF,0x7F,0xFF,0xFF,0xFC,0x16,
-0xBF,0xCF,0xA3,0xE5,0xEF,0x7F,0xFF,0xF3,
-0xE4,0xFF,0xCF,0x93,0xFC,0xFF,0x3F,0xCF,
-0xFF,0xFF,0xFF,0xD6,0x0F,0x7D,0xBF,0x6E,
-0xFB,0xF4,0xFC,0xAF,0x6D,0xDB,0x77,0xB7,
-0x6D,0xDB,0xF6,0xFD,0xBF,0xFF,0xFF,0xFF,
-0xBF,0x9B,0xFA,0xDE,0xB7,0xB7,0xED,0xF9,
-0x7E,0xB7,0xAC,0xEB,0xD6,0xB3,0xAD,0xEB,
-0x7A,0xDF,0xFF,0xFF,0xFF,0xD8,0xBF,0xFF,
-0xB7,0xED,0x9F,0x6F,0xDD,0xF7,0x68,0xDB,
-0x37,0xB3,0x6C,0xDB,0x36,0xCD,0xB3,0x7F,
-0xFF,0x7F,0xF5,0x6F,0xFD,0xEF,0x79,0x3D,
-0xF7,0x93,0xE4,0x7A,0x9E,0xAD,0xEA,0x7A,
-0x9E,0xF7,0xBD,0xEF,0xFF,0xFF,0xFF,0x76,
-0x7F,0xFB,0xC6,0xFF,0xBB,0xEF,0xDA,0xFE,
-0xFD,0xBF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,
-0xFF,0xFF,0xFB,0xFF,0xA5,0xFF,0xFD,0xAB,
-0x6F,0x78,0xDE,0x17,0x8F,0x79,0xDF,0xFD,
-0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0xFF,0xFB,
-0xFF,0xFB,0xFF,0xEF,0xFB,0xEF,0xFB,0xFE,
-0xFF,0xBB,0xDA,0xF3,0xEF,0x3B,0xCE,0xF3,
-0xBC,0xEF,0x3F,0xCF,0xDF,0xFF,0xB7,0xFF,
-0xFF,0xFF,0xCF,0x73,0xFF,0xBF,0xEF,0xFF,
-0xF3,0xFF,0x3F,0xCF,0xF3,0xFC,0xFF,0x3D,
-0xCF,0x9F,0xFE,0x07,0xFF,0xAF,0xEB,0xFE,
-0xFD,0xBF,0xEF,0xEB,0xFA,0xFF,0xAF,0xEB,
-0xFA,0xFE,0xBF,0xAF,0xFB,0xFE,0x3F,0xFB,
-0x9B,0xFF,0x7F,0xDF,0xFF,0xF3,0xFE,0xFF,
-0xDE,0xF7,0xBF,0x7B,0xDE,0xF7,0xBD,0xEF,
-0x7B,0xFE,0xFF,0xFF,0xDF,0x3F,0xFE,0xFF,
-0xB7,0xFF,0xEF,0xF7,0xFF,0xBF,0xED,0xFE,
-0xDF,0xB7,0xED,0xFB,0x7E,0xDF,0xFF,0xFF,
-0xFF,0xFD,0x5F,0xEF,0xEB,0xFA,0xFE,0xF5,
-0xBF,0x6F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFE,0xF8,0xFF,0xA8,0xFF,
-0xFF,0xBF,0xEF,0xFB,0x6A,0xFB,0xB7,0xEF,
-0xFB,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,
-0xEF,0xFB,0xFF,0xE0,0xFF,0xFF,0xFD,0x7F,
-0x5C,0xD7,0x7D,0xDF,0xF3,0x5C,0xF5,0xCD,
-0x73,0x5E,0xD7,0xB5,0xFD,0x7F,0xEF,0xFF,
-0xDB,0xFF,0xFF,0xE2,0xF8,0xBE,0x2F,0x8F,
-0xE7,0xF8,0xBE,0x6B,0xE2,0xF8,0xBE,0x2F,
-0x8B,0xE2,0xF9,0xFE,0x7F,0xE7,0xFF,0xD7,
-0xF5,0xFD,0x7F,0xFF,0xF7,0xF5,0xFD,0x7F,
-0xD7,0xF5,0xFD,0x7F,0x5F,0xD7,0xF5,0xFF,
-0xFF,0xFF,0x8F,0xFF,0xAF,0xEB,0xFA,0xFF,
-0xFF,0xBF,0xEB,0xFA,0xFF,0x2F,0xEB,0xFA,
-0xFE,0xBF,0xAF,0xEB,0xFF,0xFF,0xFE,0x5F,
-0xFF,0x5F,0xFF,0xFF,0xFD,0xFF,0xFF,0xD7,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xBF,0xFE,0xB7,0xFD,
-0xFF,0x7E,0xDF,0xF7,0xAD,0xFF,0x7F,0xF7,
-0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,
-0xF6,0x7F,0xFF,0xFF,0xFF,0xDB,0xF6,0xFC,
-0xAF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xEC,0xBF,0xFF,
-0xAF,0xEB,0xFA,0xF6,0xAB,0x8F,0xEB,0xFA,
-0xF7,0xA5,0xEB,0xFA,0xBE,0xBF,0xAF,0xEB,
-0xFA,0xFF,0x6D,0xFF,0xFF,0x7F,0xDF,0x33,
-0xDD,0xFF,0x7F,0xFE,0xF7,0xFC,0x7F,0xFB,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA9,
-0xFF,0xFD,0xFF,0xFF,0xFE,0xFF,0xFF,0xDF,
-0xFF,0xFF,0xEF,0xEF,0xFD,0xFF,0x7F,0xFF,
-0xFF,0xFF,0xFF,0xFE,0xA7,0xFF,0xFF,0xFF,
-0x77,0xDF,0xF7,0xFD,0x9F,0x7F,0xFE,0x77,
-0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xAF,0xBF,0xAF,0xFF,0xF9,0xBE,0xBF,
-0x8F,0xFB,0xFE,0xFE,0xEF,0xFB,0xFE,0xFF,
-0xBF,0xEF,0xFB,0xFF,0xFF,0xFD,0xDF,0x6F,
-0xEF,0xFF,0x7F,0xFF,0xBF,0xBF,0xDF,0xFF,
-0xFC,0xFF,0xDF,0xF7,0xFD,0xEF,0x7F,0xDF,
-0xFF,0xFF,0xFF,0x3F,0xF6,0xFF,0xCF,0xFF,
-0xDB,0xFB,0xF7,0xFF,0xEB,0x7A,0xFF,0xFF,
-0xFF,0xBF,0xEF,0xFB,0xFF,0xFF,0xFF,0xFE,
-0x6D,0xFD,0xFF,0x5F,0xFB,0xFF,0xFF,0xF7,
-0xFF,0x5F,0xF5,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xF8,0xFF,0xFB,0xFF,
-0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xE7,0xF6,
-0xBF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,
-0xFF,0xC9,0xFF,0xFF,0xFF,0xBD,0xFF,0xBF,
-0xAF,0xEF,0xEF,0x3F,0xD1,0xFC,0x7F,0xFB,
-0xC7,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3,0xFF,
-0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0x77,0xFF,
-0xDF,0xB7,0xFD,0xF7,0xFD,0xF7,0xFF,0xFF,
-0xFF,0xFF,0xFF,0x57,0xFF,0xF7,0xA5,0xFD,
-0x3F,0xDF,0xBF,0xBF,0xFE,0x7F,0xFF,0xFF,
-0xFF,0xDF,0xFA,0xFD,0xFF,0xFF,0xFF,0xFE,
-0x87,0xFF,0xE9,0xFF,0xFE,0xEF,0xBF,0xEF,
-0xFE,0xFE,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFA,0x9F,0xFF,0x3F,
-0xFF,0xFD,0xFD,0x57,0xDF,0xFD,0xF3,0xFF,
-0xDF,0xFD,0xFF,0x5F,0xDF,0xF5,0xFD,0xFF,
-0xFF,0xF9,0x8F,0xFF,0xFF,0xFF,0xEE,0x7F,
-0xFF,0xFF,0xBF,0x5E,0xFE,0xEC,0xFB,0x3F,
-0x7F,0x9F,0xEF,0xF9,0xFF,0xFF,0xCD,0x6B,
-0xFF,0xFF,0xFF,0xC5,0xF3,0xFC,0xFA,0x38,
-0xFF,0xAF,0x3F,0xEE,0x7F,0x9F,0xFF,0xD9,
-0xFF,0xFF,0xFD,0x7A,0xF7,0xFF,0xF3,0xFF,
-0xAF,0x6F,0xDB,0xF2,0xB9,0xE9,0xFB,0xFF,
-0xFF,0xFF,0xFE,0xFF,0xFF,0xEF,0xFF,0xFB,
-0xC5,0xBF,0xFF,0xEF,0xFF,0x5E,0xB7,0xAD,
-0xCD,0x79,0x7C,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFD,0x93,0xFF,0xEF,
-0xEA,0xFE,0xBF,0xEF,0x5B,0xD2,0xCD,0xF5,
-0x6D,0x77,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,
-0xFF,0xFF,0x66,0xFF,0xD5,0x65,0x7D,0x5F,
-0x75,0x9D,0x65,0x7F,0xD6,0xFB,0x4F,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xC7,
-0xFF,0xBF,0xEF,0xFA,0xFE,0xFF,0xBF,0xEB,
-0xFF,0xDF,0xFF,0x7E,0xFF,0xFF,0xEF,0xFD,
-0x7E,0xD7,0xFF,0x78,0xDF,0xFF,0x5F,0xDF,
-0xF5,0xBF,0x7F,0xDF,0xC5,0xFF,0x3F,0xF6,
-0x7E,0xFF,0x0F,0xEF,0xF2,0x3E,0xBF,0xFF,
-0xFB,0x3F,0xFF,0xFB,0x7F,0xFF,0xB3,0xFE,
-0xFB,0xF6,0xFD,0xFF,0xDA,0xF7,0xFD,0xFF,
-0x7F,0xDF,0xF7,0xBF,0xFF,0xFA,0x7F,0xFF,
-0xFF,0xFF,0xFF,0x9F,0xFF,0xF3,0xDC,0xF9,
-0xBF,0xCE,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,
-0xFF,0xFF,0xE2,0x7F,0xFE,0xFF,0xBF,0xEF,
-0xEB,0xFA,0xFF,0x9F,0x67,0x1E,0xFF,0x8F,
-0xE7,0xF8,0xFE,0x7F,0x8F,0xEF,0xFF,0xBD,
-0xBF,0xFF,0xFB,0xFF,0xFF,0xDF,0xF7,0xFF,
-0xFC,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFD,0xB3,0xFF,0xFF,0xEF,
-0xFF,0xFF,0xBF,0xED,0xFF,0xFB,0xEE,0xFE,
-0xFF,0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xFF,
-0xFF,0xB5,0xFF,0xB7,0xFD,0xFD,0x6E,0xFF,
-0xFF,0xFE,0xFD,0x2F,0xD8,0xFE,0xBF,0x8F,
-0xEB,0xF9,0xFE,0x3F,0xFF,0xFA,0xCF,0xFF,
-0xE7,0xD9,0xFA,0xBF,0xDF,0x77,0xFC,0xFB,
-0x3F,0xAB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFE,
-0xFF,0xFF,0xEE,0x1F,0xFF,0xDF,0xF7,0xFF,
-0xFF,0xFF,0x5F,0x97,0x35,0xBF,0x5E,0xFE,
-0xBF,0xEF,0xFF,0xF7,0xFD,0xFF,0xFF,0xFA,
-0xBF,0xFF,0xBE,0x6F,0x9F,0xE7,0xF8,0xBE,
-0x2F,0x8B,0x66,0x94,0x7D,0x9D,0xE7,0xF9,
-0xFE,0x7F,0x9F,0xE7,0xF1,0x7F,0xFF,0xFF,
-0xFF,0xF7,0xF5,0xFD,0x7F,0x5F,0xFB,0xFD,
-0x9E,0xFF,0xFB,0xFE,0xFF,0xFF,0xEF,0xFF,
-0xFF,0xA0,0xFF,0xFF,0xFF,0xBF,0xEF,0xEB,
-0xFA,0xFE,0xBF,0xB7,0xF7,0xF7,0xFF,0xFF,
-0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF,
-0xFD,0xFF,0xFF,0xFF,0xD7,0xFF,0xFF,0xFF,
-0x7F,0xF5,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,
-0xBF,0xFF,0xFF,0xAB,0xFE,0xFB,0xFE,0xFF,
-0xF7,0xAF,0xFF,0xFF,0xDE,0xF7,0xEB,0x5F,
-0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,0xFF,
-0xB3,0xFF,0xC9,0xFE,0xFF,0xFF,0xFF,0xFF,
-0xD6,0xFF,0xFF,0xCB,0xFF,0xFF,0xDF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFC,0x8F,0xFF,0xBA,
-0xBE,0xBF,0xAF,0xEB,0x78,0xFE,0xB7,0xAD,
-0x3A,0xFE,0xB7,0xAF,0xEB,0x7A,0xFE,0xBF,
-0xAF,0xFF,0x9F,0xFF,0xFF,0xDF,0xFC,0xFF,
-0xFF,0xFE,0xC3,0xFE,0xFF,0xFF,0x33,0xFC,
-0xFF,0xBF,0xDF,0xF3,0xFF,0xFF,0xBB,0x9F,
-0xFF,0xFF,0xFF,0xEB,0xDF,0xFF,0xFF,0xAF,
-0xF7,0x6F,0xF9,0xBF,0xEF,0xFD,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xE3,0x7F,0xFF,0xFF,0xFF,
-0xFB,0xFF,0xFF,0xBF,0xFD,0xFB,0xF7,0xFF,
-0xDF,0xF7,0xFF,0xFE,0xEF,0x5F,0xBD,0xFF,
-0xFA,0xFF,0xF8,0xFF,0xBF,0xAF,0xFB,0xFE,
-0xFE,0x3F,0xEF,0xE8,0xFF,0xDF,0xF3,0xFD,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xED,0xFF,0xFB,
-0xFD,0xFF,0xAF,0xFF,0xFF,0xFE,0xFE,0xBF,
-0xDB,0xFF,0xFF,0xFF,0xBF,0xFF,0xDF,0xFF,
-0xFD,0xFF,0xCB,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xBF,0x6F,0xFF,0x7F,0xB7,0xB3,0xFF,0xFF,
-0xDF,0xFF,0xFB,0xEF,0xFF,0xFF,0xFF,0x07,
-0xFF,0xFB,0xFF,0xFF,0xFF,0xED,0xFF,0xF5,
-0x7C,0xFF,0x7F,0xFE,0xFF,0xFF,0xEF,0xCF,
-0xFF,0xFB,0xFF,0xFF,0x2F,0xFF,0xFF,0xFF,
-0xFF,0xF3,0xFF,0xFB,0xFF,0xFE,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,
-0xFD,0x1B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFE,0x7C,0xFF,0xFF,0xFF,0xFF,
-0xEF,0xFF,0xFF,0xFF,0xFF,0xFB,0xBF,0x7F,
-0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,
-0xFF,0xFF,0xF0,0x7F,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xDF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,0xFE,
-0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xEF,0xFE,0xFF,0xBF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xEF,0xFA,0xB5,0xFF,0xFF,0xFF,
-0xF7,0xF7,0xFF,0xFF,0xFF,0xFF,0xDF,0xFB,
-0xFC,0xFF,0xFF,0xFE,0xFF,0x7F,0xDF,0xBF,
-0xFF,0xCB,0xBF,0xF9,0xFE,0x7F,0x9F,0xE7,
-0xF9,0xFE,0x7F,0x97,0xE1,0xFE,0x79,0x9F,
-0xE7,0xFD,0xFE,0x7F,0xDF,0xFE,0x37,0xFF,
-0xFB,0xDE,0xDE,0xBD,0xEF,0xF3,0xFE,0xFB,
-0xAF,0xEB,0xFE,0xFF,0xFF,0xCF,0xFF,0xFE,
-0xFF,0xBF,0xFF,0x8F,0xFF,0xEF,0xFB,0xFE,
-0xFF,0xBF,0xE7,0xF9,0x5E,0x7F,0xEF,0xFB,
-0xDA,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFD,
-0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,
-0xFF,0xFF,0x7F,0xFF,0xFF,0xF7,0xFB,0x7F,
-0xFF,0xFF,0xFF,0xFF,0xFC,0x3F,0xFF,0xBF,
-0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0x7B,0x7F,
-0xBF,0xEF,0xFB,0xFE,0xFF,0xB5,0xEF,0xFB,
-0xBF,0xFA,0x7F,0xFC,0xFF,0x3F,0xCF,0xF3,
-0xFC,0xFF,0x3F,0xCF,0xBC,0xFF,0x3F,0xEF,
-0xF3,0xFC,0xFE,0x3F,0xCF,0xFF,0xEE,0xEF,
-0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0x6A,0xD7,
-0xB7,0xFB,0xF8,0xFF,0xB7,0xEF,0xBA,0xFE,
-0xFF,0xBF,0x7F,0xE9,0xFF,0xF9,0x7E,0x5F,
-0x97,0xE5,0xF9,0xFE,0x7F,0xBF,0xF9,0x7E,
-0x5F,0x9F,0xE5,0xFB,0xFE,0x5F,0xB7,0xFF,
-0xA3,0xFF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7,
-0xFD,0xFF,0x5E,0xF7,0x7D,0xFF,0x77,0xDF,
-0xF7,0xFD,0xFF,0x7F,0xFF,0xD7,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFD,0xDF,0xFB,0x7F,
-0xFF,0xFF,0xEF,0xFF,0xFE,0xFB,0xFF,0xFF,
-0xBF,0xFE,0x8F,0xFF,0xDF,0xF7,0xFD,0xFD,
-0x7F,0xDF,0xF7,0xFD,0x3E,0xDF,0xF5,0xBD,
-0xFF,0x7F,0xDF,0xF7,0xFD,0xF7,0xFF,0x9F,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFD,0xFF,0xBE,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFD,0x3F,0xFF,0xDF,0xF7,
-0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0xCF,
-0x77,0xFC,0xFF,0x5F,0xDF,0xF7,0xFD,0xFF,
-0xF4,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFD,0xFF,0xFF,0xFF,0xEE,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xED,0xFB,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xE9,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFB,0xFF,0xFF,0xFF,0xD3,0xFF,0xFF,
-0xBF,0x3F,0xFB,0xFF,0xFF,0xFF,0xFB,0xF3,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xF7,
-0xFF,0xFF,0xFF,0xFF,0x17,0xFF,0xFF,0xFF,
-0xDF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xDF,0xDF,0xFF,0xFD,0xFF,0xFF,0xDF,0xF7,
-0xFF,0x4F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFD,
-0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0x9F,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
-0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,
-0xFF,0xFF,0x7A,0x3F,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF2,
-0x7F,0xFF,0xFB,0xFE,0xFF,0xBF,0xEF,0xF8,
-0xFE,0xFF,0xBF,0xFB,0xFE,0xFF,0x8F,0xEC,
-0xFB,0xFE,0xFF,0xBF,0xF8,0xF7,0xFE,0xFF,
-0xBF,0xEF,0xFB,0xFE,0xFD,0xBF,0xCF,0xEC,
-0xFF,0x3F,0xEF,0xDB,0xF8,0xFF,0xBF,0xCF,
-0xFF,0xF9,0xFF,0xFF,0xBF,0xFF,0xFB,0xFF,
-0xFF,0xFF,0xEF,0xFB,0xDF,0xFF,0xFF,0xFF,
-0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xBB,0xFF,
-0xEF,0xFB,0xFE,0xEF,0xBF,0xEE,0xEB,0xFB,
-0xFE,0xFF,0xEF,0xFE,0xEE,0xBF,0xFE,0xEB,
-0xFF,0xEF,0xFF,0x17,0xFF,0x7E,0xEB,0xBB,
-0xFE,0xBF,0xBE,0xFB,0xEF,0x5B,0xF7,0xBD,
-0xFB,0xCF,0xBF,0xBF,0xBB,0xFB,0x7E,0xCC,
-0xEF,0xFF
-};
diff --git a/drivers/usb/dabfirmware.h b/drivers/usb/dabfirmware.h
new file mode 100644
index 000000000..d14d80356
--- /dev/null
+++ b/drivers/usb/dabfirmware.h
@@ -0,0 +1,1408 @@
+/*
+ * dabdata.h - dab usb firmware and bitstream data
+ */
+
+static INTEL_HEX_RECORD firmware[] = {
+
+{ 2, 0x0000, 0, {0x21,0x57} },
+{ 3, 0x0003, 0, {0x02,0x01,0x66} },
+{ 3, 0x000b, 0, {0x02,0x01,0x66} },
+{ 3, 0x0013, 0, {0x02,0x01,0x66} },
+{ 3, 0x001b, 0, {0x02,0x01,0x66} },
+{ 3, 0x0023, 0, {0x02,0x01,0x66} },
+{ 3, 0x002b, 0, {0x02,0x01,0x66} },
+{ 3, 0x0033, 0, {0x02,0x03,0x0f} },
+{ 3, 0x003b, 0, {0x02,0x01,0x66} },
+{ 3, 0x0043, 0, {0x02,0x01,0x00} },
+{ 3, 0x004b, 0, {0x02,0x01,0x66} },
+{ 3, 0x0053, 0, {0x02,0x01,0x66} },
+{ 3, 0x005b, 0, {0x02,0x04,0xbd} },
+{ 3, 0x0063, 0, {0x02,0x01,0x67} },
+{ 3, 0x0100, 0, {0x02,0x0c,0x5a} },
+{ 3, 0x0104, 0, {0x02,0x01,0xed} },
+{ 3, 0x0108, 0, {0x02,0x02,0x51} },
+{ 3, 0x010c, 0, {0x02,0x02,0x7c} },
+{ 3, 0x0110, 0, {0x02,0x02,0xe4} },
+{ 1, 0x0114, 0, {0x32} },
+{ 1, 0x0118, 0, {0x32} },
+{ 3, 0x011c, 0, {0x02,0x05,0xfd} },
+{ 3, 0x0120, 0, {0x02,0x00,0x00} },
+{ 3, 0x0124, 0, {0x02,0x00,0x00} },
+{ 3, 0x0128, 0, {0x02,0x04,0x3c} },
+{ 3, 0x012c, 0, {0x02,0x04,0x6a} },
+{ 3, 0x0130, 0, {0x02,0x00,0x00} },
+{ 3, 0x0134, 0, {0x02,0x00,0x00} },
+{ 3, 0x0138, 0, {0x02,0x00,0x00} },
+{ 3, 0x013c, 0, {0x02,0x00,0x00} },
+{ 3, 0x0140, 0, {0x02,0x00,0x00} },
+{ 3, 0x0144, 0, {0x02,0x00,0x00} },
+{ 3, 0x0148, 0, {0x02,0x00,0x00} },
+{ 3, 0x014c, 0, {0x02,0x00,0x00} },
+{ 3, 0x0150, 0, {0x02,0x00,0x00} },
+{ 3, 0x0154, 0, {0x02,0x00,0x00} },
+{ 10, 0x0157, 0, {0x75,0x81,0x7f,0xe5,0x82,0x60,0x03,0x02,0x01,0x61} },
+{ 5, 0x0161, 0, {0x12,0x07,0x6f,0x21,0x64} },
+{ 1, 0x0166, 0, {0x32} },
+{ 14, 0x0167, 0, {0xc0,0xd0,0xc0,0x86,0xc0,0x82,0xc0,0x83,0xc0,0xe0,0x90,0x7f,0x97,0xe0} },
+{ 14, 0x0175, 0, {0x44,0x80,0xf0,0x90,0x7f,0x69,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} },
+{ 14, 0x0183, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} },
+{ 14, 0x0191, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x90,0x7f,0x97,0xe0} },
+{ 3, 0x019f, 0, {0x55,0x7f,0xf0} },
+{ 14, 0x01a2, 0, {0x90,0x7f,0x9a,0xe0,0x30,0xe4,0x23,0x90,0x7f,0x68,0xf0,0xf0,0xf0,0xf0} },
+{ 14, 0x01b0, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} },
+{ 14, 0x01be, 0, {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0} },
+{ 14, 0x01cc, 0, {0xe5,0xd8,0xc2,0xe3,0xf5,0xd8,0xd0,0xe0,0xd0,0x83,0xd0,0x82,0xd0,0x86} },
+{ 3, 0x01da, 0, {0xd0,0xd0,0x32} },
+{ 8, 0x01dd, 0, {0x75,0x86,0x00,0x90,0xff,0xc3,0x7c,0x05} },
+{ 7, 0x01e5, 0, {0xa3,0xe5,0x82,0x45,0x83,0x70,0xf9} },
+{ 1, 0x01ec, 0, {0x22} },
+{ 14, 0x01ed, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0xd0} },
+{ 14, 0x01fb, 0, {0x75,0xd0,0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91} },
+{ 13, 0x0209, 0, {0x90,0x88,0x00,0xe0,0xf5,0x41,0x90,0x7f,0xab,0x74,0x02,0xf0,0x90} },
+{ 9, 0x0216, 0, {0x7f,0xab,0x74,0x02,0xf0,0xe5,0x32,0x60,0x21} },
+{ 4, 0x021f, 0, {0x7a,0x00,0x7b,0x00} },
+{ 11, 0x0223, 0, {0xc3,0xea,0x94,0x18,0xeb,0x64,0x80,0x94,0x80,0x50,0x12} },
+{ 14, 0x022e, 0, {0x90,0x7f,0x69,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x0a,0xba,0x00} },
+{ 2, 0x023c, 0, {0x01,0x0b} },
+{ 2, 0x023e, 0, {0x80,0xe3} },
+{ 2, 0x0240, 0, {0xd0,0x86} },
+{ 14, 0x0242, 0, {0xd0,0xd0,0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0} },
+{ 1, 0x0250, 0, {0x32} },
+{ 14, 0x0251, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
+{ 14, 0x025f, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xab,0x74} },
+{ 4, 0x026d, 0, {0x04,0xf0,0xd0,0x86} },
+{ 11, 0x0271, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
+{ 14, 0x027c, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} },
+{ 14, 0x028a, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} },
+{ 13, 0x0298, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} },
+{ 12, 0x02a5, 0, {0x7f,0xab,0x74,0x08,0xf0,0x75,0x6e,0x00,0x75,0x6f,0x02,0x12} },
+{ 6, 0x02b1, 0, {0x11,0x44,0x75,0x70,0x39,0x75} },
+{ 6, 0x02b7, 0, {0x71,0x0c,0x75,0x72,0x02,0x12} },
+{ 12, 0x02bd, 0, {0x11,0x75,0x90,0x7f,0xd6,0xe4,0xf0,0x75,0xd8,0x20,0xd0,0x86} },
+{ 14, 0x02c9, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} },
+{ 13, 0x02d7, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
+{ 14, 0x02e4, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
+{ 14, 0x02f2, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xab,0x74} },
+{ 4, 0x0300, 0, {0x10,0xf0,0xd0,0x86} },
+{ 11, 0x0304, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
+{ 14, 0x030f, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} },
+{ 14, 0x031d, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} },
+{ 12, 0x032b, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0x75,0x6e,0x00,0x75,0x6f,0x02} },
+{ 7, 0x0337, 0, {0x12,0x11,0x44,0x75,0x70,0x40,0x75} },
+{ 6, 0x033e, 0, {0x71,0x0c,0x75,0x72,0x02,0x12} },
+{ 14, 0x0344, 0, {0x11,0x75,0x90,0x7f,0xd6,0x74,0x02,0xf0,0x90,0x7f,0xd6,0x74,0x06,0xf0} },
+{ 5, 0x0352, 0, {0x75,0xd8,0x10,0xd0,0x86} },
+{ 14, 0x0357, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} },
+{ 13, 0x0365, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
+{ 13, 0x0372, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x90,0x7f,0xa6,0x74,0x9a,0xf0,0x12} },
+{ 12, 0x037f, 0, {0x10,0x1b,0x90,0x7f,0xa6,0xe5,0x42,0xf0,0x12,0x10,0x1b,0x90} },
+{ 13, 0x038b, 0, {0x7f,0xa6,0xe5,0x43,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa5,0x74,0x40} },
+{ 1, 0x0398, 0, {0xf0} },
+{ 1, 0x0399, 0, {0x22} },
+{ 13, 0x039a, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x90,0x7f,0xa6,0x74,0x9a,0xf0,0x12} },
+{ 12, 0x03a7, 0, {0x10,0x1b,0x90,0x7f,0xa6,0xe5,0x44,0xf0,0x12,0x10,0x1b,0x90} },
+{ 12, 0x03b3, 0, {0x7f,0xa6,0xe5,0x45,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa6,0xe5} },
+{ 11, 0x03bf, 0, {0x46,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa5,0x74,0x40,0xf0} },
+{ 1, 0x03ca, 0, {0x22} },
+{ 10, 0x03cb, 0, {0x75,0x44,0x02,0x75,0x45,0x00,0x75,0x46,0x00,0x12} },
+{ 9, 0x03d5, 0, {0x03,0x9a,0x75,0x42,0x03,0x75,0x43,0x00,0x12} },
+{ 2, 0x03de, 0, {0x03,0x72} },
+{ 1, 0x03e0, 0, {0x22} },
+{ 12, 0x03e1, 0, {0x90,0x88,0x00,0xe5,0x36,0xf0,0x90,0x88,0x00,0x74,0x10,0x25} },
+{ 9, 0x03ed, 0, {0x36,0xf0,0x12,0x01,0xdd,0x75,0x42,0x01,0x75} },
+{ 9, 0x03f6, 0, {0x43,0x18,0x12,0x03,0x72,0x75,0x44,0x02,0x75} },
+{ 9, 0x03ff, 0,{0x45,0x00,0x75,0x46,0x00,0x12,0x03,0x9a,0x75} },
+{ 8, 0x0408, 0,{0x42,0x03,0x75,0x43,0x44,0x12,0x03,0x72} },
+{ 1, 0x0410, 0,{0x22} },
+{ 14, 0x0411, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
+{ 14, 0x041f, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xaa,0x74} },
+{ 4, 0x042d, 0, {0x02,0xf0,0xd0,0x86} },
+{ 11, 0x0431, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
+{ 14, 0x043c, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
+{ 14, 0x044a, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xa9,0x74} },
+{ 7, 0x0458, 0, {0x04,0xf0,0x75,0x30,0x01,0xd0,0x86} },
+{ 11, 0x045f, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
+{ 14, 0x046a, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
+{ 14, 0x0478, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xaa,0x74} },
+{ 7, 0x0486, 0, {0x04,0xf0,0x75,0x31,0x01,0xd0,0x86} },
+{ 11, 0x048d, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
+{ 14, 0x0498, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
+{ 12, 0x04a6, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe5,0xf5,0x91,0xd0,0x86} },
+{ 11, 0x04b2, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
+{ 14, 0x04bd, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0} },
+{ 12, 0x04cb, 0, {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe7,0xf5,0x91,0xd0,0x86} },
+{ 11, 0x04d7, 0, {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
+{ 12, 0x04e2, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x8a,0x20,0x90,0x7f,0x96,0xe4,0xf0} },
+{ 1, 0x04ee, 0, {0x22} },
+{ 7, 0x04ef, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x8a,0x21} },
+{ 1, 0x04f6, 0, {0x22} },
+{ 14, 0x04f7, 0, {0x90,0x17,0x13,0xe0,0xfa,0x90,0x17,0x15,0xe0,0xfb,0x74,0x80,0x2a,0xfa} },
+{ 14, 0x0505, 0, {0x74,0x80,0x2b,0xfb,0xea,0x03,0x03,0x54,0x3f,0xfc,0xea,0xc4,0x23,0x54} },
+{ 14, 0x0513, 0, {0x1f,0xfa,0x2c,0xfa,0xeb,0x03,0x03,0x54,0x3f,0xfc,0xeb,0xc4,0x23,0x54} },
+{ 11, 0x0521, 0, {0x1f,0xfb,0x2c,0xfb,0x90,0x17,0x0a,0xe0,0xfc,0x60,0x02} },
+{ 2, 0x052c, 0, {0x7a,0x00} },
+{ 7, 0x052e, 0, {0x90,0x17,0x0c,0xe0,0xfc,0x60,0x02} },
+{ 2, 0x0535, 0, {0x7b,0x00} },
+{ 11, 0x0537, 0, {0xea,0x2b,0xfc,0xc3,0x13,0xf5,0x3a,0x75,0x44,0x02,0x8b} },
+{ 7, 0x0542, 0, {0x45,0x8a,0x46,0x12,0x03,0x9a,0x75} },
+{ 9, 0x0549, 0, {0x6e,0x08,0x75,0x6f,0x00,0x12,0x11,0x44,0x75} },
+{ 4, 0x0552, 0, {0x70,0x47,0x75,0x71} },
+{ 8, 0x0556, 0, {0x0c,0x75,0x72,0x02,0x12,0x11,0x75,0x85} },
+{ 5, 0x055e, 0, {0x3a,0x73,0x12,0x11,0xa0} },
+{ 1, 0x0563, 0, {0x22} },
+{ 14, 0x0564, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x65,0x02,0xf0,0x90} },
+{ 14, 0x0572, 0, {0x7f,0xeb,0xe0,0xfa,0x90,0x7f,0xea,0xe0,0xfb,0x90,0x7f,0xef,0xe0,0xfc} },
+{ 14, 0x0580, 0, {0x33,0x95,0xe0,0xfd,0x8c,0x05,0x7c,0x00,0x90,0x7f,0xee,0xe0,0xfe,0x33} },
+{ 14, 0x058e, 0, {0x95,0xe0,0xff,0xec,0x2e,0xfc,0xed,0x3f,0xfd,0x90,0x7f,0xe9,0xe0,0xfe} },
+{ 5, 0x059c, 0, {0xbe,0x01,0x02,0x80,0x03} },
+{ 3, 0x05a1, 0, {0x02,0x05,0xf9} },
+{ 6, 0x05a4, 0, {0xbc,0x01,0x21,0xbd,0x00,0x1e} },
+{ 14, 0x05aa, 0, {0xea,0xc4,0x03,0x54,0xf8,0xfc,0xeb,0x25,0xe0,0xfd,0x2c,0x24,0x00,0xfc} },
+{ 14, 0x05b8, 0, {0xe4,0x34,0x17,0xfd,0x90,0x7e,0xc0,0xe0,0xfe,0x8c,0x82,0x8d,0x83,0xf0} },
+{ 2, 0x05c6, 0, {0x80,0x31} },
+{ 14, 0x05c8, 0, {0xea,0xc4,0x03,0x54,0xf8,0xfa,0xeb,0x25,0xe0,0xfb,0x2a,0xfa,0x24,0x00} },
+{ 14, 0x05d6, 0, {0xfb,0xe4,0x34,0x17,0xfc,0x90,0x7e,0xc0,0xe0,0xfd,0x8b,0x82,0x8c,0x83} },
+{ 14, 0x05e4, 0, {0xf0,0x74,0x01,0x2a,0x24,0x00,0xfa,0xe4,0x34,0x17,0xfb,0x90,0x7e,0xc1} },
+{ 7, 0x05f2, 0, {0xe0,0xfc,0x8a,0x82,0x8b,0x83,0xf0} },
+{ 3, 0x05f9, 0, {0x75,0x38,0x01} },
+{ 1, 0x05fc, 0, {0x22} },
+{ 14, 0x05fd, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} },
+{ 14, 0x060b, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} },
+{ 13, 0x0619, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} },
+{ 13, 0x0626, 0, {0x7f,0xaa,0x74,0x01,0xf0,0x12,0x05,0x64,0x75,0x37,0x00,0xd0,0x86} },
+{ 14, 0x0633, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} },
+{ 13, 0x0641, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
+{ 14, 0x064e, 0, {0x90,0x7f,0xeb,0xe0,0xfa,0x90,0x7f,0xea,0xe0,0xfb,0x90,0x7f,0xee,0xe0} },
+{ 14, 0x065c, 0, {0xfc,0x33,0x95,0xe0,0xfd,0x90,0x7f,0x96,0xe0,0xfe,0x90,0x7f,0x96,0x74} },
+{ 14, 0x066a, 0, {0x80,0x65,0x06,0xf0,0x90,0x7f,0x00,0x74,0x01,0xf0,0xea,0xc4,0x03,0x54} },
+{ 14, 0x0678, 0, {0xf8,0xfe,0xeb,0x25,0xe0,0xfb,0x2e,0xfe,0x24,0x00,0xfb,0xe4,0x34,0x17} },
+{ 14, 0x0686, 0, {0xff,0x8b,0x82,0x8f,0x83,0xe0,0xfb,0x74,0x01,0x2e,0x24,0x00,0xfe,0xe4} },
+{ 14, 0x0694, 0, {0x34,0x17,0xff,0x8e,0x82,0x8f,0x83,0xe0,0xfe,0x90,0x7f,0xe9,0xe0,0xff} },
+{ 3, 0x06a2, 0, {0xbf,0x81,0x0a} },
+{ 10, 0x06a5, 0, {0x90,0x7f,0x00,0xeb,0xf0,0x90,0x7f,0x01,0xee,0xf0} },
+{ 8, 0x06af, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x82,0x1a} },
+{ 3, 0x06b7, 0, {0xba,0x01,0x0c} },
+{ 12, 0x06ba, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0b} },
+{ 11, 0x06c6, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0x74,0xb5,0xf0} },
+{ 8, 0x06d1, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x83,0x1b} },
+{ 3, 0x06d9, 0, {0xba,0x01,0x0d} },
+{ 13, 0x06dc, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0b} },
+{ 11, 0x06e9, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0x74,0x12,0xf0} },
+{ 8, 0x06f4, 0, {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x84,0x1c} },
+{ 3, 0x06fc, 0, {0xba,0x01,0x0d} },
+{ 13, 0x06ff, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0c} },
+{ 12, 0x070c, 0, {0x90,0x7f,0x00,0x74,0x80,0xf0,0x90,0x7f,0x01,0x74,0x01,0xf0} },
+{ 5, 0x0718, 0, {0x90,0x7f,0xb5,0xec,0xf0} },
+{ 1, 0x071d, 0, {0x22} },
+{ 12, 0x071e, 0, {0x75,0x36,0x0d,0x90,0x88,0x00,0x74,0x1d,0xf0,0x75,0x6b,0x80} },
+{ 10, 0x072a, 0, {0x75,0x6c,0x3c,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} },
+{ 9, 0x0734, 0, {0x6c,0x0f,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} },
+{ 9, 0x073d, 0, {0x6c,0x06,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75} },
+{ 7, 0x0746, 0, {0x6c,0x01,0x12,0x10,0xe2,0x7a,0x00} },
+{ 3, 0x074d, 0, {0xba,0xff,0x00} },
+{ 2, 0x0750, 0, {0x50,0x0a} },
+{ 10, 0x0752, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xf1} },
+{ 10, 0x075c, 0, {0x75,0x6b,0x80,0x75,0x6c,0x3c,0x12,0x10,0xe2,0x75} },
+{ 8, 0x0766, 0, {0x6b,0x80,0x75,0x6c,0x0f,0x12,0x10,0xe2} },
+{ 1, 0x076e, 0, {0x22} },
+{ 14, 0x076f, 0, {0x90,0x7f,0xa1,0xe4,0xf0,0x90,0x7f,0xaf,0x74,0x01,0xf0,0x90,0x7f,0x92} },
+{ 14, 0x077d, 0, {0x74,0x02,0xf0,0x75,0x8e,0x31,0x75,0x89,0x21,0x75,0x88,0x00,0x75,0xc8} },
+{ 14, 0x078b, 0, {0x00,0x75,0x8d,0x40,0x75,0x98,0x40,0x75,0xc0,0x40,0x75,0x87,0x00,0x75} },
+{ 9, 0x0799, 0, {0x20,0x00,0x75,0x21,0x00,0x75,0x22,0x00,0x75} },
+{ 5, 0x07a2, 0, {0x23,0x00,0x75,0x47,0x00} },
+{ 7, 0x07a7, 0, {0xc3,0xe5,0x47,0x94,0x20,0x50,0x11} },
+{ 13, 0x07ae, 0, {0xe5,0x47,0x24,0x00,0xf5,0x82,0xe4,0x34,0x17,0xf5,0x83,0xe4,0xf0} },
+{ 4, 0x07bb, 0, {0x05,0x47,0x80,0xe8} },
+{ 9, 0x07bf, 0, {0xe4,0xf5,0x40,0xf5,0x3f,0xe4,0xf5,0x3c,0xf5} },
+{ 7, 0x07c8, 0, {0x3b,0xe4,0xf5,0x3e,0xf5,0x3d,0x75} },
+{ 11, 0x07cf, 0, {0x32,0x00,0x75,0x37,0x00,0x75,0x39,0x00,0x90,0x7f,0x93} },
+{ 14, 0x07da, 0, {0x74,0x3c,0xf0,0x90,0x7f,0x9c,0x74,0xff,0xf0,0x90,0x7f,0x96,0x74,0x80} },
+{ 14, 0x07e8, 0, {0xf0,0x90,0x7f,0x94,0x74,0x70,0xf0,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90} },
+{ 14, 0x07f6, 0, {0x7f,0x97,0xe4,0xf0,0x90,0x7f,0x95,0x74,0xc2,0xf0,0x90,0x7f,0x98,0x74} },
+{ 14, 0x0804, 0, {0x28,0xf0,0x90,0x7f,0x9e,0x74,0x28,0xf0,0x90,0x7f,0xf0,0xe4,0xf0,0x90} },
+{ 14, 0x0812, 0, {0x7f,0xf1,0xe4,0xf0,0x90,0x7f,0xf2,0xe4,0xf0,0x90,0x7f,0xf3,0xe4,0xf0} },
+{ 14, 0x0820, 0, {0x90,0x7f,0xf4,0xe4,0xf0,0x90,0x7f,0xf5,0xe4,0xf0,0x90,0x7f,0xf6,0xe4} },
+{ 14, 0x082e, 0, {0xf0,0x90,0x7f,0xf7,0xe4,0xf0,0x90,0x7f,0xf8,0xe4,0xf0,0x90,0x7f,0xf9} },
+{ 14, 0x083c, 0, {0x74,0x38,0xf0,0x90,0x7f,0xfa,0x74,0xa0,0xf0,0x90,0x7f,0xfb,0x74,0xa0} },
+{ 14, 0x084a, 0, {0xf0,0x90,0x7f,0xfc,0x74,0xa0,0xf0,0x90,0x7f,0xfd,0x74,0xa0,0xf0,0x90} },
+{ 14, 0x0858, 0, {0x7f,0xfe,0x74,0xa0,0xf0,0x90,0x7f,0xff,0x74,0xa0,0xf0,0x90,0x7f,0xe0} },
+{ 14, 0x0866, 0, {0x74,0x03,0xf0,0x90,0x7f,0xe1,0x74,0x01,0xf0,0x90,0x7f,0xdd,0x74,0x80} },
+{ 11, 0x0874, 0, {0xf0,0x12,0x12,0x43,0x12,0x07,0x1e,0x7a,0x00,0x7b,0x00} },
+{ 9, 0x087f, 0, {0xc3,0xea,0x94,0x1e,0xeb,0x94,0x00,0x50,0x17} },
+{ 12, 0x0888, 0, {0x90,0x88,0x00,0xe0,0xf5,0x47,0x90,0x88,0x0b,0xe0,0xf5,0x47} },
+{ 9, 0x0894, 0, {0x90,0x7f,0x68,0xf0,0x0a,0xba,0x00,0x01,0x0b} },
+{ 2, 0x089d, 0, {0x80,0xe0} },
+{ 12, 0x089f, 0, {0x12,0x03,0xe1,0x90,0x7f,0xd6,0xe4,0xf0,0x7a,0x00,0x7b,0x00} },
+{ 13, 0x08ab, 0, {0x8a,0x04,0x8b,0x05,0xc3,0xea,0x94,0xe0,0xeb,0x94,0x2e,0x50,0x1a} },
+{ 14, 0x08b8, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} },
+{ 10, 0x08c6, 0, {0x04,0xd0,0x03,0xd0,0x02,0x0a,0xba,0x00,0x01,0x0b} },
+{ 2, 0x08d0, 0, {0x80,0xd9} },
+{ 13, 0x08d2, 0, {0x90,0x7f,0xd6,0x74,0x02,0xf0,0x90,0x7f,0xd6,0x74,0x06,0xf0,0x90} },
+{ 14, 0x08df, 0, {0x7f,0xde,0x74,0x05,0xf0,0x90,0x7f,0xdf,0x74,0x05,0xf0,0x90,0x7f,0xac} },
+{ 14, 0x08ed, 0, {0xe4,0xf0,0x90,0x7f,0xad,0x74,0x05,0xf0,0x75,0xa8,0x80,0x75,0xf8,0x10} },
+{ 13, 0x08fb, 0, {0x90,0x7f,0xae,0x74,0x0b,0xf0,0x90,0x7f,0xe2,0x74,0x88,0xf0,0x90} },
+{ 12, 0x0908, 0, {0x7f,0xab,0x74,0x08,0xf0,0x75,0xe8,0x11,0x75,0x32,0x01,0x75} },
+{ 12, 0x0914, 0, {0x31,0x00,0x75,0x30,0x00,0xc0,0x04,0xc0,0x05,0x12,0x04,0xf7} },
+{ 10, 0x0920, 0, {0xd0,0x05,0xd0,0x04,0x75,0x34,0x00,0x75,0x35,0x01} },
+{ 13, 0x092a, 0, {0x90,0x7f,0xae,0x74,0x03,0xf0,0x8c,0x02,0xba,0x00,0x02,0x80,0x03} },
+{ 3, 0x0937, 0, {0x02,0x0a,0x3f} },
+{ 12, 0x093a, 0, {0x85,0x33,0x34,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90,0x7f,0x97} },
+{ 14, 0x0946, 0, {0x74,0x08,0xf0,0x90,0x7f,0x9d,0x74,0x88,0xf0,0x90,0x7f,0x9a,0xe0,0xfa} },
+{ 12, 0x0954, 0, {0x74,0x05,0x5a,0xf5,0x33,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90} },
+{ 13, 0x0960, 0, {0x7f,0x97,0x74,0x02,0xf0,0x90,0x7f,0x9d,0x74,0x82,0xf0,0xe5,0x33} },
+{ 13, 0x096d, 0, {0x25,0xe0,0xfa,0x90,0x7f,0x9a,0xe0,0x54,0x05,0xfb,0x4a,0xf5,0x33} },
+{ 2, 0x097a, 0, {0x60,0x0c} },
+{ 12, 0x097c, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x4a,0xf0} },
+{ 11, 0x0988, 0, {0x75,0x6e,0x00,0x75,0x6f,0x00,0xc0,0x04,0xc0,0x05,0x12} },
+{ 14, 0x0993, 0, {0x11,0x44,0xd0,0x05,0xd0,0x04,0x90,0x17,0x13,0xe0,0xfa,0x74,0x80,0x2a} },
+{ 6, 0x09a1, 0, {0xfa,0xe5,0x33,0xb4,0x04,0x29} },
+{ 3, 0x09a7, 0, {0xba,0xa0,0x00} },
+{ 2, 0x09aa, 0, {0x50,0x24} },
+{ 13, 0x09ac, 0, {0x90,0x17,0x13,0xe0,0x04,0xfb,0x0b,0x90,0x17,0x13,0xeb,0xf0,0x90} },
+{ 14, 0x09b9, 0, {0x17,0x13,0xe0,0xfb,0x90,0x17,0x15,0xf0,0xc0,0x02,0xc0,0x04,0xc0,0x05} },
+{ 9, 0x09c7, 0, {0x12,0x04,0xf7,0xd0,0x05,0xd0,0x04,0xd0,0x02} },
+{ 5, 0x09d0, 0, {0xe5,0x33,0xb4,0x02,0x26} },
+{ 6, 0x09d5, 0, {0xc3,0x74,0x04,0x9a,0x50,0x20} },
+{ 13, 0x09db, 0, {0x90,0x17,0x13,0xe0,0xfa,0x1a,0x1a,0x90,0x17,0x13,0xea,0xf0,0x90} },
+{ 13, 0x09e8, 0, {0x17,0x13,0xe0,0xfa,0x90,0x17,0x15,0xf0,0xc0,0x04,0xc0,0x05,0x12} },
+{ 6, 0x09f5, 0, {0x04,0xf7,0xd0,0x05,0xd0,0x04} },
+{ 5, 0x09fb, 0, {0xe5,0x33,0xb4,0x08,0x1d} },
+{ 4, 0x0a00, 0, {0xe5,0x34,0x70,0x19} },
+{ 10, 0x0a04, 0, {0x74,0x01,0x25,0x35,0x54,0x0f,0xf5,0x35,0x85,0x35} },
+{ 12, 0x0a0e, 0, {0x75,0x75,0x76,0x00,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0} },
+{ 3, 0x0a1a, 0, {0x05,0xd0,0x04} },
+{ 5, 0x0a1d, 0, {0xe5,0x33,0xb4,0x01,0x1d} },
+{ 4, 0x0a22, 0, {0xe5,0x34,0x70,0x19} },
+{ 10, 0x0a26, 0, {0xe5,0x35,0x24,0xff,0x54,0x0f,0xf5,0x35,0x85,0x35} },
+{ 12, 0x0a30, 0, {0x75,0x75,0x76,0x00,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0} },
+{ 3, 0x0a3c, 0, {0x05,0xd0,0x04} },
+{ 14, 0x0a3f, 0, {0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0,0x04,0x90,0x7f,0x96} },
+{ 14, 0x0a4d, 0, {0xe0,0xfa,0x90,0x7f,0x96,0x74,0x7f,0x5a,0xf0,0x90,0x7f,0x97,0x74,0x08} },
+{ 10, 0x0a5b, 0, {0xf0,0xc3,0xec,0x94,0x00,0xed,0x94,0x02,0x40,0x08} },
+{ 8, 0x0a65, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x20,0xe6,0x08} },
+{ 8, 0x0a6d, 0, {0xc3,0xe4,0x9c,0x74,0x08,0x9d,0x50,0x13} },
+{ 14, 0x0a75, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x40,0x65,0x02,0xf0,0x7c} },
+{ 5, 0x0a83, 0, {0x00,0x7d,0x00,0x80,0x05} },
+{ 5, 0x0a88, 0, {0x0c,0xbc,0x00,0x01,0x0d} },
+{ 5, 0x0a8d, 0, {0xe5,0x38,0xb4,0x01,0x0e} },
+{ 13, 0x0a92, 0, {0xc0,0x04,0xc0,0x05,0x12,0x04,0xf7,0xd0,0x05,0xd0,0x04,0x75,0x38} },
+{ 1, 0x0a9f, 0, {0x00} },
+{ 7, 0x0aa0, 0, {0xe5,0x31,0x70,0x03,0x02,0x09,0x2a} },
+{ 10, 0x0aa7, 0, {0x90,0x7f,0xc9,0xe0,0xfa,0x70,0x03,0x02,0x0c,0x2d} },
+{ 14, 0x0ab1, 0, {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x65,0x02,0xf0,0x90} },
+{ 9, 0x0abf, 0, {0x7d,0xc0,0xe0,0xfa,0xba,0x2c,0x02,0x80,0x03} },
+{ 3, 0x0ac8, 0, {0x02,0x0b,0x36} },
+{ 5, 0x0acb, 0, {0x75,0x32,0x00,0x7b,0x00} },
+{ 3, 0x0ad0, 0, {0xbb,0x64,0x00} },
+{ 2, 0x0ad3, 0, {0x50,0x1c} },
+{ 14, 0x0ad5, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} },
+{ 13, 0x0ae3, 0, {0x04,0xd0,0x03,0xd0,0x02,0x90,0x88,0x0f,0xe0,0xf5,0x47,0x0b,0x80} },
+{ 1, 0x0af0, 0, {0xdf} },
+{ 13, 0x0af1, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x07,0x1e,0x12,0x03,0xe1,0x12} },
+{ 12, 0x0afe, 0, {0x04,0xf7,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x75,0x6e,0x00,0x75} },
+{ 13, 0x0b0a, 0, {0x6f,0x01,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x11,0x44,0xd0,0x05} },
+{ 9, 0x0b17, 0, {0xd0,0x04,0xd0,0x02,0x75,0x70,0x4d,0x75,0x71} },
+{ 11, 0x0b20, 0, {0x0c,0x75,0x72,0x02,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12} },
+{ 11, 0x0b2b, 0, {0x11,0x75,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x02,0x0c,0x2d} },
+{ 3, 0x0b36, 0, {0xba,0x2a,0x3b} },
+{ 13, 0x0b39, 0, {0x90,0x7f,0x98,0x74,0x20,0xf0,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12} },
+{ 14, 0x0b46, 0, {0x01,0xdd,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x90,0x7f,0x98,0x74,0x28,0xf0} },
+{ 2, 0x0b54, 0, {0x7b,0x00} },
+{ 3, 0x0b56, 0, {0xbb,0x0a,0x00} },
+{ 5, 0x0b59, 0, {0x40,0x03,0x02,0x0c,0x2d} },
+{ 14, 0x0b5e, 0, {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0} },
+{ 8, 0x0b6c, 0, {0x04,0xd0,0x03,0xd0,0x02,0x0b,0x80,0xe2} },
+{ 3, 0x0b74, 0, {0xba,0x2b,0x1a} },
+{ 8, 0x0b77, 0, {0x90,0x7f,0xc9,0xe0,0xfb,0xbb,0x40,0x12} },
+{ 14, 0x0b7f, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x12,0x05,0xd0,0x05,0xd0,0x04,0xd0} },
+{ 4, 0x0b8d, 0, {0x02,0x02,0x0c,0x2d} },
+{ 3, 0x0b91, 0, {0xba,0x10,0x1f} },
+{ 14, 0x0b94, 0, {0x90,0x7f,0x96,0xe0,0xfb,0x90,0x7f,0x96,0x74,0x80,0x65,0x03,0xf0,0xc0} },
+{ 14, 0x0ba2, 0, {0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x3d,0xd0,0x05,0xd0,0x04,0xd0,0x02} },
+{ 3, 0x0bb0, 0, {0x02,0x0c,0x2d} },
+{ 3, 0x0bb3, 0, {0xba,0x11,0x12} },
+{ 14, 0x0bb6, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x6a,0xd0,0x05,0xd0,0x04,0xd0} },
+{ 4, 0x0bc4, 0, {0x02,0x02,0x0c,0x2d} },
+{ 3, 0x0bc8, 0, {0xba,0x12,0x12} },
+{ 14, 0x0bcb, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x8f,0xd0,0x05,0xd0,0x04,0xd0} },
+{ 4, 0x0bd9, 0, {0x02,0x02,0x0c,0x2d} },
+{ 3, 0x0bdd, 0, {0xba,0x13,0x0b} },
+{ 11, 0x0be0, 0, {0x90,0x7d,0xc1,0xe0,0xfb,0x90,0x88,0x00,0xf0,0x80,0x42} },
+{ 3, 0x0beb, 0, {0xba,0x14,0x11} },
+{ 14, 0x0bee, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x11,0xdd,0xd0,0x05,0xd0,0x04,0xd0} },
+{ 3, 0x0bfc, 0, {0x02,0x80,0x2e} },
+{ 3, 0x0bff, 0, {0xba,0x15,0x1d} },
+{ 12, 0x0c02, 0, {0x90,0x7d,0xc1,0xe0,0xf5,0x75,0x90,0x7d,0xc2,0xe0,0xf5,0x76} },
+{ 14, 0x0c0e, 0, {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0,0x05,0xd0,0x04,0xd0} },
+{ 3, 0x0c1c, 0, {0x02,0x80,0x0e} },
+{ 3, 0x0c1f, 0, {0xba,0x16,0x0b} },
+{ 11, 0x0c22, 0, {0xc0,0x04,0xc0,0x05,0x12,0x13,0xa3,0xd0,0x05,0xd0,0x04} },
+{ 11, 0x0c2d, 0, {0x90,0x7f,0xc9,0xe4,0xf0,0x75,0x31,0x00,0x02,0x09,0x2a} },
+{ 1, 0x0c38, 0, {0x22} },
+{ 7, 0x0c39, 0, {0x53,0x55,0x50,0x45,0x4e,0x44,0x00} },
+{ 7, 0x0c40, 0, {0x52,0x45,0x53,0x55,0x4d,0x45,0x00} },
+{ 6, 0x0c47, 0, {0x20,0x56,0x6f,0x6c,0x20,0x00} },
+{ 13, 0x0c4d, 0, {0x44,0x41,0x42,0x55,0x53,0x42,0x20,0x76,0x31,0x2e,0x30,0x30,0x00} },
+{ 14, 0x0c5a, 0, {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04} },
+{ 14, 0x0c68, 0, {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0} },
+{ 13, 0x0c76, 0, {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90} },
+{ 14, 0x0c83, 0, {0x7f,0xab,0x74,0x01,0xf0,0x90,0x7f,0xe8,0xe0,0xfa,0x90,0x7f,0xe9,0xe0} },
+{ 6, 0x0c91, 0, {0xfb,0xbb,0x00,0x02,0x80,0x03} },
+{ 3, 0x0c97, 0, {0x02,0x0d,0x38} },
+{ 3, 0x0c9a, 0, {0xba,0x80,0x14} },
+{ 14, 0x0c9d, 0, {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5} },
+{ 6, 0x0cab, 0, {0x74,0x02,0xf0,0x02,0x0e,0xcd} },
+{ 5, 0x0cb1, 0, {0xba,0x82,0x02,0x80,0x03} },
+{ 3, 0x0cb6, 0, {0x02,0x0d,0x1d} },
+{ 8, 0x0cb9, 0, {0x90,0x7f,0xec,0xe0,0xfc,0xbc,0x01,0x00} },
+{ 2, 0x0cc1, 0, {0x40,0x21} },
+{ 6, 0x0cc3, 0, {0xc3,0x74,0x07,0x9c,0x40,0x1b} },
+{ 14, 0x0cc9, 0, {0xec,0x24,0xff,0x25,0xe0,0xfd,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x7f,0xf5} },
+{ 13, 0x0cd7, 0, {0x83,0xe0,0xfd,0x53,0x05,0x01,0x90,0x7f,0x00,0xed,0xf0,0x80,0x2b} },
+{ 3, 0x0ce4, 0, {0xbc,0x81,0x00} },
+{ 2, 0x0ce7, 0, {0x40,0x21} },
+{ 6, 0x0ce9, 0, {0xc3,0x74,0x87,0x9c,0x40,0x1b} },
+{ 14, 0x0cef, 0, {0xec,0x24,0x7f,0x25,0xe0,0xfc,0x24,0xb6,0xf5,0x82,0xe4,0x34,0x7f,0xf5} },
+{ 13, 0x0cfd, 0, {0x83,0xe0,0xfc,0x53,0x04,0x01,0x90,0x7f,0x00,0xec,0xf0,0x80,0x05} },
+{ 5, 0x0d0a, 0, {0x90,0x7f,0x00,0xe4,0xf0} },
+{ 14, 0x0d0f, 0, {0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x02,0x0e,0xcd} },
+{ 5, 0x0d1d, 0, {0xba,0x81,0x02,0x80,0x03} },
+{ 3, 0x0d22, 0, {0x02,0x0e,0xc5} },
+{ 14, 0x0d25, 0, {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5,0x74} },
+{ 5, 0x0d33, 0, {0x02,0xf0,0x02,0x0e,0xcd} },
+{ 3, 0x0d38, 0, {0xbb,0x01,0x2d} },
+{ 6, 0x0d3b, 0, {0xba,0x00,0x03,0x02,0x0e,0xcd} },
+{ 3, 0x0d41, 0, {0xba,0x02,0x11} },
+{ 13, 0x0d44, 0, {0x75,0x59,0x00,0xc0,0x02,0xc0,0x03,0x12,0x0e,0xf0,0xd0,0x03,0xd0} },
+{ 4, 0x0d51, 0, {0x02,0x02,0x0e,0xcd} },
+{ 5, 0x0d55, 0, {0xba,0x21,0x02,0x80,0x03} },
+{ 3, 0x0d5a, 0, {0x02,0x0e,0xcd} },
+{ 11, 0x0d5d, 0, {0x75,0x37,0x01,0x90,0x7f,0xc5,0xe4,0xf0,0x02,0x0e,0xcd} },
+{ 3, 0x0d68, 0, {0xbb,0x03,0x1f} },
+{ 6, 0x0d6b, 0, {0xba,0x00,0x03,0x02,0x0e,0xcd} },
+{ 5, 0x0d71, 0, {0xba,0x02,0x02,0x80,0x03} },
+{ 3, 0x0d76, 0, {0x02,0x0e,0xcd} },
+{ 13, 0x0d79, 0, {0x75,0x59,0x01,0xc0,0x02,0xc0,0x03,0x12,0x0e,0xf0,0xd0,0x03,0xd0} },
+{ 4, 0x0d86, 0, {0x02,0x02,0x0e,0xcd} },
+{ 3, 0x0d8a, 0, {0xbb,0x06,0x54} },
+{ 5, 0x0d8d, 0, {0xba,0x80,0x02,0x80,0x03} },
+{ 3, 0x0d92, 0, {0x02,0x0e,0xc5} },
+{ 8, 0x0d95, 0, {0x90,0x7f,0xeb,0xe0,0xfc,0xbc,0x01,0x15} },
+{ 12, 0x0d9d, 0, {0x7c,0xfb,0x7d,0x0f,0x8d,0x06,0x7f,0x00,0x90,0x7f,0xd4,0xee} },
+{ 9, 0x0da9, 0, {0xf0,0x90,0x7f,0xd5,0xec,0xf0,0x02,0x0e,0xcd} },
+{ 10, 0x0db2, 0, {0x90,0x7f,0xeb,0xe0,0xfc,0xbc,0x02,0x02,0x80,0x03} },
+{ 3, 0x0dbc, 0, {0x02,0x0e,0xc5} },
+{ 10, 0x0dbf, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xbc,0x00,0x02,0x80,0x03} },
+{ 3, 0x0dc9, 0, {0x02,0x0e,0xc5} },
+{ 12, 0x0dcc, 0, {0x7c,0x3b,0x7d,0x0f,0x8d,0x06,0x7f,0x00,0x90,0x7f,0xd4,0xee} },
+{ 9, 0x0dd8, 0, {0xf0,0x90,0x7f,0xd5,0xec,0xf0,0x02,0x0e,0xcd} },
+{ 6, 0x0de1, 0, {0xbb,0x07,0x03,0x02,0x0e,0xc5} },
+{ 3, 0x0de7, 0, {0xbb,0x08,0x10} },
+{ 13, 0x0dea, 0, {0xac,0x48,0x90,0x7f,0x00,0xec,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0} },
+{ 3, 0x0df7, 0, {0x02,0x0e,0xcd} },
+{ 3, 0x0dfa, 0, {0xbb,0x09,0x31} },
+{ 5, 0x0dfd, 0, {0xba,0x00,0x02,0x80,0x03} },
+{ 3, 0x0e02, 0, {0x02,0x0e,0xc5} },
+{ 14, 0x0e05, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xc3,0x74,0x01,0x9c,0x50,0x03,0x02,0x0e,0xc5} },
+{ 8, 0x0e13, 0, {0x90,0x7f,0xea,0xe0,0xfc,0xbc,0x00,0x0a} },
+{ 10, 0x0e1b, 0, {0x90,0x17,0x21,0xe4,0xf0,0x90,0x17,0x22,0xe4,0xf0} },
+{ 9, 0x0e25, 0, {0x90,0x7f,0xea,0xe0,0xf5,0x48,0x02,0x0e,0xcd} },
+{ 3, 0x0e2e, 0, {0xbb,0x0a,0x27} },
+{ 5, 0x0e31, 0, {0xba,0x81,0x02,0x80,0x03} },
+{ 3, 0x0e36, 0, {0x02,0x0e,0xc5} },
+{ 14, 0x0e39, 0, {0x90,0x7f,0xec,0xe0,0xfa,0x24,0x20,0xfa,0xe4,0x34,0x17,0xfc,0x8a,0x82} },
+{ 14, 0x0e47, 0, {0x8c,0x83,0xe0,0xfa,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0} },
+{ 3, 0x0e55, 0, {0x02,0x0e,0xcd} },
+{ 5, 0x0e58, 0, {0xbb,0x0b,0x02,0x80,0x03} },
+{ 3, 0x0e5d, 0, {0x02,0x0e,0xa9} },
+{ 13, 0x0e60, 0, {0x90,0x17,0x20,0xe4,0xf0,0x90,0x7f,0xec,0xe0,0xfa,0xba,0x01,0x1a} },
+{ 8, 0x0e6d, 0, {0x90,0x7f,0xed,0xe0,0xfa,0xba,0x00,0x12} },
+{ 14, 0x0e75, 0, {0x90,0x7f,0xea,0xe0,0xfa,0x90,0x17,0x21,0xf0,0xc0,0x03,0x12,0x04,0xe2} },
+{ 4, 0x0e83, 0, {0xd0,0x03,0x80,0x46} },
+{ 8, 0x0e87, 0, {0x90,0x7f,0xec,0xe0,0xfa,0xba,0x02,0x3e} },
+{ 8, 0x0e8f, 0, {0x90,0x7f,0xed,0xe0,0xfa,0xba,0x00,0x36} },
+{ 13, 0x0e97, 0, {0xc0,0x03,0x12,0x04,0xef,0xd0,0x03,0x90,0x7f,0xea,0xe0,0xfa,0x90} },
+{ 5, 0x0ea4, 0, {0x17,0x22,0xf0,0x80,0x24} },
+{ 5, 0x0ea9, 0, {0xbb,0x12,0x02,0x80,0x17} },
+{ 5, 0x0eae, 0, {0xbb,0x81,0x02,0x80,0x0d} },
+{ 5, 0x0eb3, 0, {0xbb,0x83,0x02,0x80,0x08} },
+{ 5, 0x0eb8, 0, {0xbb,0x82,0x02,0x80,0x03} },
+{ 3, 0x0ebd, 0, {0xbb,0x84,0x05} },
+{ 5, 0x0ec0, 0, {0x12,0x06,0x4e,0x80,0x08} },
+{ 8, 0x0ec5, 0, {0x90,0x7f,0xb4,0x74,0x03,0xf0,0x80,0x06} },
+{ 6, 0x0ecd, 0, {0x90,0x7f,0xb4,0x74,0x02,0xf0} },
+{ 2, 0x0ed3, 0, {0xd0,0x86} },
+{ 14, 0x0ed5, 0, {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04} },
+{ 13, 0x0ee3, 0, {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32} },
+{ 11, 0x0ef0, 0, {0x90,0x7f,0xec,0xe0,0xf5,0x5a,0xc3,0x94,0x01,0x40,0x1d} },
+{ 7, 0x0efb, 0, {0xc3,0x74,0x07,0x95,0x5a,0x40,0x16} },
+{ 13, 0x0f02, 0, {0xe5,0x5a,0x24,0xff,0x25,0xe0,0xfa,0x24,0xc6,0xf5,0x82,0xe4,0x34} },
+{ 9, 0x0f0f, 0, {0x7f,0xf5,0x83,0xaa,0x59,0xea,0xf0,0x80,0x22} },
+{ 7, 0x0f18, 0, {0xc3,0xe5,0x5a,0x94,0x81,0x40,0x1b} },
+{ 7, 0x0f1f, 0, {0xc3,0x74,0x87,0x95,0x5a,0x40,0x14} },
+{ 13, 0x0f26, 0, {0xe5,0x5a,0x24,0xff,0x25,0xe0,0xfa,0x24,0xb6,0xf5,0x82,0xe4,0x34} },
+{ 7, 0x0f33, 0, {0x7f,0xf5,0x83,0xaa,0x59,0xea,0xf0} },
+{ 1, 0x0f3a, 0, {0x22} },
+{ 14, 0x0f3b, 0, {0x09,0x02,0xba,0x00,0x03,0x01,0x00,0x40,0x00,0x09,0x04,0x00,0x00,0x00} },
+{ 14, 0x0f49, 0, {0x01,0x01,0x00,0x00,0x09,0x24,0x01,0x00,0x01,0x3d,0x00,0x01,0x01,0x0c} },
+{ 14, 0x0f57, 0, {0x24,0x02,0x01,0x10,0x07,0x00,0x02,0x03,0x00,0x00,0x00,0x0d,0x24,0x06} },
+{ 14, 0x0f65, 0, {0x03,0x01,0x02,0x15,0x00,0x03,0x00,0x03,0x00,0x00,0x09,0x24,0x03,0x02} },
+{ 14, 0x0f73, 0, {0x01,0x01,0x00,0x01,0x00,0x09,0x24,0x03,0x04,0x02,0x03,0x00,0x03,0x00} },
+{ 14, 0x0f81, 0, {0x09,0x24,0x03,0x05,0x03,0x06,0x00,0x01,0x00,0x09,0x04,0x01,0x00,0x00} },
+{ 14, 0x0f8f, 0, {0x01,0x02,0x00,0x00,0x09,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00,0x07} },
+{ 14, 0x0f9d, 0, {0x24,0x01,0x02,0x01,0x01,0x00,0x0b,0x24,0x02,0x01,0x02,0x02,0x10,0x01} },
+{ 14, 0x0fab, 0, {0x80,0xbb,0x00,0x09,0x05,0x88,0x05,0x00,0x01,0x01,0x00,0x00,0x07,0x25} },
+{ 14, 0x0fb9, 0, {0x01,0x00,0x00,0x00,0x00,0x09,0x04,0x02,0x00,0x02,0x00,0x00,0x00,0x00} },
+{ 14, 0x0fc7, 0, {0x07,0x05,0x82,0x02,0x40,0x00,0x00,0x07,0x05,0x02,0x02,0x40,0x00,0x00} },
+{ 14, 0x0fd5, 0, {0x09,0x04,0x02,0x01,0x03,0x00,0x00,0x00,0x00,0x07,0x05,0x82,0x02,0x40} },
+{ 14, 0x0fe3, 0, {0x00,0x00,0x07,0x05,0x02,0x02,0x40,0x00,0x00,0x09,0x05,0x89,0x05,0xa0} },
+{ 10, 0x0ff1, 0, {0x01,0x01,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00} },
+{ 14, 0x0ffb, 0, {0x12,0x01,0x00,0x01,0x00,0x00,0x00,0x40,0x47,0x05,0x99,0x99,0x00,0x01} },
+{ 14, 0x1009, 0, {0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x02,0xba} },
+{ 4, 0x1017, 0, {0x00,0x03,0x01,0x00} },
+{ 2, 0x101b, 0, {0x7a,0x00} },
+{ 3, 0x101d, 0, {0xba,0x05,0x00} },
+{ 2, 0x1020, 0, {0x50,0x17} },
+{ 8, 0x1022, 0, {0x90,0x7f,0xa5,0xe0,0xfb,0x30,0xe0,0x05} },
+{ 5, 0x102a, 0, {0x90,0x00,0x01,0x80,0x0d} },
+{ 10, 0x102f, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xe4} },
+{ 3, 0x1039, 0, {0x90,0x00,0x01} },
+{ 1, 0x103c, 0, {0x22} },
+{ 14, 0x103d, 0, {0x90,0x7d,0xc1,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x7c,0x00,0x7d} },
+{ 4, 0x104b, 0, {0x7e,0xeb,0x60,0x12} },
+{ 14, 0x104f, 0, {0x89,0x82,0x8a,0x83,0xe0,0xa3,0xa9,0x82,0xaa,0x83,0x8c,0x82,0x8d,0x83} },
+{ 4, 0x105d, 0, {0xf0,0x0c,0xdb,0xee} },
+{ 8, 0x1061, 0, {0x90,0x7d,0xc3,0xe0,0x90,0x7f,0xb9,0xf0} },
+{ 1, 0x1069, 0, {0x22} },
+{ 14, 0x106a, 0, {0x90,0x7d,0xc1,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x7c,0xc4,0x7d} },
+{ 4, 0x1078, 0, {0x7d,0xeb,0x60,0xe5} },
+{ 14, 0x107c, 0, {0x8c,0x82,0x8d,0x83,0xe0,0x0c,0x89,0x82,0x8a,0x83,0xf0,0xa3,0xa9,0x82} },
+{ 4, 0x108a, 0, {0xaa,0x83,0xdb,0xee} },
+{ 1, 0x108e, 0, {0x22} },
+{ 14, 0x108f, 0, {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x05,0x86,0x90,0x7d,0xc1,0xe0,0x05,0x86} },
+{ 14, 0x109d, 0, {0xa3,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa6,0x05,0x86,0xa3,0xa3,0xe0,0xf9} },
+{ 5, 0x10ab, 0, {0x60,0x16,0xa3,0x05,0x86} },
+{ 13, 0x10b0, 0, {0x90,0x7f,0xa6,0x05,0x86,0xe0,0xa3,0x05,0x86,0xf0,0xc0,0x01,0x12} },
+{ 6, 0x10bd, 0, {0x10,0x1b,0xd0,0x01,0xd9,0xed} },
+{ 6, 0x10c3, 0, {0x90,0x7f,0xa5,0x74,0x40,0xf0} },
+{ 1, 0x10c9, 0, {0x22} },
+{ 8, 0x10ca, 0, {0x90,0x88,0x02,0x74,0x01,0xf0,0x7a,0x00} },
+{ 3, 0x10d2, 0, {0xba,0xff,0x00} },
+{ 2, 0x10d5, 0, {0x50,0x0a} },
+{ 10, 0x10d7, 0, {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xf1} },
+{ 1, 0x10e1, 0, {0x22} },
+{ 5, 0x10e2, 0, {0xe5,0x6b,0xb4,0xc0,0x08} },
+{ 8, 0x10e7, 0, {0x90,0x88,0x03,0xe5,0x6c,0xf0,0x80,0x06} },
+{ 6, 0x10ef, 0, {0x90,0x88,0x02,0xe5,0x6c,0xf0} },
+{ 4, 0x10f5, 0, {0x7a,0x00,0x7b,0x00} },
+{ 11, 0x10f9, 0, {0xc3,0xea,0x94,0x32,0xeb,0x64,0x80,0x94,0x80,0x50,0x07} },
+{ 5, 0x1104, 0, {0x0a,0xba,0x00,0x01,0x0b} },
+{ 2, 0x1109, 0, {0x80,0xee} },
+{ 1, 0x110b, 0, {0x22} },
+{ 10, 0x110c, 0, {0x90,0x88,0x03,0xe5,0x6d,0xf0,0x05,0x39,0x7a,0x00} },
+{ 3, 0x1116, 0, {0xba,0x28,0x00} },
+{ 2, 0x1119, 0, {0x50,0x03} },
+{ 3, 0x111b, 0, {0x0a,0x80,0xf8} },
+{ 5, 0x111e, 0, {0xe5,0x39,0xb4,0x10,0x08} },
+{ 8, 0x1123, 0, {0x90,0x88,0x02,0x74,0xc0,0xf0,0x80,0x0e} },
+{ 5, 0x112b, 0, {0xe5,0x39,0xb4,0x20,0x09} },
+{ 9, 0x1130, 0, {0x90,0x88,0x02,0x74,0x80,0xf0,0x75,0x39,0x00} },
+{ 2, 0x1139, 0, {0x7a,0x00} },
+{ 3, 0x113b, 0, {0xba,0x28,0x00} },
+{ 2, 0x113e, 0, {0x50,0x03} },
+{ 3, 0x1140, 0, {0x0a,0x80,0xf8} },
+{ 1, 0x1143, 0, {0x22} },
+{ 4, 0x1144, 0, {0xe5,0x6f,0x60,0x02} },
+{ 2, 0x1148, 0, {0x80,0x07} },
+{ 7, 0x114a, 0, {0x7a,0x00,0x75,0x39,0x00,0x80,0x05} },
+{ 5, 0x1151, 0, {0x7a,0x40,0x75,0x39,0x10} },
+{ 9, 0x1156, 0, {0xe5,0x6e,0x2a,0xfa,0xe5,0x6e,0x25,0x39,0xf5} },
+{ 10, 0x115f, 0, {0x39,0x90,0x88,0x02,0x74,0x80,0x2a,0xf0,0x7a,0x00} },
+{ 8, 0x1169, 0, {0xc3,0xea,0x64,0x80,0x94,0xa8,0x50,0x03} },
+{ 3, 0x1171, 0, {0x0a,0x80,0xf5} },
+{ 1, 0x1174, 0, {0x22} },
+{ 6, 0x1175, 0, {0xaa,0x70,0xab,0x71,0xac,0x72} },
+{ 12, 0x117b, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x12,0x14,0xee,0xfd,0x60,0x18} },
+{ 13, 0x1187, 0, {0x8d,0x6d,0xc0,0x02,0xc0,0x03,0xc0,0x04,0x12,0x11,0x0c,0xd0,0x04} },
+{ 9, 0x1194, 0, {0xd0,0x03,0xd0,0x02,0x0a,0xba,0x00,0x01,0x0b} },
+{ 2, 0x119d, 0, {0x80,0xdc} },
+{ 1, 0x119f, 0, {0x22} },
+{ 13, 0x11a0, 0, {0xe5,0x73,0xc4,0x54,0x0f,0xfa,0x53,0x02,0x0f,0xc3,0x74,0x09,0x9a} },
+{ 2, 0x11ad, 0, {0x50,0x06} },
+{ 6, 0x11af, 0, {0x74,0x37,0x2a,0xfb,0x80,0x04} },
+{ 4, 0x11b5, 0, {0x74,0x30,0x2a,0xfb} },
+{ 12, 0x11b9, 0, {0x8b,0x6d,0xc0,0x03,0x12,0x11,0x0c,0xd0,0x03,0xaa,0x73,0x53} },
+{ 8, 0x11c5, 0, {0x02,0x0f,0xc3,0x74,0x09,0x9a,0x50,0x06} },
+{ 6, 0x11cd, 0, {0x74,0x37,0x2a,0xfb,0x80,0x04} },
+{ 4, 0x11d3, 0, {0x74,0x30,0x2a,0xfb} },
+{ 5, 0x11d7, 0, {0x8b,0x6d,0x12,0x11,0x0c} },
+{ 1, 0x11dc, 0, {0x22} },
+{ 7, 0x11dd, 0, {0x90,0x7d,0xc3,0xe0,0xfa,0x60,0x0f} },
+{ 12, 0x11e4, 0, {0x90,0x7d,0xc1,0xe0,0xf5,0x6e,0x90,0x7d,0xc2,0xe0,0xf5,0x6f} },
+{ 3, 0x11f0, 0, {0x12,0x11,0x44} },
+{ 12, 0x11f3, 0, {0x90,0x7d,0xff,0xe4,0xf0,0x75,0x70,0xc4,0x75,0x71,0x7d,0x75} },
+{ 5, 0x11ff, 0, {0x72,0x01,0x12,0x11,0x75} },
+{ 1, 0x1204, 0, {0x22} },
+{ 2, 0x1205, 0, {0x7a,0x04} },
+{ 3, 0x1207, 0, {0xba,0x40,0x00} },
+{ 2, 0x120a, 0, {0x50,0x36} },
+{ 14, 0x120c, 0, {0xea,0x24,0xc0,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfb,0x7c,0x00} },
+{ 3, 0x121a, 0, {0xbc,0x08,0x00} },
+{ 2, 0x121d, 0, {0x50,0x20} },
+{ 6, 0x121f, 0, {0x8b,0x05,0xed,0x30,0xe7,0x0b} },
+{ 11, 0x1225, 0, {0x90,0x7f,0x96,0x74,0x42,0xf0,0x74,0xc3,0xf0,0x80,0x08} },
+{ 8, 0x1230, 0, {0x90,0x7f,0x96,0xe4,0xf0,0x74,0x81,0xf0} },
+{ 7, 0x1238, 0, {0xeb,0x25,0xe0,0xfb,0x0c,0x80,0xdb} },
+{ 3, 0x123f, 0, {0x0a,0x80,0xc5} },
+{ 1, 0x1242, 0, {0x22} },
+{ 4, 0x1243, 0, {0x7a,0x00,0x7b,0xef} },
+{ 3, 0x1247, 0, {0xba,0x10,0x00} },
+{ 2, 0x124a, 0, {0x50,0x20} },
+{ 14, 0x124c, 0, {0x74,0x11,0x2b,0xfb,0x24,0x00,0xfc,0xe4,0x34,0x18,0xfd,0x8c,0x82,0x8d} },
+{ 14, 0x125a, 0, {0x83,0xe4,0xf0,0xea,0x24,0x00,0xf5,0x82,0xe4,0x34,0x19,0xf5,0x83,0xe4} },
+{ 4, 0x1268, 0, {0xf0,0x0a,0x80,0xdb} },
+{ 1, 0x126c, 0, {0x22} },
+{ 14, 0x126d, 0, {0x74,0xf8,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
+{ 14, 0x127b, 0, {0x74,0xf9,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
+{ 14, 0x1289, 0, {0x74,0xfa,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
+{ 14, 0x1297, 0, {0x74,0xfb,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
+{ 14, 0x12a5, 0, {0x74,0xff,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0} },
+{ 1, 0x12b3, 0, {0x22} },
+{ 14, 0x12b4, 0, {0x12,0x03,0xcb,0x12,0x12,0x6d,0x7a,0xc0,0x7b,0x87,0x7c,0x01,0x74,0x01} },
+{ 14, 0x12c2, 0, {0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x74} },
+{ 14, 0x12d0, 0, {0x01,0x12,0x14,0xbf,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e} },
+{ 14, 0x12de, 0, {0x83,0x8f,0xf0,0x74,0x06,0x12,0x14,0xbf,0x74,0x01,0x2a,0xfd,0xe4,0x3b} },
+{ 14, 0x12ec, 0, {0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0xe4,0x12,0x14,0xbf,0x74} },
+{ 14, 0x12fa, 0, {0x01,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0} },
+{ 14, 0x1308, 0, {0x74,0x0b,0x12,0x14,0xbf,0x74,0x01,0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07} },
+{ 14, 0x1316, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x74,0x08,0x12,0x14,0xbf,0x74,0x01,0x2d} },
+{ 14, 0x1324, 0, {0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0,0x74,0x01} },
+{ 14, 0x1332, 0, {0x12,0x14,0xbf,0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83} },
+{ 14, 0x1340, 0, {0x8c,0xf0,0xe4,0x12,0x14,0xbf,0x74,0x01,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f} },
+{ 14, 0x134e, 0, {0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0,0x74,0x03,0x12,0x14,0xbf,0x7d,0x00} },
+{ 3, 0x135c, 0, {0xbd,0x06,0x00} },
+{ 2, 0x135f, 0, {0x50,0x12} },
+{ 11, 0x1361, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x0a,0xba,0x00,0x01,0x0b} },
+{ 7, 0x136c, 0, {0xe4,0x12,0x14,0xbf,0x0d,0x80,0xe9} },
+{ 13, 0x1373, 0, {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0xe5,0x74,0x12,0x14,0xbf,0x74,0xf9} },
+{ 14, 0x1380, 0, {0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0x74,0x0f,0xf0,0x74} },
+{ 14, 0x138e, 0, {0xfe,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0x74,0x01,0xf0} },
+{ 6, 0x139c, 0, {0x12,0x03,0xe1,0x12,0x04,0xf7} },
+{ 1, 0x13a2, 0, {0x22} },
+{ 13, 0x13a3, 0, {0x90,0x7d,0xc1,0xe0,0xfa,0x24,0x00,0xfb,0xe4,0x34,0x19,0xfc,0x90} },
+{ 14, 0x13b0, 0, {0x7d,0xc2,0xe0,0xfd,0x8b,0x82,0x8c,0x83,0xf0,0x75,0xf0,0x11,0xea,0xa4} },
+{ 3, 0x13be, 0, {0xfa,0x7b,0x00} },
+{ 3, 0x13c1, 0, {0xbb,0x10,0x00} },
+{ 2, 0x13c4, 0, {0x50,0x24} },
+{ 14, 0x13c6, 0, {0xea,0x24,0x00,0xfc,0xe4,0x34,0x18,0xfd,0xeb,0x2c,0xfc,0xe4,0x3d,0xfd} },
+{ 14, 0x13d4, 0, {0x74,0x04,0x2b,0x24,0xc0,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfe} },
+{ 8, 0x13e2, 0, {0x8c,0x82,0x8d,0x83,0xf0,0x0b,0x80,0xd7} },
+{ 14, 0x13ea, 0, {0xea,0x24,0x00,0xfa,0xe4,0x34,0x18,0xfb,0x74,0x10,0x2a,0xf5,0x82,0xe4} },
+{ 5, 0x13f8, 0, {0x3b,0xf5,0x83,0xe4,0xf0} },
+{ 1, 0x13fd, 0, {0x22} },
+{ 4, 0x13fe, 0, {0xe5,0x76,0x60,0x02} },
+{ 2, 0x1402, 0, {0x80,0x16} },
+{ 12, 0x1404, 0, {0x74,0x0f,0x55,0x75,0xfa,0x8a,0x75,0x24,0x00,0xf5,0x82,0xe4} },
+{ 10, 0x1410, 0, {0x34,0x19,0xf5,0x83,0xe0,0xf5,0x74,0x12,0x12,0xb4} },
+{ 10, 0x141a, 0, {0x12,0x10,0xca,0x75,0x6e,0x00,0x75,0x6f,0x00,0x12} },
+{ 6, 0x1424, 0, {0x11,0x44,0x75,0x70,0xb9,0x75} },
+{ 6, 0x142a, 0, {0x71,0x14,0x75,0x72,0x02,0x12} },
+{ 11, 0x1430, 0, {0x11,0x75,0xe5,0x76,0xb4,0x02,0x04,0x74,0x01,0x80,0x01} },
+{ 1, 0x143b, 0, {0xe4} },
+{ 3, 0x143c, 0, {0xfa,0x70,0x0f} },
+{ 12, 0x143f, 0, {0x74,0x01,0x25,0x75,0xf5,0x73,0xc0,0x02,0x12,0x11,0xa0,0xd0} },
+{ 3, 0x144b, 0, {0x02,0x80,0x0a} },
+{ 10, 0x144e, 0, {0x85,0x75,0x73,0xc0,0x02,0x12,0x11,0xa0,0xd0,0x02} },
+{ 12, 0x1458, 0, {0x75,0x6e,0x00,0x75,0x6f,0x01,0xc0,0x02,0x12,0x11,0x44,0xd0} },
+{ 4, 0x1464, 0, {0x02,0xea,0x70,0x1a} },
+{ 13, 0x1468, 0, {0x75,0xf0,0x11,0xe5,0x75,0xa4,0xfa,0x24,0x00,0xfa,0xe4,0x34,0x18} },
+{ 9, 0x1475, 0, {0xfb,0x8a,0x70,0x8b,0x71,0x75,0x72,0x01,0x12} },
+{ 4, 0x147e, 0, {0x11,0x75,0x80,0x36} },
+{ 2, 0x1482, 0, {0x7a,0x00} },
+{ 3, 0x1484, 0, {0xba,0x10,0x00} },
+{ 2, 0x1487, 0, {0x50,0x2f} },
+{ 13, 0x1489, 0, {0xea,0x24,0x00,0xf5,0x82,0xe4,0x34,0x19,0xf5,0x83,0xe0,0xfb,0xe5} },
+{ 4, 0x1496, 0, {0x75,0xb5,0x03,0x1b} },
+{ 14, 0x149a, 0, {0x75,0xf0,0x11,0xea,0xa4,0xfb,0x24,0x00,0xfb,0xe4,0x34,0x18,0xfc,0x8b} },
+{ 9, 0x14a8, 0, {0x70,0x8c,0x71,0x75,0x72,0x01,0xc0,0x02,0x12} },
+{ 4, 0x14b1, 0, {0x11,0x75,0xd0,0x02} },
+{ 3, 0x14b5, 0, {0x0a,0x80,0xcc} },
+{ 1, 0x14b8, 0, {0x22} },
+{ 6, 0x14b9, 0, {0x50,0x72,0x6f,0x67,0x20,0x00} },
+{ 14, 0x14bf, 0, {0xc8,0xc0,0xe0,0xc8,0xc0,0xe0,0xe5,0xf0,0x60,0x0b,0x14,0x60,0x0f,0x14} },
+{ 7, 0x14cd, 0, {0x60,0x11,0x14,0x60,0x12,0x80,0x15} },
+{ 7, 0x14d4, 0, {0xd0,0xe0,0xa8,0x82,0xf6,0x80,0x0e} },
+{ 5, 0x14db, 0, {0xd0,0xe0,0xf0,0x80,0x09} },
+{ 4, 0x14e0, 0, {0xd0,0xe0,0x80,0x05} },
+{ 5, 0x14e4, 0, {0xd0,0xe0,0xa8,0x82,0xf2} },
+{ 4, 0x14e9, 0, {0xc8,0xd0,0xe0,0xc8} },
+{ 1, 0x14ed, 0, {0x22} },
+{ 14, 0x14ee, 0, {0xc8,0xc0,0xe0,0xe5,0xf0,0x60,0x0d,0x14,0x60,0x0f,0x14,0x60,0x0f,0x14} },
+{ 6, 0x14fc, 0, {0x60,0x10,0x74,0xff,0x80,0x0f} },
+{ 5, 0x1502, 0, {0xa8,0x82,0xe6,0x80,0x0a} },
+{ 3, 0x1507, 0, {0xe0,0x80,0x07} },
+{ 4, 0x150a, 0, {0xe4,0x93,0x80,0x03} },
+{ 3, 0x150e, 0, {0xa8,0x82,0xe2} },
+{ 4, 0x1511, 0, {0xf8,0xd0,0xe0,0xc8} },
+{ 1, 0x1515, 0, {0x22} },
+{ 0, 0x0000, 1, {0} }
+
+};
+
+static unsigned char bitstream[] = {
+
+0x00,0x09,0x0F,0xF0,0x0F,0xF0,0x0F,0xF0, 0x0F,0xF0,0x00,0x00,0x01,0x61,0x00,0x0D,
+0x64,0x61,0x62,0x75,0x73,0x62,0x74,0x72, 0x2E,0x6E,0x63,0x64,0x00,0x62,0x00,0x0B,
+0x73,0x31,0x30,0x78,0x6C,0x76,0x71,0x31, 0x30,0x30,0x00,0x63,0x00,0x0B,0x31,0x39,
+0x39,0x39,0x2F,0x30,0x39,0x2F,0x32,0x34, 0x00,0x64,0x00,0x09,0x31,0x30,0x3A,0x34,
+0x32,0x3A,0x34,0x36,0x00,0x65,0x00,0x00, 0x2E,0xC0,0xFF,0x20,0x17,0x5F,0x9F,0x5B,
+0xFE,0xFB,0xBB,0xB7,0xBB,0xBB,0xFB,0xBF, 0xAF,0xEF,0xFB,0xDF,0xB7,0xFB,0xFB,0x7F,
+0xBF,0xB7,0xEF,0xF2,0xFF,0xFB,0xFE,0xFF, 0xFF,0xEF,0xFF,0xFE,0xFF,0xBF,0xFF,0xFF,
+0xFF,0xFF,0xAF,0xFF,0xFA,0xFF,0xFF,0xFF, 0xC9,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFB,0xFF,0xA3,0xFF,0xFB,
+0xFE,0xFF,0xBF,0xEF,0xE3,0xFE,0xFF,0xBF, 0xE3,0xFE,0xFF,0xBF,0x6F,0xFB,0xF6,0xFF,
+0xBF,0xFF,0x47,0xFF,0xFF,0x9F,0xEE,0xF9, 0xFE,0xCF,0x9F,0xEF,0xFB,0xCF,0x9B,0xEE,
+0xF8,0xFE,0xEF,0x8F,0xEE,0xFB,0xFE,0x0B, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xBF,0xFF,0xFF,0xFB,0xFF,0xFF, 0xBF,0xFF,0xFF,0xFC,0x17,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xFB,0xFF,0xFF,0x7F,0xFF,0xFF,
+0xFC,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x5F,0xFF, 0xFF,0xFD,0xFF,0xFF,0xDB,0xFF,0xFD,0xFF,
+0x77,0xFF,0xFD,0xFF,0xFF,0xDF,0xFE,0xFD, 0xFF,0xFF,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFD,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,
+0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xE3,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,
+0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x67,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0x7F,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF, 0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0x2F,0xFF,
+0xF3,0xFD,0xFF,0x7F,0xDE,0xF7,0xFD,0xFF, 0x7F,0xF7,0x7D,0xFF,0x7F,0xDF,0xF7,0xBD,
+0xFF,0x7F,0xFF,0x1F,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xEF,0xFB,
+0xFE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFF, 0x3F,0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,
+0x9F,0xE7,0xFA,0x7F,0x9F,0xE7,0xF9,0xFE, 0x7F,0x9F,0xE7,0xFF,0xFC,0x7F,0xBF,0xBF,
+0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xB7, 0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,
+0xFF,0xE0,0xFD,0xF9,0xFE,0x7F,0x9F,0xE7, 0xF9,0xFE,0x7F,0x9D,0xF9,0xFE,0x7D,0x9D,
+0xE7,0xF9,0xFE,0x7F,0x9F,0xED,0xED,0xFF, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,
+0xDF,0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF, 0x7F,0xDF,0xFF,0x9B,0xFF,0xEF,0xFB,0xFE,
+0xFB,0xBF,0xEF,0xBB,0xFE,0xFF,0xAF,0xBB, 0xBE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFF,
+0xB7,0xBF,0xDB,0xF6,0xBD,0xBF,0x6B,0xDB, 0xF6,0xF9,0xBF,0x5B,0xD6,0xF9,0xBF,0x6F,
+0xDB,0xF6,0xFD,0xBF,0xFF,0x0E,0xFF,0xFF, 0xFF,0xFF,0x5F,0xFF,0xF7,0xFF,0xFF,0x7F,
+0xF7,0xBD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xDF,0x9F,0xFF,0xFF,0xFF,0xFE,0xFF,
+0xFF,0xEF,0xFE,0xFE,0xFF,0xFF,0x77,0xFF, 0xFB,0xFB,0xFF,0xFF,0xFF,0xFF,0xF8,0x3F,
+0xFF,0xFD,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xF4,0x7F,0xFF,0xFE,0xFD, 0xBE,0xFF,0xDF,0xFE,0xFF,0xFF,0xEF,0x7F,
+0xFF,0xCF,0xFF,0xCF,0xFF,0xFF,0xFF,0xDF, 0xE6,0xFF,0xFF,0x7F,0xDF,0xF7,0xDD,0x7F,
+0x7F,0xDF,0xF7,0xFF,0x7F,0xDF,0xD7,0xFD, 0xFF,0x7F,0xDF,0xF7,0xFF,0xCD,0xFF,0xF2,
+0xFF,0xFF,0x4F,0x7F,0xF4,0xFF,0xFF,0xFF, 0xE7,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xBB,0xFF,0xEF,0xFF,0xFE,0xFF, 0xFF,0xFF,0xEF,0xFF,0xFF,0xEF,0xFF,0xFB,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x65, 0xEF,0xFF,0xFF,0x7F,0xFF,0xFD,0xEF,0xFF,
+0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xCF,0xDF,0xFE,0xFF,
+0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xF3,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFE,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xBF,0xFF, 0xFF,0xFF,0xE3,0x7F,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xEF,0xEB,0xFF,0xFE,0xBF,0xFF, 0xEB,0xFF,0xFC,0x7F,0xFF,0xFF,0xFF,0xEE,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF, 0xD6,0xFF,0xFD,0xBF,0xFF,0xFB,0xFF,0xFE,
+0xFD,0xFF,0xFF,0xFD,0xEF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xDE,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xBF,0xFF,0xFD,0xFF,0x7F,0xBF, 0xFF,0x5F,0xDF,0xFF,0xFF,0xBF,0x77,0xFF,
+0xFF,0xFF,0x7F,0xD7,0xFF,0xFF,0xFF,0xFF, 0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xDF,0xEF,
+0xFF,0xFF,0xFE,0xFB,0xFF,0xFF,0xDF,0xBF, 0xFF,0xFF,0xFF,0xFF,0xED,0xFF,0xB7,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xAF,0x7F,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xDF,0xBF,0xDF,0xF3,0xFD,0xFB,0xFF,0x5B,
+0xFD,0xFF,0xBF,0xEF,0xF7,0xFF,0xFF,0x7D, 0xFF,0xFF,0xFF,0xFF,0xF8,0x3B,0xFF,0xBF,
+0x6F,0xFF,0xFE,0xFF,0xBF,0xFF,0xEB,0x7D, 0xFF,0xEF,0xFB,0xFE,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xF2,0x7F,0xFC,0xFF,0x3F,0xDF,0xED, 0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0x5F,0xF7,
+0xB5,0xFF,0xEF,0xFF,0xFF,0xFF,0xE0,0x3F, 0x9F,0x9E,0xFF,0xFF,0xEF,0xFF,0xDF,0xFF,
+0xBF,0x5F,0xBF,0xCF,0xF3,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0x69,0xAF,0x33,0xFD,0xFF,
+0xFB,0xFF,0xFF,0xFF,0xFF,0xFC,0xFF,0x7F, 0xD9,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xF5,
+0xA3,0xDF,0x6E,0xDE,0xFF,0xFF,0xBD,0xFF, 0xFF,0xFE,0xFF,0xFF,0xFF,0xFE,0xE7,0xFD,
+0xFF,0xFF,0xFF,0xF9,0xEF,0xC6,0xFE,0xB7, 0xAD,0xE5,0xF9,0xFF,0xFF,0xFF,0xCF,0xFF,
+0xFF,0xFF,0xCD,0xFB,0x7F,0xFF,0xFF,0xFF, 0xF9,0xF6,0x0F,0xDF,0xEC,0xCF,0x7F,0xFF,
+0xFB,0x7F,0xFF,0xFF,0xFF,0xFD,0xFF,0xFE, 0xF9,0xFD,0x7F,0xFF,0x7F,0xFF,0xF9,0x5B,
+0xFF,0x73,0xDC,0xFD,0x7B,0xDF,0xFF,0xFF, 0xFF,0x7B,0xFF,0xFF,0xF7,0x53,0xD6,0xFF,
+0xFF,0xFF,0xFF,0xD8,0x9F,0xFE,0xFF,0xEF, 0x7F,0xEE,0xFF,0xFF,0xFF,0xFB,0xED,0xED,
+0xFD,0xFF,0xFE,0xFF,0xFF,0xFB,0x7F,0xFF, 0xE2,0x7F,0xFF,0x6F,0xD8,0x57,0xF7,0xFF,
+0xFF,0xFF,0xDF,0xFF,0xE8,0xFF,0xFF,0xFD, 0xFF,0xFF,0xFC,0x7F,0xFF,0xE4,0xFF,0xFB,
+0xEF,0xFB,0xFE,0xDF,0xB7,0xED,0xFF,0xFE, 0xDF,0x7F,0xFF,0xFE,0x7F,0xB7,0xFF,0xFF,
+0xFF,0xFF,0x89,0xFF,0xFF,0xCF,0xF3,0xFE, 0x7F,0xFF,0xEF,0xFF,0xFE,0x7E,0x7F,0xFB,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF1, 0xFF,0xEB,0x7A,0xD5,0xBF,0x6F,0xDB,0xBE,
+0xFD,0xB7,0xD8,0xF6,0xE5,0xBF,0x6F,0xFB, 0xFE,0xF5,0xBD,0x7E,0x06,0xFF,0xDF,0xF7,
+0xFB,0xF6,0xFF,0x3F,0xFF,0xDB,0xFF,0xFF, 0x6F,0xFB,0xF7,0xFF,0xFF,0xFF,0xFB,0xFE,
+0xF7,0xAF,0xFF,0xB7,0xED,0xEF,0xF7,0xFE, 0xFF,0xFF,0xDF,0xFF,0xFE,0xFF,0xEF,0xFF,
+0xFF,0xFF,0xFF,0xBF,0xF7,0xFC,0x1F,0xEE, 0xFB,0xFE,0xBD,0xFF,0x7F,0x5F,0xD7,0xFD,
+0xFB,0x43,0xFF,0xFF,0xFD,0xFF,0x5F,0xFF, 0xF7,0xFF,0xF9,0x3F,0xFF,0xCF,0xF3,0xFD,
+0xF7,0x7E,0xEF,0xA7,0xF9,0xFE,0x8F,0xA7, 0xE9,0xF3,0x7E,0x9F,0xFB,0xF8,0xFF,0xFF,
+0x3F,0xFD,0x7F,0x5F,0xDF,0xFD,0xFF,0xFF, 0x5F,0xFF,0xFD,0x5F,0xFF,0xFF,0x7F,0xFD,
+0x7F,0xFD,0x9F,0xFF,0xE0,0xFF,0xFA,0xF8, 0xBE,0x6F,0x9F,0xE6,0xF8,0xBE,0x3F,0x9A,
+0xF9,0xBE,0x6F,0x9F,0xE2,0xF9,0xFE,0x6F, 0x9F,0xF9,0xFF,0xF5,0xFD,0x7F,0xCF,0xDF,
+0xFD,0xFD,0x7F,0xFF,0xF5,0xFF,0xFF,0xFF, 0xF7,0xF5,0xFD,0x0F,0xDB,0xFF,0xD3,0xFF,
+0xEB,0xFA,0xFF,0xFF,0xBF,0xFF,0xFA,0xFF, 0xFF,0xCB,0xFB,0xFE,0xFF,0xFF,0xEB,0xFA,
+0xFE,0xFF,0xFF,0xB7,0xFF,0xFF,0xFF,0xFF, 0xBF,0xFF,0xDF,0xF5,0xFF,0xFF,0xD7,0xFF,
+0xFF,0xFF,0xDF,0xD7,0xF5,0xFF,0x7F,0xFE, 0x4F,0xFF,0xFD,0xFF,0x7F,0x7F,0xFF,0xAD,
+0xEB,0xFB,0xFF,0xAD,0xFF,0xFF,0xFF,0xFF, 0xAF,0xEB,0xFB,0xFF,0xFC,0x0D,0xFF,0xFF,
+0xDF,0xD2,0xFD,0xFF,0xFF,0xFD,0xF6,0xFF, 0xFF,0x7F,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,
+0xFF,0xFB,0x3F,0x7D,0xEB,0x32,0xFE,0xBF, 0x2F,0xEB,0xFA,0xAE,0xBD,0xE0,0xFA,0x7E,
+0xBF,0xAD,0xEB,0xFA,0xFE,0xBF,0xF5,0x7F, 0xFF,0xDE,0xFE,0xE3,0xFB,0xFF,0xFF,0xFF,
+0xDF,0xEF,0x4F,0xDF,0xFF,0x7F,0xDF,0xFF, 0xF7,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xEF,
+0xFB,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xDF, 0xED,0xFB,0xDF,0xFF,0xBF,0xFF,0xFF,0xFF,
+0x81,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF, 0xFF,0xFF,0xFE,0xDD,0xFE,0xEF,0xFD,0xFF,
+0xFF,0xFB,0xFE,0xF7,0xFF,0x93,0xFD,0xFB, 0x7E,0xFF,0xFE,0x87,0xE9,0xFF,0x7F,0xB3,
+0x9F,0xFE,0xFE,0xFF,0xAF,0xFD,0xFE,0x7E, 0x3F,0xFE,0x67,0xFF,0xFF,0xF7,0xFF,0xFF,
+0xFC,0xF7,0xDF,0xFD,0xFF,0x7F,0xFF,0xFF, 0x7F,0x6D,0xFF,0xFF,0xFE,0xFF,0xFF,0x2F,
+0xFF,0xBF,0xFF,0xFF,0xEE,0xFF,0xBE,0xFF, 0xFF,0xFE,0xFF,0xEF,0xFF,0xFF,0xFE,0xFF,
+0xEF,0xFF,0xFF,0xFA,0x5F,0xFF,0xFF,0xFB, 0xFF,0xFF,0xEF,0xFF,0xFB,0xFE,0xFD,0xFF,
+0xFE,0xFF,0xFB,0xFF,0xFF,0xFF,0x7F,0xFF, 0xFE,0xBF,0xDF,0xFF,0xFB,0xFF,0xFF,0xF7,
+0xFC,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF2,0x7F,0xFF,
+0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF, 0xF3,0xFF,0xFF,0xFF,0xEF,0xFB,0xFF,0xFF,
+0xFF,0xDF,0xE2,0xFF,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFB,0xE7,0xFF,0xFD,
+0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xED, 0xEF,0xFD,0xFF,0xFF,0xDF,0xD7,0xF5,0xFD,
+0x7F,0x5D,0xFD,0xFF,0x7F,0xDF,0x97,0xF4, 0xFD,0x7B,0x5F,0xFF,0xC9,0xFF,0xFB,0xFE,
+0xFF,0xBF,0xFF,0x5F,0xFF,0xFF,0xF7,0xFF, 0xEF,0xFD,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xF7,0xFF,0xD7,0xFD,0x7D,0x7F,0xFF, 0xFF,0xFF,0xFF,0xEF,0xDF,0xF7,0xFD,0xFF,
+0xBB,0xFF,0xFF,0x7F,0xFF,0xFE,0xE3,0xFF, 0xF9,0xFE,0x7F,0xBF,0xEF,0xFB,0xFE,0xFF,
+0xBF,0xF9,0xFE,0xFF,0x9F,0xEF,0xF9,0xFE, 0xFF,0xBF,0xF3,0xDA,0xFF,0x37,0xCD,0xF3,
+0x7C,0xDF,0x37,0xCD,0xF3,0x7F,0x37,0xCD, 0xF3,0x7C,0xDF,0x37,0xCC,0xF3,0x7F,0x5A,
+0xBD,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,0xFD, 0xBF,0x6F,0xDE,0xFD,0xBF,0x6F,0xDB,0xF6,
+0xFD,0xBF,0x6F,0xFE,0xF1,0x6F,0xEB,0x7A, 0xDE,0xB7,0xAD,0xEB,0x7A,0xDE,0xB7,0xAF,
+0x7A,0xDE,0xB7,0xAD,0xEB,0x7A,0xDE,0xB7, 0xFF,0x7E,0xFF,0xFE,0xCD,0xB3,0x6C,0xDB,
+0x36,0xCD,0xB3,0x6C,0xDE,0xCD,0xB3,0x6C, 0xDB,0x36,0xCD,0xB3,0x6C,0xDF,0xC9,0xBF,
+0xF7,0xBD,0xEF,0x7A,0x9E,0xA7,0xA9,0xEA, 0x7A,0xB7,0xBD,0xEA,0x7B,0xDE,0xA7,0xBD,
+0xCA,0x72,0x8D,0x91,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFE,0xF7,0xEF,0xFB,
+0xFE,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFE, 0x87,0xFF,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,
+0xFD,0xBF,0x6F,0xF6,0xFD,0xBF,0x6F,0xDB, 0xF6,0xFD,0xBF,0x6F,0xFE,0x4F,0xFF,0xBF,
+0xEF,0xBB,0xEE,0xFB,0xBE,0xEF,0xBB,0xEF, 0xBE,0xEF,0xBB,0xEE,0xFB,0xBE,0xEF,0xBB,
+0xEF,0xFC,0x5F,0xFF,0xFF,0xFF,0x3F,0xCF, 0xF3,0xFC,0xFF,0x3F,0xCF,0xFC,0xFF,0x3F,
+0xCF,0xF3,0xFC,0xFF,0x3F,0xCF,0xFD,0x9F, 0xFE,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,
+0xEB,0xFE,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF, 0xAF,0xEB,0xFF,0xE1,0x6F,0xFD,0xFF,0x7F,
+0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFD,0xFF, 0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,
+0x7A,0xBF,0xFB,0xFE,0xDF,0xB7,0xED,0xFB, 0x7E,0xDF,0xB7,0xFB,0x7E,0xDF,0xB7,0xED,
+0xFB,0x7E,0xDF,0xB7,0xFF,0xC9,0xFF,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,
+0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEE, 0xFB,0xFE,0xBB,0xFF,0xFE,0xFF,0xBF,0xEF,
+0xFB,0xFE,0xFF,0xBF,0xEF,0xFE,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0x3F,0xCF,0xFF,0xE7,
+0xFE,0xFF,0xF5,0xFD,0x77,0x5D,0xD7,0x35, 0xDD,0x77,0xD7,0xF5,0xCD,0x7B,0x5D,0xD7,
+0xF5,0xDD,0x77,0xFE,0x27,0xFF,0xFF,0x8B, 0xE2,0xF8,0xBE,0x2F,0x8B,0xE2,0xF9,0xAF,
+0x8B,0xE2,0xF8,0xBE,0x2F,0x8B,0xE2,0xF9, 0xFE,0x1F,0xFF,0x5F,0xD7,0xF5,0xFD,0x7F,
+0x5F,0xD7,0xF5,0xFF,0x5F,0xD7,0xF5,0xFD, 0x7F,0x5F,0xD7,0xF5,0xFF,0xFA,0x3F,0xFE,
+0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,0xEB, 0xEC,0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,
+0xEB,0xFF,0xFE,0x7F,0xFD,0x7F,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6, 0xFF,0xFA,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,
+0xF7,0xFC,0xFF,0xDF,0xF7,0xFD,0xFF,0x7F, 0xDF,0xF7,0xFD,0xFF,0xF5,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0x02,0xFF,0xFE,0xBF,0xAB,0xEB,0xFA, 0xBE,0xBF,0x23,0xEB,0xDE,0x1F,0xAF,0xEA,
+0xFA,0xFE,0xAF,0xAF,0xEB,0xFD,0x97,0xFF, 0xF3,0xFC,0x7B,0x1F,0xCF,0xF1,0xFC,0x7F,
+0x1F,0xF1,0xFC,0x77,0x1F,0xCD,0xF1,0xFC, 0xFF,0x1F,0xFE,0x87,0xFF,0xAF,0xEF,0xFA,
+0xFE,0xFF,0xAF,0xEF,0xFA,0xFD,0xBF,0x2B, 0xFB,0x7E,0xBF,0xBF,0xEB,0xFB,0xFB,0xFB,
+0xDF,0xFF,0xFB,0xF7,0xFF,0xFF,0x7F,0xF7, 0xF7,0xFF,0xFD,0xDF,0xFE,0xFC,0xDF,0xFF,
+0xDF,0xFF,0xFD,0xFF,0xDA,0xBF,0xFF,0xBB, 0xEF,0xFB,0xF9,0xFF,0xBE,0xEF,0xFB,0xFB,
+0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xF7,0x7F,0xFD,0xD7,0xFF,0xFF,0x7F,
+0xFF,0xFF,0xFF,0xFE,0xF7,0xFF,0xFE,0xFF, 0xF7,0xFF,0xFF,0x7F,0xFF,0xFF,0xEC,0xFF,
+0xFF,0xFE,0xDF,0xBF,0xFF,0xFB,0xFE,0xFF, 0xBB,0x68,0xAE,0x1F,0xAE,0xFB,0xFB,0xFF,
+0xFF,0xBF,0xFF,0xD5,0xFF,0x7F,0xFF,0xFF, 0xF7,0xFE,0xFE,0xFF,0xBF,0xEF,0x9F,0xFD,
+0x7F,0xFF,0xCB,0xFF,0xFF,0xDF,0xFF,0xFF, 0xBB,0xF7,0xBF,0xFF,0xFF,0xFF,0xFF,0xDF,
+0xFF,0xBF,0xFB,0xFF,0xFF,0xFF,0xDE,0x3F, 0xFF,0xFF,0xFF,0xFF,0xFF,0xA7,0xFF,0xFF,
+0xFF,0xFF,0xEF,0xFF,0x7F,0xFB,0xFD,0xFB, 0x7F,0xFF,0xFF,0xFF,0xFF,0xCF,0xF3,0x7C,
+0xFF,0x7F,0x8D,0x7F,0xFF,0xFF,0xFF,0xFF, 0xFB,0xFF,0xF7,0xFB,0xFE,0xFD,0xFF,0xFF,
+0xFF,0xFF,0xF7,0xFD,0xFF,0x7F,0xFD,0x1F, 0xFD,0xFF,0xFF,0xFF,0xFF,0xBF,0xDF,0xFF,
+0xFF,0xFE,0x5C,0xFF,0x6D,0xFF,0x7F,0xAB, 0xE7,0xF1,0xFF,0xFD,0x9F,0xFF,0xFF,0xAD,
+0xEB,0x7A,0x3F,0x1F,0xFF,0xFF,0xFE,0xBF, 0xAF,0xF3,0xDE,0xF5,0xFF,0x8F,0xFB,0xDF,
+0xE6,0x7F,0xFF,0xDF,0xF3,0xFD,0xFF,0x7E, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xF7,0xF3,
+0x7F,0xDF,0xF7,0xEF,0xFF,0xF6,0x3F,0x9F, 0xDF,0xFF,0xFF,0xEE,0xFF,0xFF,0xEF,0xFB,
+0xFF,0xFF,0xF9,0xFB,0xFE,0x4F,0xBF,0xEF, 0xBB,0xFF,0x69,0xAF,0xAF,0xFC,0xFF,0x3F,
+0xDD,0xFF,0xFC,0xBF,0x8F,0xFF,0xFD,0xF3, 0xBF,0xED,0x9E,0xFC,0xBF,0x6F,0xF5,0xD3,
+0xDF,0xFF,0xDB,0xD6,0xF5,0xEF,0xFD,0xFE, 0xFF,0xB9,0xFF,0x1F,0xD2,0xA9,0xAF,0xFF,
+0xDB,0xF7,0xBF,0xEF,0x46,0xFF,0xFF,0xAD, 0xEB,0x7A,0xDF,0xEF,0xF7,0xFF,0x7F,0xF7,
+0x9F,0xED,0xFF,0x7F,0xFF,0xAD,0xEB,0x7F, 0xF5,0x6F,0xFF,0xFD,0xFB,0xD6,0xF4,0xF7,
+0xFB,0xF9,0x7E,0x7F,0xFF,0x5F,0xC2,0xFE, 0xBF,0xFD,0xFB,0x33,0xDF,0xF9,0x5B,0xFF,
+0xFF,0xDD,0x67,0x7D,0xCF,0xEF,0xDB,0xEC, 0xFF,0x77,0xDD,0xF7,0xFD,0xFF,0xFF,0xDE,
+0xA7,0xBF,0xD4,0x9F,0xFF,0xFF,0xBF,0xEF, 0xFE,0xFF,0xDF,0xEF,0xBB,0xFF,0xFF,0xEF,
+0xEB,0xFA,0xFF,0xEF,0xBD,0xFB,0xFF,0xE2, 0x7F,0xFF,0xDF,0xDF,0xF7,0xFD,0xBF,0xBB,
+0x73,0xF7,0xFD,0x7F,0xDF,0xDE,0xF7,0xBF, 0xEA,0xDB,0xF6,0xFF,0xD6,0xFF,0xFF,0x66,
+0xFF,0xBE,0xFF,0xBF,0x6B,0xD9,0xF6,0xDF, 0xFF,0xFB,0x7E,0x7F,0xB7,0x7E,0xFF,0xFE,
+0xFF,0xCD,0xFF,0xFE,0x7F,0xFF,0xFC,0xFD, 0x3F,0xFB,0xFB,0xF7,0xFF,0xFF,0xFB,0xF6,
+0x7D,0xFE,0x7F,0xFF,0xFC,0xFF,0xB9,0xFF, 0xF9,0xFA,0xFE,0xBF,0xAF,0x5B,0xD6,0xED,
+0xAD,0x7B,0xF6,0xF9,0xBF,0xEF,0xF8,0xFA, 0xFE,0xBF,0xFE,0xE6,0xFF,0xFF,0xF7,0xFD,
+0xFF,0x7F,0xBF,0xEF,0xF3,0xFF,0xFF,0x6F, 0xF7,0xFE,0xFF,0xFF,0xF7,0xFD,0xFE,0xF7,
+0xEF,0xFF,0xFB,0xEF,0xFB,0x7E,0xDE,0xFE, 0xFF,0xBF,0xFF,0xFE,0xFF,0xFF,0xFB,0xFF,
+0xFF,0xEF,0xFB,0x6F,0xFC,0x1F,0xFE,0xE7, 0xFF,0xFF,0xFF,0xEF,0xFF,0xD3,0xB4,0xBB,
+0xFF,0xFF,0xFD,0xBF,0x6F,0xE3,0xFE,0xFF, 0xBF,0xFC,0xBF,0xF7,0xCF,0xF7,0xFD,0xFF,
+0x2F,0xDF,0xAB,0xEA,0xFF,0xDF,0xE7,0xEA, 0x9A,0xAF,0xEF,0xFB,0xFE,0xFF,0xF5,0x3F,
+0xFD,0x7E,0xFF,0xD7,0xF5,0xFB,0xFF,0xFD, 0xF7,0xFF,0x7F,0xFE,0xF7,0xFD,0xFF,0xD7,
+0xFF,0xD7,0x7F,0xEE,0x7F,0xFA,0x79,0xFE, 0x2F,0x8B,0xE6,0xF9,0xFE,0x3F,0x9E,0xF9,
+0xBE,0x2F,0x0B,0xE7,0xF9,0xFE,0x2F,0x9F, 0xFD,0xFF,0xFE,0x7D,0x7F,0x5F,0xD7,0xFF,
+0xFF,0x7F,0xFF,0xFD,0xFF,0x7F,0x5F,0x97, 0xFF,0xFD,0x7F,0x5F,0xFF,0xE3,0xFF,0xFF,
+0xFA,0xFE,0xBF,0xAF,0xFB,0xFB,0xFF,0xFF, 0xCF,0xEB,0xFE,0xBF,0xAF,0xFF,0xFA,0xFE,
+0xBF,0xFF,0x87,0xFF,0xFF,0xF5,0xFF,0xFF, 0xFF,0xFF,0xFD,0xFF,0x7F,0xFF,0xFF,0xFF,
+0xFB,0xFF,0xFF,0xF5,0xFF,0xFF,0xFE,0x0F, 0xFF,0xFD,0xEB,0xFF,0xFF,0xF7,0xFF,0xEF,
+0x7B,0xDF,0xFE,0xFF,0xFF,0xDF,0xF7,0xFD, 0xEB,0x7F,0xDF,0xFF,0x5F,0xFF,0xFF,0xFF,
+0xFF,0xFD,0xBF,0xFF,0x7E,0xFA,0xBF,0xC7, 0xDB,0xF7,0xBD,0x3F,0xFB,0xFF,0xF6,0xFF,
+0xFA,0xAF,0xFF,0xEB,0xFA,0xFE,0x3F,0x2F, 0xEA,0xFA,0x3E,0xAD,0xC9,0xBA,0xF6,0xAD,
+0xAF,0xEB,0xFA,0xF6,0xBF,0xFE,0x7F,0xFF, 0xFF,0xFD,0xFF,0xF1,0x7F,0x3F,0xCF,0xF1,
+0xEF,0xFF,0x7F,0xFF,0xBC,0xDF,0xDF,0xF7, 0xDD,0xFF,0xE0,0x7F,0xFF,0xFF,0xFE,0xFF,
+0xFA,0xEC,0xBB,0x7F,0x5F,0xFF,0xFB,0xEC, 0xFF,0xEF,0xB7,0xFF,0xF7,0xFF,0xFF,0xB5,
+0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xEE,0xDF, 0x5F,0xDF,0xDE,0xFF,0xAE,0xE7,0x77,0xFF,
+0xFF,0xDF,0xF7,0xFF,0xE3,0xFF,0xFA,0xBB, 0xFE,0xFF,0xAF,0xFD,0xFB,0xFE,0xBF,0xAB,
+0xF9,0xFE,0xFF,0xBF,0x7F,0xBF,0xFE,0xBD, 0xFE,0xD7,0xFF,0x9F,0xFD,0xFF,0xBE,0xEF,
+0xFF,0xEE,0xFD,0xBB,0x5B,0xEF,0xFF,0x7F, 0xEF,0xFF,0xEF,0xFF,0x7F,0xFF,0x4F,0xFF,
+0xEF,0xFB,0xBC,0xFC,0xFF,0xFF,0xFF,0xFE, 0xFE,0xFD,0xFA,0xFE,0xFB,0xFF,0xFD,0xF3,
+0xFB,0xFF,0xF8,0x5F,0xFF,0xFF,0xD7,0xF5, 0xFD,0xDF,0xEF,0xFF,0xF3,0xDC,0x5F,0xCE,
+0xF5,0xBD,0xFF,0xFF,0xD7,0xFF,0xFF,0xF9, 0x3F,0xFF,0xDF,0xF7,0xFF,0xFE,0xFF,0xFD,
+0xFF,0xFB,0xFF,0xF7,0xB9,0x7D,0xFE,0xDF, 0xFF,0xFF,0xFF,0xFF,0xF9,0x7F,0xFF,0xFE,
+0xFF,0xFF,0x7F,0xFF,0xFE,0xFF,0xFF,0xF7, 0xF6,0xFF,0xBF,0xF1,0xF8,0xFF,0xFF,0xFF,
+0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF, 0xFF,0xFF,0xFF,0xFF,0xEF,0xEF,0xFF,0xFF,
+0x9B,0xFB,0x7F,0xFF,0xFF,0xFF,0xC1,0xFF, 0xDF,0xFF,0x3F,0x5F,0xD7,0xBF,0xEF,0xBB,
+0xDE,0xEE,0xFF,0x7F,0xDF,0xFF,0xFE,0xF5, 0x7F,0xDF,0xFF,0x99,0xFF,0xFF,0xFA,0xFF,
+0xBF,0xFD,0xEB,0x7A,0xFF,0xB7,0xFE,0xFE, 0xFF,0xFF,0xEF,0xFF,0xFF,0xFD,0xBF,0xFF,
+0x97,0xFF,0xFD,0xF7,0xFF,0x7F,0xF7,0xFF, 0xFF,0xFD,0x5F,0xFE,0xF3,0xF9,0xDF,0xDF,
+0xFF,0xFF,0xFC,0xFF,0xFF,0x83,0xFF,0xFF, 0xFE,0xFF,0x9E,0xEC,0xFB,0xEE,0xFF,0x9F,
+0xBF,0xEF,0xFF,0xFE,0xED,0x7B,0xFF,0xFF, 0xFF,0xF1,0x5A,0xFF,0xFF,0xFD,0xFF,0x7C,
+0x69,0x3B,0xDF,0xFF,0x7F,0x1F,0xDF,0xFF, 0xFD,0xBA,0xFF,0xFF,0xFB,0xFF,0x5B,0xBD,
+0xFF,0xFF,0xFF,0xFF,0xD7,0xB6,0xED,0xE9, 0xFF,0xD6,0xBD,0x6F,0x5F,0xFB,0xFF,0xEF,
+0xFF,0x5F,0xFE,0xF6,0x6F,0xFF,0xFF,0xFF, 0xFF,0xF7,0xEB,0x7A,0xDF,0xFF,0x9F,0x7F,
+0x7F,0xFF,0xB7,0xFF,0xFF,0xFE,0xDF,0xFF, 0x6C,0xFF,0xFB,0xFF,0xBB,0x6F,0xEB,0xFE,
+0xCC,0xF7,0xA5,0xFA,0x5C,0xF5,0x75,0xBB, 0xB7,0xDF,0xFE,0x6F,0x5F,0xC5,0xBF,0xFD,
+0x7B,0xFE,0xFF,0x95,0xE7,0x29,0xCF,0x4F, 0xF5,0x91,0xEE,0x6B,0xDF,0xEF,0xFD,0x54,
+0xF5,0xBD,0xB1,0xFF,0xEF,0xEE,0xFB,0xBE, 0xBF,0xAF,0xFE,0xDE,0xBD,0x6F,0xDA,0xF2,
+0xFF,0xAF,0xBE,0xFF,0xFF,0xFD,0x7E,0xA7, 0xFF,0xF7,0xFF,0xBF,0xEF,0x7B,0xF6,0xFD,
+0xBD,0x4A,0xF2,0x85,0x85,0xBF,0x5B,0xFE, 0xB5,0xFD,0xFA,0xFF,0x4F,0xFF,0xFE,0xDF,
+0xFF,0xED,0xFF,0xBF,0xFF,0xBF,0x7F,0xFE, 0xFF,0xB7,0x6D,0xFF,0xF7,0xBF,0xBF,0xEF,
+0xFD,0x1F,0xFF,0xFE,0x7D,0xFF,0x67,0xFF, 0xFF,0xFF,0x3F,0x7F,0xFE,0xBF,0xFF,0xE7,
+0xDF,0xE7,0xFF,0xEF,0x6B,0xFC,0x1F,0xFF, 0xBF,0xEF,0xFB,0xFE,0xDE,0xBF,0xAF,0xFA,
+0xFF,0xB6,0xEF,0xF9,0xFE,0xFF,0x8F,0xEF, 0xDB,0xEF,0xAB,0x6F,0xFB,0xFE,0xFF,0xFF,
+0xEF,0xFD,0xFF,0x7F,0xFF,0xFF,0xDE,0xFF, 0xFF,0xEF,0xFF,0xFF,0xFF,0x3F,0xFF,0x6C,
+0xFF,0xBF,0xFB,0xFF,0xFE,0xFF,0xFB,0xFE, 0xDF,0xFF,0xFF,0xEF,0xFF,0xFF,0xBF,0xFF,
+0xFF,0xFE,0xFB,0xFF,0xD5,0x7F,0xFF,0xFF, 0xEF,0xFB,0xFF,0xFF,0xBF,0xEF,0x43,0xB5,
+0xFD,0x6F,0xCF,0xD6,0xBE,0x3F,0x7F,0xDB, 0xFE,0xC3,0xFF,0xFD,0xFF,0xAF,0xEB,0xFB,
+0xFC,0xFF,0x3E,0xEF,0xE8,0xFA,0xBD,0xCD, 0xAA,0xFE,0xFE,0x7D,0xCF,0xFF,0xB7,0xFF,
+0xF7,0xFF,0xFF,0xFF,0xFD,0xFF,0x75,0xCD, 0x52,0xD7,0xFD,0xFB,0xF7,0xDD,0xFB,0xEF,
+0xEB,0xFF,0xFF,0x4F,0xFF,0xBF,0x9F,0xE7, 0xF9,0xFC,0x7F,0x8B,0xC3,0xF9,0xAF,0x8F,
+0xE7,0xE9,0xBE,0x7F,0x9F,0xE6,0xF9,0xFC, 0x5F,0xFF,0xFF,0xF7,0xFD,0xFF,0x7A,0x5F,
+0xD7,0xED,0xFF,0xFF,0xD7,0xFF,0xDD,0x7F, 0xE7,0xFF,0xFC,0xFF,0xFC,0x3F,0xFF,0xFF,
+0xFF,0xFB,0xFF,0xFE,0xBF,0xAF,0xFF,0xFD, 0xFF,0xEF,0xFF,0xEB,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xF7,0x7F,0xFF,0x7F,0xDF,0xFF,0xFD, 0xFD,0x7F,0xFE,0xF7,0xFD,0x7F,0xDF,0xFF,
+0xFD,0xFF,0xFF,0xDF,0xFB,0xFF,0xEE,0xFF, 0xFB,0xFF,0xF7,0xFD,0xFF,0x7A,0xDF,0xF5,
+0xFD,0xFA,0xDF,0xF7,0xFC,0xFF,0x7F,0xDF, 0xBF,0xED,0xFF,0xC9,0xFF,0xDF,0xFF,0xBF,
+0x2F,0xFB,0xFF,0xBC,0xAD,0xFF,0xF7,0xFF, 0xFF,0xEF,0xD3,0xFF,0x7D,0xBF,0x6F,0xFF,
+0xFA,0xFF,0xFE,0xBF,0xAE,0xEA,0xFA,0xBE, 0xAD,0xA5,0xEB,0xCE,0xBF,0xA7,0xEB,0x5A,
+0xDE,0xBD,0xAF,0x6B,0xFD,0x57,0xFF,0xFF, 0xF4,0x7F,0x1F,0x7F,0xFD,0xFF,0x7F,0x36,
+0xF0,0xDF,0x79,0xFF,0xFF,0xFF,0xF7,0xFD, 0xBF,0xFF,0x87,0xFF,0xFB,0xF3,0xFC,0xFF,
+0xFF,0xFF,0xFF,0x7E,0xFF,0xBF,0xDF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,0xF8,0x9F,
+0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFD, 0xF7,0xFC,0xBD,0xFF,0xFE,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFB,0xF9,0xBF,0xFF,0xFF,0xEB, 0xE2,0xFE,0xFF,0xBF,0xEF,0xA9,0xBA,0x2F,
+0xEB,0xF9,0xFE,0x77,0xDF,0xF7,0xFF,0xFF, 0xF9,0x7F,0xFF,0xFF,0x7F,0xEF,0xD7,0xFF,
+0xFD,0xFF,0xFB,0xF5,0xFF,0xBF,0x6F,0xDF, 0xFF,0xFF,0xFD,0xFF,0xFF,0xF0,0xFF,0xFF,
+0xFF,0x3F,0xCF,0xFF,0xBA,0xEE,0x9B,0xBF, 0xEE,0xD7,0xFE,0xCD,0xEF,0xFF,0xDF,0xBF,
+0xFF,0xFF,0xC5,0xFF,0xFF,0xFD,0x7F,0x4F, 0xFD,0xF6,0xD9,0xFF,0x4F,0xD6,0xFD,0xBF,
+0x6E,0xFF,0xFF,0xF4,0x7F,0xFF,0x7F,0x8B, 0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xF9,0xFE,
+0x37,0xFF,0xD9,0xFB,0xF5,0xAF,0xFD,0xFF, 0xFF,0xFB,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,
+0xFB,0xF7,0xFF,0xFD,0xFF,0x7C,0xFA,0x7E, 0x4F,0xFC,0xDF,0x1D,0xC7,0xFF,0xFF,0xFF,
+0xFF,0xAE,0xFF,0xFF,0xFF,0xFF,0xFD,0xFB, 0xFF,0xFF,0xFE,0xFE,0xFC,0xFF,0x7F,0x7F,
+0xBF,0xEF,0xFE,0xFF,0xFF,0xFF,0x5F,0xFD, 0xFF,0xFF,0xFF,0xFD,0x6F,0x5A,0xD7,0x7B,
+0xBE,0x5F,0xFE,0x39,0xFF,0xF7,0xFF,0xF7, 0xFD,0xFE,0xAA,0x1F,0xFF,0xFF,0xFF,0xFF,
+0xFE,0xFE,0xAB,0xAF,0xFD,0xFE,0xBF,0xFF, 0xF7,0xFF,0x7F,0xFE,0x8F,0xE3,0xFB,0xEE,
+0x7F,0xFF,0xFF,0xFF,0xFF,0xEB,0xFB,0xFF, 0xFD,0xBF,0xEF,0xDF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFB,0xE4,0x3F,0xFF,0xDF, 0xFF,0xFF,0xFF,0xFF,0xF3,0xEF,0xBB,0xFB,
+0xBF,0xEF,0xBB,0xFF,0xD7,0xBF,0xFF,0xFF, 0xFF,0x29,0xAF,0xF7,0xFF,0xFF,0xFB,0xFF,
+0xFB,0xE6,0xFF,0x0F,0xFB,0x3F,0xDF,0x0F, 0xFF,0xAF,0xFF,0xFF,0xFF,0xF5,0xC3,0xDF,
+0x5F,0xFF,0xFF,0xFF,0xFE,0x6B,0xCA,0xBE, 0xBC,0xFF,0x9F,0xF2,0xBF,0xFF,0xFE,0xFA,
+0xFF,0xFF,0xEF,0x16,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFC,0xDF,0x97,0xFD,0x79,0xFF,0x37,
+0xE7,0x7F,0xFF,0xFF,0xB5,0xFF,0xFF,0xF6, 0x2F,0xFF,0xFD,0xFB,0xFE,0xFF,0xFF,0xFD,
+0x5F,0x57,0x5F,0xFF,0xDB,0x52,0xDF,0xFF, 0xFD,0xBF,0xFF,0xFF,0xFC,0xDB,0xFF,0x7B,
+0xB5,0xFD,0x7F,0xFF,0x71,0x9C,0x6E,0xFF, 0xF6,0x35,0xA5,0x9B,0xFF,0xFF,0xFD,0xFF,
+0xFF,0xDB,0x9E,0x7F,0xFE,0xEF,0xFB,0xFF, 0xFF,0xBD,0xEF,0xFF,0xDE,0xB7,0xF9,0x4B,
+0xFF,0xF5,0xEF,0xFF,0xFF,0xFF,0xE8,0x7E, 0xFF,0xEA,0xDF,0xF7,0xFF,0xFD,0x69,0x5B,
+0xFC,0x9F,0xEF,0x78,0xD6,0xFF,0xEB,0xEF, 0xFF,0xFF,0xFF,0xE8,0xFF,0xFF,0xED,0xFF,
+0xFF,0xFF,0xFF,0xE3,0xF9,0xF6,0xBF,0xFF, 0xFF,0xFE,0xDF,0xFF,0x7F,0xFF,0xFF,0xFF,
+0xD1,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF, 0xE7,0xF9,0xFF,0xBF,0x7F,0xD9,0xFF,0xFD,
+0xFE,0x7F,0xFF,0xFE,0xFF,0xF9,0xFF,0xFB, 0xD6,0xDF,0xBF,0xEF,0x5B,0xD6,0xFF,0xBF,
+0xFB,0xF6,0xFF,0xBF,0xEF,0xF8,0xF6,0xDD, 0xBE,0xFE,0x16,0xFF,0xBF,0xEF,0xFF,0xFE,
+0xFF,0xBF,0xEF,0xFF,0xFF,0xFF,0x6F,0xFB, 0xFF,0xFF,0xFF,0x6F,0xF3,0xFF,0xF7,0xEF,
+0xFB,0xFF,0xBF,0xFF,0xEF,0xFE,0xFF,0xBF, 0xFF,0xFF,0xFF,0xBE,0xBF,0xFF,0xEF,0xFF,
+0x7F,0xEF,0xFF,0xFD,0x17,0xFB,0x7B,0xFF, 0xFF,0xFD,0x7F,0xDB,0xF6,0xF4,0x7F,0xFA,
+0xFE,0xF5,0xBF,0xEB,0xE3,0xF7,0xFF,0xFF, 0xE9,0xBF,0xFF,0xAF,0xF7,0xFD,0xF3,0x7E,
+0x8F,0xA3,0xEA,0xFF,0xCB,0xF3,0xEE,0xFF, 0xBF,0xEF,0xF7,0xF9,0xFF,0xFE,0x7F,0xFF,
+0xFF,0xFF,0xFF,0xF5,0xFB,0xF6,0xFF,0xF5, 0x2F,0xFE,0xFB,0xD7,0xBF,0xFF,0xBE,0xDF,
+0x9F,0xFF,0xF0,0xFF,0xFF,0xF9,0xFE,0x7F, 0x8F,0xA3,0xF8,0xFE,0x6F,0x9F,0xF9,0xF6,
+0x2F,0x9F,0xE7,0xF9,0xFE,0x2F,0x9F,0xE1, 0xFF,0xFF,0xFF,0x7F,0xDF,0xF7,0xF5,0xFD,
+0x7F,0x7F,0xF5,0xFF,0x9F,0x5F,0xFB,0xFE, 0xFF,0x7F,0xFF,0xFF,0xCB,0xFF,0xFF,0xFB,
+0xFE,0xFF,0xBF,0xAF,0xFB,0xFE,0xFF,0xDF, 0xFE,0xFE,0xBF,0xF7,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xC7,0xFF,0xFF,0xFD,0xFF,0x7F,0xDD, 0xF7,0xFD,0xFF,0xFF,0xD7,0xFF,0xFD,0x7F,
+0xFF,0xFB,0xFD,0xFF,0xFF,0xFE,0xEF,0x7F, 0xFD,0xEF,0xFB,0xFE,0xFB,0xFD,0xFF,0x7F,
+0xDF,0xFD,0xFF,0x7A,0xDF,0xF7,0xFD,0xFF, 0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xD3,0xF7,
+0xFF,0xFF,0x6F,0xDB,0xFF,0xFF,0xEF,0xCB, 0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+0x29,0xFF,0xE8,0xDA,0x76,0x9F,0xAF,0x6A, 0xDA,0xFE,0x35,0xEB,0xDA,0xD6,0xBF,0xAB,
+0xEB,0x7A,0xDE,0xBF,0xD7,0x7F,0xFF,0xFE, 0xFF,0xBF,0xEF,0xFD,0xDF,0x77,0xBF,0xFD,
+0x37,0xEF,0xFF,0xEF,0xFF,0x3F,0xFF,0xFF, 0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xF7,0x7E,
+0xDF,0xFF,0xFF,0xFF,0xFA,0xB7,0x7F,0xFF, 0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0x89,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x9F,0xFB,0xFF,0xFF,0xFF,0xE7,0xFF,
+0xFF,0xFF,0xFF,0xAA,0xFF,0xAB,0xFB,0xFA, 0xEF,0xBF,0xFF,0xDF,0xFA,0x7B,0xB9,0xFE,
+0xFE,0xFF,0xFD,0xFF,0xF7,0xFE,0x3F,0xFF, 0xB7,0xFF,0xF7,0xEE,0xFF,0x7F,0xEF,0xFF,
+0xFF,0x7F,0xFF,0x1F,0xFB,0xFF,0xBF,0xFB, 0xFE,0xFF,0xBD,0xFF,0xFF,0x2F,0xFF,0xBF,
+0xFF,0x7F,0xDF,0xFA,0xFF,0xFF,0xFC,0xEE, 0xF5,0xF3,0xBE,0xFB,0x0F,0xEF,0xF3,0xBE,
+0xEF,0xFC,0x5F,0xFF,0x5A,0xFF,0xF7,0xDF, 0xFF,0xFF,0xFE,0xD5,0xFC,0x5F,0xFB,0xF2,
+0xFF,0xFF,0x2F,0xBB,0xF3,0xFF,0xFF,0xBF, 0xFF,0xEF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,
+0xBF,0xFF,0xFF,0xFD,0x7B,0xFF,0xDF,0xB9, 0xFF,0xFB,0xFF,0xD8,0x7F,0xFF,0xFF,0xFF,
+0xFB,0xFF,0xFC,0x7F,0x1F,0xBF,0xE0,0xDF, 0xF7,0xEF,0xFF,0xFD,0x7F,0xFE,0xDF,0xFF,
+0xE0,0xFF,0xFF,0xFD,0xEF,0xFB,0xFF,0xFE, 0xF7,0xDF,0xFF,0xEB,0x5F,0xFF,0xF7,0xFF,
+0xFF,0xFF,0xFF,0xBF,0xFF,0xFD,0xFF,0xFD, 0xFF,0xFF,0xFF,0xF7,0xFD,0xFF,0x3B,0xDC,
+0xFD,0x6D,0x7B,0x5F,0x57,0xF5,0xFD,0x7F, 0x5F,0xFF,0xB1,0xFF,0xEB,0xFF,0xFF,0xFF,
+0xFB,0xFB,0xFE,0xFF,0xBF,0xFB,0xBE,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFF,0xAF,0xFE,0xF7,
+0xDF,0xDF,0xFF,0xFF,0xFF,0x7F,0xCF,0xF3, 0xF8,0xFF,0xD7,0xFB,0xFF,0x5F,0xBF,0xF7,
+0xFB,0xFF,0x7F,0xFE,0x23,0xFF,0xFF,0xFE, 0x7F,0xF3,0xFF,0xFB,0xFE,0xFF,0xFF,0xF3,
+0xFF,0xFF,0xF5,0xF9,0xFF,0x3F,0xFF,0xFF, 0xF0,0x9A,0xFF,0xBE,0x7F,0xFF,0xFC,0xF9,
+0xFF,0xFD,0xAF,0xEB,0xFE,0xBF,0xFF,0xCF, 0xF3,0xFE,0x7F,0xFF,0xFF,0x5B,0xBD,0xFF,
+0xBC,0xEB,0xFF,0xD7,0xD4,0xAF,0xAF,0xFD, 0xFF,0xCF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7,
+0xFD,0xFE,0xFF,0x6F,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFD,0x7F,0x5E,0xFD,0xBF,0xDB,0xF6,
+0xFD,0xBF,0x6F,0xFB,0xEE,0xFD,0xFF,0x7A, 0xFF,0xFA,0xFB,0xFF,0x3F,0xFB,0xB7,0x5F,
+0xD6,0xF7,0x1F,0x71,0xDC,0x77,0x1D,0xC7, 0x31,0xDC,0x77,0xDF,0xF9,0xBF,0xF5,0x5B,
+0xF4,0xD7,0x9D,0xAE,0xFF,0xBF,0xFD,0xBF, 0xDB,0xF6,0xFD,0xBF,0x6F,0xDB,0xF6,0xFE,
+0x3D,0x81,0xFF,0xEB,0xFE,0xFE,0xFE,0xFF, 0xEB,0x7A,0xDF,0x7D,0x77,0x7D,0xF5,0x79,
+0xDF,0x57,0xDD,0xF5,0x7D,0x7E,0xE6,0xFF, 0xD6,0x3F,0xBF,0x7F,0xFF,0xD4,0xF5,0x3F,
+0xBF,0xFB,0xBE,0xEF,0xB3,0xEE,0xFB,0x9E, 0xEF,0xBB,0xFE,0x8B,0xFF,0xFE,0xDF,0xB7,
+0xED,0xFF,0xF7,0xFD,0xFE,0xFF,0xEF,0xBB, 0xEE,0xFF,0xBE,0xEF,0xBB,0xEE,0xEB,0xFC,
+0x1F,0xFF,0xFF,0xFD,0xFF,0xE7,0xFF,0xF7, 0xFD,0xFF,0xEF,0xFE,0xFF,0xBF,0xEF,0xFB,
+0xFE,0xFF,0xBF,0xEB,0xFA,0x1F,0xFF,0xB7, 0xEF,0x5B,0xFE,0xFF,0xAF,0xEB,0xDD,0xE7,
+0xDE,0x77,0x9D,0xE7,0x79,0xDE,0x77,0x9D, 0xBF,0xE6,0x6F,0xFF,0xFE,0xFF,0xBF,0xEF,
+0xFB,0xFE,0xFD,0xBF,0x6F,0xF6,0xFD,0xBF, 0x6F,0xDB,0xF6,0xFD,0xBF,0xFF,0x7E,0xFF,
+0xFF,0xFB,0xFE,0xFE,0xFF,0xEF,0xFB,0xFD, 0xEF,0x7E,0xF7,0xBD,0xEF,0x7B,0xDE,0xF7,
+0xBD,0xEF,0xFF,0xD5,0xFF,0xBF,0xFF,0xEF, 0xFE,0xFF,0xFC,0x3F,0x0F,0xE7,0xFE,0x7F,
+0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,0xFE, 0xF3,0xFF,0xFE,0xDF,0xAD,0xDF,0x67,0xEE,
+0xFB,0xBF,0xEF,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFE,0xFF,0xBF,0xEF,0xFF,0x23,0xFF,0xFF,
+0xFF,0xFF,0x7F,0xFF,0xF3,0xBC,0xDB,0xFE, 0xFB,0xFF,0xFB,0xBE,0xF7,0xFB,0xFF,0x7F,
+0xDF,0xFF,0xCF,0xFB,0xFF,0x9F,0xE3,0xF9, 0xBE,0x3F,0x8F,0xE7,0x79,0xFF,0x9D,0xE7,
+0xF9,0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x5F, 0xFF,0xCF,0xF7,0xFF,0xFF,0xFF,0xDF,0xF7,
+0xFE,0x7F,0xE7,0xF9,0xFE,0x7F,0xFF,0xFF, 0xFB,0xFE,0xFF,0xFF,0xBF,0xFF,0xBF,0xBF,
+0xFF,0xFE,0xFF,0xBF,0xEF,0xFF,0xFD,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFD,0xFF,
+0xFF,0x3F,0xFF,0xBF,0xFF,0xF7,0xFF,0xFF, 0x7F,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xE8,0xEF,0xFF, 0x5F,0xF7,0xBF,0xF9,0xFE,0xDF,0xB7,0xFD,
+0xFF,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0xDD,0xFF,0xF2,0xFF,0xBF,0xFF,
+0xFF,0xBF,0xFF,0xFF,0x2F,0xF2,0xFF,0xBF, 0x2F,0x7B,0xD2,0xF7,0xBF,0x2F,0xFF,0xBB,
+0xFF,0xEE,0x8F,0xAF,0xEB,0xFA,0xFE,0x3F, 0xA7,0x69,0xCE,0x8F,0xA4,0xEA,0xFA,0xEE,
+0xB7,0xAE,0xEB,0xFD,0xC7,0xFF,0xF7,0xF7, 0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3E,0xF3,
+0x74,0xFF,0x3F,0x4F,0xFF,0xE7,0xFF,0x3F, 0xFE,0xA7,0xFF,0xFF,0xDF,0xF7,0xB7,0xFF,
+0xF7,0xFF,0xBA,0xEF,0x37,0xEB,0xFB,0xFE, 0xBF,0xFB,0xFE,0xF3,0xFF,0xF9,0xDF,0xFF,
+0xBF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF, 0xFD,0xDF,0xFF,0xFD,0xFF,0xFF,0xFB,0xFE,
+0xFD,0xFF,0xFB,0xBF,0xFE,0x3F,0xED,0xFF, 0xDF,0xBE,0x3D,0xA7,0xFB,0xFA,0x3F,0xE6,
+0xE1,0xFE,0xFE,0x3F,0xEF,0xE3,0xDF,0xF5, 0x7F,0xFE,0xFF,0x7E,0xFF,0xFF,0xFF,0xFF,
+0xEF,0x6F,0xF6,0xFF,0x7D,0xEF,0xD7,0xDE, 0xFF,0x7D,0xEF,0xFF,0xF2,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0x7B,0xDE,0xFB,0xE6,0xEE, 0xEF,0x37,0x6E,0xF3,0x7E,0xEB,0x37,0xEF,
+0xFF,0xC1,0xFF,0xFE,0xFF,0xF7,0xEF,0xFF, 0xFF,0xFF,0xBF,0x3F,0xD2,0xDF,0xBF,0x2F,
+0x7B,0xE2,0xFF,0xFE,0x3B,0xBD,0xDB,0xFF, 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFE,
+0xFF,0xFB,0xFF,0xFF,0xBF,0xFF,0xFB,0xDF, 0xFF,0xBF,0xFF,0xB7,0xFF,0xFF,0xBF,0xEF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF, 0x7F,0xFF,0x1F,0xEF,0xF1,0xFD,0xFF,0xF6,
+0xAF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF, 0xFF,0xFF,0xFE,0x9F,0xFF,0xFF,0xFF,0x77,
+0xEF,0xF7,0xFB,0xFF,0xFE,0x5F,0xFF,0xFF, 0xBF,0xCF,0xFB,0xF7,0xDD,0xF7,0xF5,0xFF,
+0x5F,0xD5,0xF5,0xFD,0x7F,0x5F,0xD7,0xF5, 0xFF,0xFB,0x0F,0xFF,0xFF,0xA9,0xEA,0x7A,
+0xFF,0xAF,0x8F,0xFE,0xDF,0xAF,0xEF,0xFB, 0xFE,0xFF,0xBF,0xEF,0xFB,0xDF,0xE5,0x5F,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xBD,0x57,0xFF, 0xFF,0x6F,0x77,0xBF,0xF7,0xFB,0xFF,0x7F,
+0xBF,0xF7,0xFF,0xFC,0xBF,0xFF,0x9F,0xFF, 0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xFF,0x1F,
+0xCF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFF,0xFB, 0x65,0xAF,0xF3,0x7C,0xFF,0x3F,0xDF,0xFF,
+0xFD,0xE9,0xFE,0x7F,0xE7,0xFF,0xFE,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFD,0xE3,0xDF,0xFB,
+0xDB,0xF6,0xFD,0xEF,0x5B,0xFB,0xFF,0xDF, 0xFC,0xFF,0x3F,0xDF,0xF3,0xFD,0xFF,0x7F,
+0xDF,0xEF,0x66,0xFF,0xDF,0xAD,0xEB,0x7A, 0xDE,0xF7,0xF7,0xE7,0xD9,0xFD,0x9F,0x67,
+0xD9,0xF6,0x7D,0x9F,0xE7,0xDF,0xF5,0x47, 0xFD,0x65,0x5B,0xD6,0xF4,0xFE,0xFF,0xEF,
+0xFF,0x6D,0xF6,0xDD,0xB7,0x6D,0xDB,0x76, 0xDC,0xB7,0x7D,0xFA,0x9B,0xF6,0x6D,0x9D,
+0x67,0x59,0xDF,0xF7,0xDD,0xFF,0xEB,0xFE, 0xBF,0xAF,0xEB,0xFA,0xFE,0xBF,0xAF,0xE3,
+0xD1,0x9F,0xFF,0xBD,0xBF,0xEF,0xFE,0xF7, 0xBF,0xBF,0xF7,0xD7,0x7F,0xDD,0xF7,0x9D,
+0xDF,0x7F,0xDF,0xF7,0xFF,0xE0,0x7F,0xFD, 0xC1,0xDF,0xF7,0xFD,0xC7,0x7F,0x7F,0xFB,
+0xFF,0xBB,0xEC,0xFB,0x3E,0xFF,0xBF,0xEC, 0xFB,0xFF,0xD8,0x7F,0xBF,0x6C,0xFF,0xBE,
+0xFF,0xBF,0xED,0xFF,0xEF,0xFE,0xFB,0xBF, 0xEF,0xFB,0xFE,0xFF,0xBF,0xEE,0xFF,0xC5,
+0xFF,0xAF,0x6F,0xFF,0xFC,0xFD,0x3F,0xE7, 0xFF,0xFE,0xFF,0xEF,0xFB,0xFE,0xFF,0xBF,
+0xEF,0xFB,0xFE,0xBF,0x89,0xFE,0xFA,0xBA, 0xFE,0xBF,0xAF,0xFB,0xF6,0xF5,0xD9,0x7D,
+0x97,0x65,0xD9,0x74,0x5D,0x97,0x65,0xD3, 0xFE,0xD6,0xFF,0xBF,0xF7,0xFD,0xFF,0x7F,
+0xBF,0xCF,0xFB,0xFE,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xEF,0xFB,0xFF,0xF6,0x8F,0xFB,
+0xFF,0xEF,0xFB,0x7E,0xDB,0xFE,0xFF,0xBE, 0xEF,0xEE,0xFB,0xBE,0xEF,0xBB,0xEE,0xFB,
+0xBE,0xFF,0xFF,0xDF,0xFF,0x43,0xFF,0xFF, 0xFB,0xEF,0x5F,0xB7,0xFE,0x7F,0xE7,0xF9,
+0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0xF9, 0xBF,0xFE,0xAF,0x77,0xFD,0xFF,0x2F,0xAF,
+0xA7,0xFE,0xFF,0xEF,0xFB,0xFE,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0xF1,0x7F,0xEF,0xDF,
+0xFF,0x97,0xF5,0xEF,0xFF,0xDF,0xFF,0xFF, 0xBF,0xFF,0xBF,0xFF,0xFF,0xFE,0xFF,0xFF,
+0xFF,0xE0,0xFF,0xFF,0xF9,0xFE,0x2F,0x8B, 0xE3,0xF8,0xBE,0x77,0x9F,0xF9,0xDA,0x77,
+0x9D,0xE7,0x79,0xDE,0x77,0x9F,0xDD,0xFF, 0xFD,0xFD,0x7F,0x5F,0xD7,0xFD,0xFF,0x7F,
+0xE7,0xFE,0x7F,0x97,0xE7,0xFB,0xFE,0xFF, 0xBF,0xEF,0xFF,0xAB,0xFF,0xEF,0xFA,0xFE,
+0xBF,0xAF,0xFF,0xFA,0xFF,0xFF,0xDF,0xFF, 0xFB,0xFF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,
+0x67,0xFF,0xF7,0xF5,0xFF,0xFF,0xFF,0xDF, 0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xBD, 0xEB,0xFF,0xFF,0xF7,0xAD,0xEB,0xFF,0xDF,
+0xFD,0xFF,0x3F,0xDF,0xF7,0xFD,0xFF,0x7F, 0xDF,0xFF,0x5F,0xFF,0xF7,0xFF,0xFF,0xFD,
+0xBF,0xFF,0xCB,0xF4,0xFF,0x7F,0xD3,0xF7, 0xFD,0x3F,0x7F,0xD3,0xF7,0xFF,0xFC,0x3F,
+0xFF,0xEA,0xFA,0xBE,0xAF,0xAB,0xEB,0xBA, 0xF4,0x95,0x6B,0x52,0xD4,0xAD,0x2F,0x4A,
+0xD2,0xF6,0xBF,0xD2,0x7F,0xF7,0x3F,0xFF, 0xFF,0xF3,0x7F,0xFF,0xFF,0xF7,0xFF,0xBA,
+0xDF,0xFB,0xFD,0xFF,0xBF,0xFF,0xFB,0xFF, 0xF8,0x7F,0xEA,0xFF,0xFE,0xFE,0xDF,0xFF,
+0xF7,0xFF,0x7F,0xBB,0xFF,0xFF,0xBF,0xDF, 0xFB,0xFF,0xFF,0xBF,0xFF,0xB1,0x7F,0xFF,
+0xFB,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF, 0xCF,0xFE,0xFF,0xFF,0xEF,0xFF,0xF7,0xFF,
+0xFF,0xFF,0xF1,0xFF,0x69,0xBE,0xFA,0xBF, 0xAF,0xE2,0xFF,0xFE,0xFD,0xAF,0xF3,0xFE,
+0xFF,0xBF,0xEF,0xFB,0xFC,0xFF,0xFF,0x07, 0xFD,0x95,0xDB,0xDF,0x7F,0xDF,0xAF,0xFF,
+0xF7,0xAF,0x36,0xFE,0xBF,0x65,0xEB,0xF6, 0xFE,0x9F,0x6F,0xFE,0x07,0xFF,0xCF,0xFF,
+0xF8,0xFE,0xFF,0xCF,0xFF,0xF6,0xFA,0xE7, 0xFB,0xFE,0xFF,0xBB,0xED,0xF9,0xFF,0xFF,
+0xFF,0x5F,0xFF,0xFF,0xFF,0x75,0xFF,0xEF, 0x7E,0xFD,0xE0,0xE8,0x5E,0xD3,0xE5,0xF9,
+0x3E,0x5F,0xD7,0xF7,0xFF,0xFA,0x2F,0xFB, 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0x7F,
+0x7F,0xD7,0xF5,0x7D,0x5F,0x57,0xD5,0xF5, 0xEF,0xFF,0xF3,0x7F,0xFC,0x7F,0xFF,0xC7,
+0xF1,0xFF,0xFF,0x1F,0xCF,0xB0,0xFF,0x3F, 0xCF,0xF3,0xFC,0xFF,0x3F,0xCE,0xFF,0xE4,
+0xFF,0xDF,0x7F,0xFE,0xF7,0xBB,0xFF,0xFF, 0xDF,0xEF,0xEE,0xFF,0xBF,0xEF,0xFB,0xFE,
+0xBF,0xBF,0xEF,0xFF,0xD1,0xFF,0xFF,0xFF, 0xFD,0xFB,0xFF,0xFD,0xFF,0xFB,0x9F,0xE9,
+0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0xBF, 0xFF,0xB3,0xFF,0xFF,0xF7,0xFF,0xFF,0xAF,
+0xF7,0xFF,0xB6,0x3F,0xEB,0xFA,0xFE,0xBF, 0xAF,0xEB,0xFA,0xFE,0xBF,0xFE,0xA7,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF, 0xFE,0x9F,0xF7,0xF9,0xFF,0x7F,0x9F,0xE7,
+0xFF,0xFF,0xFE,0xAF,0x6F,0xFF,0xFF,0xFF, 0x9F,0xFF,0xDF,0xFF,0x7D,0x5F,0xDD,0xFF,
+0xFB,0xBF,0xE7,0xBB,0xFF,0xFB,0xDF,0x6D, 0x5F,0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xEB,0xF7,0xFF,0xE7,0xEF,0xF7,0xFF,0xFF, 0x7F,0xFF,0xF7,0xFF,0xFC,0x8F,0xFF,0xEF,
+0xFD,0xFE,0xFF,0xBE,0xF4,0xF2,0x7D,0xD7, 0xCF,0xFF,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xCF,0x6B,0xFF,0xBF,0x3F,0xFB,0xF2, 0xFC,0x7F,0xEB,0xFF,0x9F,0xFA,0xFF,0xFF,
+0x3F,0xFF,0xF3,0xFF,0xFF,0xFD,0x70,0xF7, 0xFF,0xFF,0xBF,0xFF,0xFB,0xD7,0xFE,0xF5,
+0x77,0xFF,0x15,0xDD,0x77,0xFD,0xFF,0x7F, 0xDF,0xF7,0xFB,0xCD,0xBF,0xFF,0xFD,0xFF,
+0xFF,0xDF,0x37,0xCD,0xF9,0xEC,0xFE,0xEF, 0xBB,0xF4,0xFB,0x3F,0x4F,0xB3,0xFF,0xFD,
+0xCB,0xFF,0xE9,0x7E,0x54,0x9F,0xE5,0x4B, 0xB7,0xFF,0xDD,0x7D,0xC7,0x71,0xDD,0x77,
+0x5D,0xD7,0x75,0xCD,0x7F,0xD6,0xFF,0xD3, 0xF6,0xF9,0x3F,0x6D,0x95,0xAF,0x7F,0xFE,
+0xFF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFE,0xF6,0xC7,0xFF,0xAD,0x7B,0xCA,0xFF,
+0xBF,0xBF,0xEF,0xFD,0xE3,0xDF,0xB7,0xED, 0xFB,0x7E,0xDF,0x37,0xED,0xE3,0xFB,0xDF,
+0xFF,0x52,0x5C,0x15,0xFD,0xCF,0x7F,0xDF, 0xFE,0xEF,0xEF,0xFB,0xFE,0xFF,0xBF,0xEC,
+0x7B,0xFE,0xFF,0xFE,0x3E,0x7F,0xDA,0xF7, 0xFD,0xFF,0x7F,0xFF,0xFF,0xFB,0xEF,0xBB,
+0x6F,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFF, 0xF7,0x7D,0xFF,0xD8,0xFF,0xFD,0xBF,0x7F,
+0xFB,0xFF,0xFF,0x9F,0xFB,0xFE,0x7F,0x9F, 0xE7,0xF9,0xFE,0x7F,0x9F,0xEA,0x7F,0xF6,
+0xBF,0xBD,0x6A,0x5A,0xF6,0xE5,0xBF,0x77, 0x5F,0x6D,0xDD,0x77,0x5D,0xD7,0x75,0xDD,
+0x77,0xFF,0xA5,0xBF,0xCF,0xFB,0xFF,0xFF, 0xBF,0xCF,0xFB,0xFD,0xFF,0xBF,0xF3,0xFE,
+0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFD,0xAB, 0xFF,0xBF,0xBF,0xFF,0xFB,0xFF,0x7F,0xEF,
+0xFF,0xBE,0xFB,0xEE,0xFB,0xBE,0xEF,0xBB, 0xEE,0xFB,0xBF,0xFF,0xB5,0xFF,0xD0,0xBC,
+0xFD,0x2F,0x4B,0xF7,0xFF,0xFF,0x9F,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,
+0xFA,0x8F,0xFD,0xAB,0xFA,0xDA,0xBF,0xAF, 0xB3,0xFD,0xFF,0xBF,0xFB,0xFE,0xFF,0xBF,
+0xEF,0xFB,0xFE,0xF7,0xBF,0xFF,0x9F,0xFF, 0x77,0xF7,0xBD,0xFD,0x77,0xDF,0xFF,0x7E,
+0xDF,0xED,0xBB,0xFE,0xFF,0xBE,0xEF,0xFB, 0xFE,0xFF,0xFA,0x3F,0xFF,0xBE,0x6F,0x8F,
+0xE6,0xF9,0xFE,0x7F,0x9F,0xC7,0xFE,0x7F, 0x9F,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7,0xFB,
+0x7F,0xFF,0x7F,0xCF,0xFF,0xFD,0xFF,0xFF, 0xDF,0xFB,0xAF,0xBF,0xEF,0xFF,0xFE,0xFF,
+0x9F,0xEF,0xFB,0xFF,0xFC,0xFF,0xFB,0xFE, 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xF7,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xF5,0xFF,0xFF,0xFF,0x3F,0xDF,0xF7,
+0xFF,0xFF,0x7F,0xEF,0xFE,0xFF,0xBF,0xFF, 0xFB,0xFF,0xFF,0xBF,0xEF,0xFF,0xB3,0x7F,
+0xFF,0x7B,0x5E,0xF7,0xFD,0xFF,0x7B,0x7F, 0xF7,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,
+0xDF,0xF7,0xFF,0x17,0xFF,0xFF,0xFF,0x7F, 0xFF,0xFF,0xDD,0xF6,0xFC,0xBF,0xCB,0xF2,
+0xBC,0xBF,0x2F,0xCB,0xF2,0xFC,0xBF,0xFE, 0x8F,0xFF,0xFA,0x7E,0xBF,0xA7,0xEB,0xDA,
+0xFC,0xBF,0xAF,0x7A,0xFE,0xBF,0xAF,0xEA, 0xFA,0xFE,0xBF,0xAF,0xF4,0xDF,0xFE,0xFF,
+0xF3,0x3C,0x7F,0x3E,0xFF,0xCF,0xF8,0xBF, 0x8F,0xE3,0xF8,0xFE,0x3F,0x8F,0xE7,0xE8,
+0xFF,0xFC,0x9F,0xFF,0xFF,0xCF,0xEB,0xB3, 0xE7,0xFB,0x7B,0xF3,0xFE,0xFF,0xCF,0xDB,
+0xFB,0xFB,0xBF,0x6F,0x6F,0xDF,0xEC,0x7F, 0xFF,0xFF,0xF7,0xFD,0xFD,0xFF,0xFF,0xFF,
+0xFF,0xB2,0xBF,0xFF,0xDE,0xFD,0xBD,0xEF, 0xFB,0xF6,0xDF,0xEA,0xE7,0xDB,0xFE,0xBB,
+0xFF,0xEB,0xFB,0xBF,0x9F,0x8F,0xE8,0xFE, 0x3F,0x8F,0xA3,0xF8,0xFE,0x3F,0x8F,0xFF,
+0xF8,0x7E,0xFD,0xFD,0x7F,0xFF,0xFB,0xCD, 0xFF,0xFD,0xFF,0x5F,0xEF,0xFD,0xFF,0xFF,
+0xDF,0xF7,0xFD,0xFF,0xBE,0x90,0xFF,0xFF, 0xEE,0xFF,0x3F,0xBF,0xF3,0xBB,0xFE,0xB7,
+0xAB,0xFA,0xFE,0xAF,0xAD,0xEA,0xFA,0xDE, 0xAB,0xFF,0x63,0xFF,0xFE,0xF2,0xFF,0xB3,
+0xFF,0xDF,0xEE,0x7D,0xFF,0x03,0xF1,0xF4, 0x3F,0x1F,0xC3,0xF1,0xEC,0x7F,0xFE,0x6F,
+0xFF,0xFB,0xFB,0xFF,0x9F,0xFF,0xBF,0xFF, 0x7B,0x5F,0xFD,0xFF,0xDF,0xF7,0xFD,0xFD,
+0x7F,0x7F,0xDF,0xFE,0xCF,0xFB,0xFF,0xFF, 0xAF,0xFB,0xFF,0x1F,0xEF,0xA5,0xFD,0xBF,
+0xDF,0xFB,0x7D,0xFF,0xBF,0xDF,0xFB,0xFF, 0xFD,0x3B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,
+0xAF,0xF3,0xFF,0xFB,0x7F,0xBF,0xD7,0xFB, 0xBF,0x7F,0xBB,0xF7,0xFF,0xF8,0x7F,0xFF,
+0xFA,0x5F,0xD7,0xFF,0xDF,0x7F,0xEF,0xFF, 0xFF,0x7F,0xDB,0xF7,0xFD,0xFF,0x7F,0xDF,
+0xB7,0xFB,0xEC,0xFF,0xFF,0xF7,0xBF,0xEF, 0xFD,0xFC,0xFB,0xFF,0xEF,0xF0,0xFE,0x3F,
+0x8F,0xE3,0xF8,0xFE,0x3F,0x8F,0xEF,0x8D, 0xFF,0xFF,0xEF,0x7F,0xBF,0xFF,0xFB,0xFF,
+0xDB,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xEF,0xD8,0xFF,0x2E,0x7F,
+0xBE,0xEF,0xFE,0x6E,0xFF,0xBF,0xF9,0xFF, 0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFC,0x66,0xBE,0x47,0xF3,0x7F,0xDF,0xFE, 0x87,0x9F,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xD6,0x6F,0x7C, 0xFB,0x4F,0xD2,0xFF,0xFD,0x2B,0xFE,0xFF,
+0xFF,0xFD,0x5F,0xD7,0xD5,0xF5,0x7D,0xFF, 0xFF,0xFF,0xBF,0x9B,0xFF,0xFF,0xDF,0xB7,
+0xFF,0xFF,0xDF,0xFF,0x3F,0xCF,0xFE,0x7F, 0xBF,0xEF,0xFB,0xFC,0xFF,0x3F,0xFF,0xD9,
+0xBF,0xFE,0x97,0xEC,0x8F,0xB7,0xFE,0x9B, 0x7D,0xFD,0xB7,0xDD,0x77,0x1D,0xC7,0x71,
+0xDD,0x77,0x5D,0xD7,0xF3,0x6F,0xFD,0x3F, 0x73,0xDD,0xAF,0xFD,0x7A,0xFF,0xFF,0xAF,
+0xFE,0xFD,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF, 0xEF,0x66,0x7F,0xFF,0xFF,0xBF,0xBF,0xFF,
+0xFB,0xFF,0xF7,0xDF,0xFD,0xFB,0x7D,0xDF, 0xB7,0xCD,0xF3,0x7C,0x5F,0x3F,0x91,0x3F,
+0xFF,0x3D,0xEF,0x7B,0xFF,0xFC,0xFF,0xCA, 0xEF,0xFE,0xFF,0xBD,0xEF,0xFB,0x1E,0xE7,
+0xBB,0xEC,0x7F,0xB3,0xFF,0xFD,0x9F,0xFF, 0xFF,0xFE,0xFF,0xFF,0x7F,0xBF,0xFB,0xFE,
+0xFF,0xBF,0xEF,0xFB,0xEE,0xFB,0xBF,0xDF, 0x67,0xFF,0xFF,0xBF,0xEF,0xDB,0xFF,0xBC,
+0xFE,0x7F,0xFB,0xFF,0x9F,0xEF,0xF9,0xFE, 0x7F,0x9F,0xE7,0xF9,0xFE,0x87,0xFF,0xEE,
+0xFB,0xBE,0xE5,0xBF,0xEF,0xF9,0xD7,0x65, 0xF7,0xDD,0xE7,0x7D,0xDF,0x77,0x5D,0xD7,
+0x7F,0xF8,0x9B,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xFF,0xBF,0xEF,0xFB,0xFF,0x7F,0xCF,
+0xF3,0xFC,0xFF,0xBF,0xEF,0xFF,0xDB,0x3F, 0xEF,0xFB,0xFE,0xFF,0xDF,0xFF,0xFE,0xFB,
+0xBB,0xEF,0xBF,0xEF,0xBB,0xEE,0xFB,0xBE, 0xEF,0xBB,0xFF,0xFC,0x7F,0xFD,0x3B,0x5B,
+0xD6,0xE5,0xFD,0x4F,0xC3,0xFB,0xFF,0xBF, 0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFF,
+0xB4,0xFF,0xFA,0xBC,0x8F,0xB2,0xE9,0xD2, 0x2E,0xCF,0xFB,0xFF,0xBF,0xEF,0xFB,0xFE,
+0xFF,0xBF,0xEF,0xFB,0xFF,0xEC,0xFF,0xFD, 0xFD,0x7F,0xDF,0xF7,0xE4,0xDF,0x5F,0xFF,
+0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xC3,0xFF,0xEF,0xE6,0xF8,0xFE,
+0x3F,0x8B,0x83,0xF9,0xFE,0x7F,0xE7,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x17,
+0xFD,0xFF,0xFF,0xFF,0x7F,0x5F,0xF7,0x2C, 0xFF,0xFF,0xFF,0xFE,0x7F,0xFF,0xE7,0xF9,
+0xFE,0x7F,0x9F,0xFE,0x2F,0xFF,0xFF,0xEF, 0xFF,0xFE,0xBF,0xEF,0xAD,0xFF,0xFF,0x7F,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFE,0xDF,0xFF,0xDF,0xFF,0xFD,0xFD,0x7F,
+0xDF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0x3F,0xFE,
+0xF7,0xFD,0xEF,0x7A,0xFF,0xB1,0xBD,0xFF, 0x7F,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,
+0xFF,0x7F,0xF3,0x27,0xFF,0xDF,0xFF,0xDD, 0xFF,0xFC,0x9B,0xFF,0xCB,0xFC,0xBF,0x2F,
+0xCB,0xF2,0xFC,0xBF,0x2F,0xC9,0xFF,0xDE, 0xFF,0xDF,0xAF,0xEB,0xDA,0xFE,0xBB,0xAF,
+0xEB,0xF8,0xF7,0xAF,0xE8,0xFA,0xFE,0xBF, 0xAF,0xEB,0xF2,0xFF,0xFD,0xFF,0xFF,0xEF,
+0xBD,0xD7,0xBF,0xFF,0xFF,0xDE,0x8F,0xB8, 0xDE,0x37,0x8D,0xA3,0x78,0xDA,0x3F,0x8F,
+0xFF,0xA1,0xFF,0xFF,0xFB,0xFB,0xFF,0xFF, 0xFF,0xFF,0xA7,0xBD,0xFB,0x76,0xFD,0xBF,
+0xEF,0xDB,0xFE,0xBB,0xBF,0xFE,0x27,0x7F, 0xFF,0xFE,0xFE,0xFD,0xF5,0xFF,0xEF,0xF5,
+0xDF,0x1F,0xE7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0xFF,0xCD,0xFD,0xAE,0xFF,0xFA,
+0x3E,0x3F,0xAB,0xFD,0xF8,0x7E,0x8F,0xE3, 0xF8,0xFE,0x3E,0x8F,0xE3,0xF8,0xFF,0xFE,
+0x1F,0xEF,0xDF,0xBF,0xFE,0xDE,0xDF,0xD9, 0xFF,0xDF,0xBC,0xFF,0xFF,0x7F,0xFF,0xEF,
+0xFD,0x7F,0xDF,0xF7,0xF9,0x3F,0xFE,0xFF, 0xFF,0x6F,0xFE,0xDE,0xBF,0xF7,0xED,0xEA,
+0xFD,0x8F,0x83,0xF8,0xEA,0x3F,0x8F,0xEF, 0xFF,0xF4,0x7F,0xFF,0xEF,0xEF,0x7B,0xF3,
+0xF1,0x5F,0xFF,0xFF,0xF1,0x3B,0x7F,0xDF, 0xF7,0xFD,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,
+0xFF,0xFF,0xF7,0xFF,0x6F,0xFF,0x7F,0xFF, 0xFF,0xF7,0xDE,0xF7,0xBF,0xEF,0xFB,0xF7,
+0xFD,0xFF,0xFF,0xF5,0xFA,0xFF,0xFF,0xFB, 0xE7,0xFF,0xF3,0xF8,0x7F,0xF3,0xDF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0xEF, 0xBB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,
+0xFF,0x7F,0xFF,0x9F,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xCF,0xFF,0x37,0xFF,0xFF,
+0x7F,0xDF,0x77,0x5D,0xE7,0xFC,0xFF,0xBF, 0xF7,0xF5,0xFB,0xFF,0xFF,0xD7,0xF5,0xFB,
+0xFF,0xFF,0x45,0xFD,0x7F,0xEA,0xFD,0xBE, 0xBF,0xDF,0xF7,0xFF,0xFF,0xDB,0xFB,0xFE,
+0xFF,0xBF,0xEF,0xFF,0xFF,0xFF,0xFB,0x5F, 0x7F,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFE,0xFF,0xEF,0xFD,0xFF,0x7F,0xDF, 0xFF,0xEF,0xFB,0xF8,0x0F,0xF3,0xFF,0xF9,
+0x2E,0xFB,0xFE,0xFC,0xF3,0xEF,0xFF,0xFF, 0xBF,0xFF,0xFB,0xE7,0xFF,0xFE,0x7E,0xFF,
+0xC0,0x6B,0xCF,0xFF,0x34,0xDF,0xF1,0xFD, 0xFF,0xEF,0xFF,0xFF,0xFF,0xDF,0xF7,0xFD,
+0xCF,0x7F,0x9C,0xFD,0xFD,0x6C,0xF7,0xFF, 0xF6,0xFD,0xEB,0x2B,0x9F,0xFF,0xFC,0xFE,
+0x7E,0xFF,0xFF,0xFF,0xFF,0xD7,0xF3,0xF7, 0xFF,0xFB,0xE1,0xBF,0xFF,0xEB,0x7A,0xDE,
+0xD7,0xFB,0xFF,0xF9,0xFE,0xFF,0xFF,0xF3, 0xDE,0x7F,0xFD,0xE7,0x7F,0xFF,0xFD,0xBB,
+0xFF,0xFF,0x7E,0xCC,0xF6,0xAF,0x5F,0x7F, 0xFE,0xF4,0x7D,0xF7,0xFD,0xBB,0x6E,0xDB,
+0xB7,0xFF,0xF7,0xDF,0x66,0xFF,0xFF,0xF7, 0x3D,0xCF,0xDE,0xBD,0xFF,0xFF,0xDE,0xDB,
+0x8D,0xF7,0x7E,0xDF,0xB7,0xEF,0x7F,0xFF, 0xF6,0x87,0xFF,0xFF,0xEF,0xFE,0xDE,0xBF,
+0xFF,0xFF,0xFF,0xBB,0xEF,0xFD,0xFF,0x7B, 0xDE,0xF7,0x3F,0xFF,0xBF,0xFB,0xDB,0xFF,
+0xF2,0xB6,0xFD,0xBD,0x7F,0xE7,0xFF,0xFF, 0xFF,0x6F,0xF7,0xFF,0xFF,0xFF,0xFE,0x77,
+0xFF,0xBF,0xF8,0xAF,0xFF,0xDF,0xBF,0xFF, 0xBF,0x7F,0xFB,0xFF,0xFF,0xFF,0xDB,0xFE,
+0xFF,0xBF,0xFF,0xFA,0xFF,0xFD,0xFF,0xF6, 0x7F,0xFF,0x9F,0xFF,0xFF,0x3F,0xEF,0xF8,
+0xEE,0x7E,0x9F,0xBA,0xFE,0xBF,0x8F,0xEF, 0xFE,0xFE,0xF9,0xFF,0xFA,0x7F,0xFE,0x7E,
+0xBF,0xAF,0xFB,0x96,0xFD,0x9F,0xEF,0x5E, 0x65,0xBE,0xEF,0x5B,0xB6,0xFF,0xBE,0xE3,
+0xFF,0xB5,0xBF,0xFF,0xFD,0xFF,0x7F,0xFF, 0xEF,0xDF,0xFE,0xFF,0xBF,0xFB,0xFE,0xFF,
+0xBF,0xCF,0xFF,0xFF,0xFF,0xFD,0x9B,0xFF, 0xFE,0xFB,0xFE,0xDF,0xFF,0x7F,0xFF,0xF7,
+0xFE,0xFF,0xDF,0xFB,0xFB,0xFE,0xFF,0xFF, 0xFF,0xFF,0xFF,0xB7,0xFE,0xFA,0xFF,0xAB,
+0xEF,0xFF,0xFD,0xB5,0x7B,0x7F,0xFB,0xF7, 0xFD,0xFF,0xFF,0xDD,0xFF,0xEF,0x8F,0xFF,
+0x2F,0xFF,0xFB,0x7C,0xFF,0x3F,0xDF,0x73, 0xEB,0xFE,0x3F,0xFF,0xEF,0xFB,0xFE,0xFF,
+0xEF,0xFD,0xFF,0xBF,0xFD,0x0F,0xFF,0xFF, 0xFF,0xF5,0xF9,0xFF,0x7F,0xD7,0xFD,0xFF,
+0xDF,0xFF,0xF7,0xFB,0xFF,0x7F,0xBF,0xFF, 0xFF,0xF0,0x9F,0xFF,0xFE,0x7F,0x8B,0xE3,
+0xF9,0xDE,0x27,0x9B,0xE6,0xBE,0x7F,0x9B, 0xC3,0xF8,0xDE,0x7F,0x9D,0xE7,0xFE,0x7F,
+0xFF,0xFF,0x5F,0xD7,0xFF,0xFF,0xFF,0x4F, 0xFB,0xFF,0xFF,0x7F,0xFF,0xAF,0xFF,0x9F,
+0x7F,0xFB,0xFF,0xE8,0xFF,0xFF,0xFE,0xBF, 0xAF,0xFF,0xFF,0xFE,0xBF,0xEF,0xF7,0xFF,
+0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF, 0xFC,0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xFF,
+0xFD,0x3F,0xCF,0xFF,0xFF,0xFF,0xFF,0xF7, 0xFF,0xFD,0x7F,0xFF,0xFF,0x93,0xFF,0xFF,
+0x7A,0xDF,0xF7,0xFF,0xFF,0x7B,0x7F,0xB7, 0xEF,0xFF,0xFF,0xFD,0xBF,0xFD,0xFB,0xFF,
+0xF7,0xFF,0xD7,0xFF,0xFF,0xFF,0xFC,0x9F, 0x6F,0xCB,0xFF,0xF4,0xBB,0xDF,0xD6,0xFD,
+0xBF,0x2F,0xD3,0xF7,0xFF,0xDF,0xFF,0xCF, 0xFF,0xFA,0xBE,0xBD,0xAF,0x6A,0xDA,0xBE,
+0xBB,0xAB,0x3A,0xBE,0x2D,0xAE,0xEB,0xDA, 0xF6,0x3F,0xAD,0xF5,0xDD,0xFF,0xCF,0xF1,
+0xFF,0xF9,0x7F,0xFF,0x73,0xFE,0xFF,0xCF, 0xC3,0xF4,0xF7,0x2F,0xF3,0xFF,0xFC,0xFF,
+0x7C,0x1F,0xFF,0x3F,0x4F,0xFF,0x7E,0xFF, 0xEF,0xBD,0xF6,0xFE,0xFF,0x2B,0xEF,0xDC,
+0xFB,0xFD,0xFF,0xFB,0xFF,0xEA,0x7B,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFB,0xF7,0xDF,0xFF,
+0xE3,0x7D,0xFF,0xB7,0xFF,0xBF,0xFF,0xFF, 0xDF,0xFF,0xF8,0xFF,0xBF,0xFF,0xBF,0xEB,
+0xE7,0xFA,0xFE,0x3D,0xBF,0xE9,0xFC,0xBF, 0xFF,0xFA,0xFB,0xFE,0xFF,0xFF,0xFF,0xD9,
+0xFF,0xFF,0xFF,0xF6,0x7F,0xFF,0xF6,0x7D, 0xFF,0xDF,0xCF,0xFD,0xBF,0xFB,0xEF,0x7E,
+0xFF,0x7F,0xFF,0xFF,0xD3,0xFF,0xFD,0xFB, 0xFF,0xFB,0xFF,0xFF,0xFF,0xEF,0xFF,0xBF,
+0xFE,0xFF,0xF7,0xEF,0xFF,0xFF,0xFF,0xFB, 0xFF,0x87,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,
+0x7B,0xFE,0xFF,0xFE,0x3B,0xF7,0xF7,0xFF, 0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,
+0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xF7, 0xFF,0xFF,0xAD,0xFF,0xFE,0xF7,0xFF,0xFF,
+0x5F,0xFF,0xFF,0xDF,0xFF,0xFD,0xFF,0xF5, 0xFF,0xDF,0xFF,0xBD,0xFF,0xE9,0xFF,0xC7,
+0xF3,0xFF,0xFF,0xF7,0xFF,0xF3,0xFF,0xF8, 0x3B,0xFF,0xFF,0x7B,0xDF,0xBF,0xFB,0xEF,
+0xFB,0xFF,0xFB,0xF7,0xF7,0xBB,0xFF,0xFF, 0xFF,0xFF,0xFB,0xFF,0xFE,0x7F,0xF3,0x7F,
+0x5E,0xB7,0xBF,0xFD,0x7F,0xFF,0xF9,0x7F, 0xFB,0xFF,0xEB,0xFD,0x7F,0x7F,0xFF,0xEF,
+0xFB,0xE0,0x3F,0xFE,0xBF,0xBF,0xDF,0xFF, 0x7E,0xFF,0xF7,0xFF,0xFF,0xFE,0xBF,0xFF,
+0xDB,0x78,0xFF,0xFF,0xFF,0xEE,0xA1,0xBF, 0xF5,0xDE,0xFB,0xF7,0xFF,0xFB,0xFF,0xFF,
+0xFF,0xFF,0xFB,0xFF,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xEF,0xF0,0xFF,0xFF,0xFF,0xF3,
+0xF7,0xFF,0xEF,0xFF,0xE7,0xCF,0xFF,0xFB, 0xFF,0xEF,0xFF,0xFF,0x9F,0x9F,0xEF,0xFC,
+0x16,0xBF,0xFE,0xF3,0xE4,0xFF,0xFF,0xC6, 0xFF,0xE7,0xFF,0xFF,0xFD,0xFF,0xBF,0xFF,
+0xFF,0x3F,0xFF,0xBF,0xD6,0xAF,0x7F,0xFE, 0x6B,0x7E,0x7F,0xFF,0xAF,0xFF,0xFF,0xBF,
+0xFF,0x5F,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF, 0xFF,0xBD,0xDB,0xFF,0xFE,0x5F,0xF2,0xFF,
+0xFF,0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xEF,0x7F,0xFF,0xFF,0xFF,0xFF,0xDE,0xBF,
+0xFF,0xFF,0xEF,0xFB,0x77,0xFE,0xBD,0x7F, 0x5F,0xFF,0xFF,0xFF,0xDF,0x6F,0xED,0xFF,
+0xFD,0xFF,0x7F,0xFD,0x6F,0xFF,0xFF,0x77, 0xDA,0xCF,0xFD,0x5F,0xFF,0xBF,0xFF,0xFF,
+0xDF,0x7F,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF, 0x66,0x7F,0xFF,0xFE,0xBF,0xE7,0xBF,0xFA,
+0xFF,0xFE,0xFF,0xFF,0xFF,0xDF,0xFF,0x59, 0xEF,0xFF,0xEF,0xFB,0x7F,0x89,0xFF,0xFF,
+0xE9,0xFF,0x6F,0xFF,0xF5,0xFF,0xFF,0xFF, 0xFF,0xFF,0x7F,0xF2,0xF7,0xFF,0xFF,0xEF,
+0xF8,0x7F,0xFB,0xFF,0xFD,0xFF,0xFF,0xD9, 0xFF,0xEF,0xBB,0xFF,0xFF,0xFF,0xBF,0xEF,
+0xDE,0xFF,0xFF,0x9F,0x7F,0xDF,0xFF,0xF7, 0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xAF,
+0xFF,0xFF,0xF7,0x3F,0xEB,0x9F,0xFE,0x7F, 0x9E,0x7F,0x9F,0xFE,0x87,0xFF,0xED,0xDB,
+0x56,0xFF,0xBF,0xAF,0x0B,0xD2,0xFF,0xEF, 0xDB,0x6E,0x7D,0xBD,0x6F,0xF8,0xFE,0x3F,
+0xFA,0x5B,0xFF,0xFD,0xBF,0xEF,0xFF,0xBF, 0x6F,0xDB,0xE6,0xFF,0xFF,0x3F,0xFF,0xDF,
+0xFE,0xFF,0xFF,0xFF,0xFF,0xDA,0x3F,0xFF, 0xFB,0xFE,0xFE,0xFF,0xFF,0xDF,0xF7,0xBD,
+0xFF,0xFD,0xFF,0xFE,0xFF,0xFB,0xFF,0xFF, 0xFF,0xFF,0xF1,0x5F,0xFD,0x9F,0xDF,0xFD,
+0xFF,0xFD,0x7F,0xFF,0xFF,0xFF,0xFF,0x76, 0xFA,0xFF,0xFF,0x7F,0xE3,0xF8,0xFF,0xAE,
+0xFF,0xFB,0x7E,0x9D,0x73,0xFF,0xFA,0x7F, 0xDF,0xFF,0xFF,0x7F,0xFF,0xFB,0xCD,0xFF,
+0x7F,0xEF,0xFB,0xFF,0xFD,0xFF,0xF7,0x7F, 0x7F,0xEF,0xFF,0xED,0xFF,0xFF,0xFF,0xB5,
+0xFF,0xBF,0xFF,0xBF,0xFD,0xEF,0xDB,0xF7, 0xFF,0x93,0xFF,0xEF,0xE2,0xF9,0xBE,0x7F,
+0x8B,0xE7,0xF9,0xFE,0x6B,0xE7,0xF9,0xFE, 0x7F,0x9F,0xE7,0xF9,0xFE,0x7F,0x47,0xFF,
+0xFF,0xFD,0xFF,0x9F,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xF5,0xFF,0x9F,0xFF,0xF7,0xFE,
+0xFF,0xBF,0xFE,0x6F,0xFF,0xFF,0xFB,0xFF, 0xFF,0xFF,0xAF,0xFF,0xFF,0xFF,0x7F,0xFB,
+0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, 0xDF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xDF,
+0xFF,0xFF,0xFF,0x5F,0xFF,0xFF,0xFF,0xFF, 0x5F,0xFB,0xFE,0xFF,0xF8,0x37,0xFF,0xFF,
+0xEF,0xFF,0x7F,0xFE,0xBF,0xFF,0xFF,0xFE, 0xBF,0xFF,0xFF,0x7F,0xFF,0xBF,0xFD,0xFF,
+0x7F,0xFA,0x7F,0xFF,0xFF,0x6F,0xFF,0xFF, 0x7D,0xFF,0xCF,0xFF,0xFF,0xFF,0x4F,0xFF,
+0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0xBF, 0xFF,0xAE,0xEB,0xFA,0xFE,0xBB,0xAD,0xEB,
+0xFA,0xF7,0xAF,0x6B,0xFA,0xF6,0xBF,0x25, 0xE9,0xF2,0x7F,0x45,0xFF,0xFF,0xFD,0xF7,
+0xF7,0xBF,0xFF,0xDF,0xFF,0xFF,0xBF,0xFB, 0xFF,0xDF,0xF3,0xFF,0xF7,0x3F,0xCF,0xFF,
+0xA1,0xFF,0xFF,0xBF,0xE7,0xFF,0xFF,0x7F, 0xFF,0x3D,0xFF,0xFF,0xFF,0xF7,0xFF,0x2F,
+0xFF,0xFB,0xF5,0x7F,0xFE,0x57,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,
+0x3F,0xFF,0xFE,0xFF,0xFF,0xFF,0xFD,0xFE, 0xF7,0xEE,0xAF,0xFE,0xEE,0xE7,0xFA,0xFF,
+0xFE,0x9D,0xF9,0x5E,0xFE,0xFF,0xEB,0xFF, 0xFF,0xDF,0xA7,0xFF,0xFF,0xFF,0xFC,0xDB,
+0xFF,0xFF,0xFF,0x7E,0xFB,0xFF,0xFF,0xEF, 0xFB,0xFD,0xFF,0xDB,0xFF,0xFF,0xFF,0xEF,
+0xFF,0xFF,0xFF,0xFD,0xBF,0xFE,0xBF,0xFF, 0x6F,0x7F,0xFF,0xF7,0xFF,0xFF,0xF9,0xFF,
+0xF7,0xFF,0xBF,0xDE,0xF7,0xFF,0xFF,0xFF, 0xFA,0x7F,0xFD,0xBF,0x5F,0xFF,0xFF,0xBF,
+0xFF,0xED,0xFF,0xF7,0xBF,0xFF,0xFF,0xEF, 0xFF,0xDF,0xFF,0xFF,0xFF,0xE6,0xFF,0xFB,
+0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,
+0xFD,0xFF,0xF5,0xFF,0xF6,0x7F,0xDF,0xBD, 0xCF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,
+0xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3, 0xFF,0xEE,0xBF,0xFF,0x7D,0xEF,0xFE,0xFF,
+0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFE, 0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xB5,0xAE,
+0xFF,0xFF,0xB6,0xFE,0xBF,0xFF,0xFF,0xBF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0x27,0xFF,0xEF,0xFE,0x7F,0xDF,0xFF, 0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFD,0xFF,0xF7,0xF9,0x9F,0xFF, 0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,
+0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0x0F,0xFF,0xE7,0xBF,0xFE,
+0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFC,0xBF, 0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xC4,
+0x6B,0xFF,0x29,0x1F,0xFB,0xAF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xEF,0x1B,0xFE,0xFF,0xFC,
+0x6F,0xFF,0xFF,0xFD,0x6A,0xF7,0xD7,0xF5, 0xBF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFE,0xBF,0xFF,0xFF,0xFA,0xFF,0xFF,0xF7, 0xFB,0xDD,0xBF,0xFF,0xE7,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x7F,0xFF, 0xFF,0xF5,0xFF,0xFF,0xF7,0xFD,0xB3,0xEF,
+0xFD,0x7E,0x5D,0xFF,0xFD,0xFF,0xFF,0xFF, 0xFD,0x7F,0xD2,0xF5,0xFB,0x7E,0xCB,0xB7,
+0xFF,0xFF,0xFF,0xC6,0xFF,0xFD,0xEE,0x63, 0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xFD,0x65,
+0x5B,0xDF,0xFF,0xD5,0xFF,0xFF,0xFF,0xF6, 0xE7,0xBF,0xF7,0xA9,0xFF,0xFF,0xED,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,0xFF,0xFF, 0xAF,0xFF,0xFF,0xFF,0xF8,0x1B,0xFF,0xE3,
+0xD0,0xBF,0xFF,0xE1,0xFF,0xFF,0xFF,0xFF, 0xFF,0xD7,0xFF,0xFF,0xFF,0x5F,0xFF,0xFF,
+0xFF,0xFF,0xAF,0xFF,0xDB,0x76,0xBF,0xFF, 0x7F,0xFF,0xBF,0xEF,0xFE,0xFF,0xBF,0xEF,
+0xFB,0xFE,0xFF,0xFF,0xFF,0xBF,0xF2,0x7F, 0xFF,0x9F,0xFE,0xBD,0xFE,0x7F,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xF7,0x3F,0xEC,0x7F,0xF6,0x95,0xBB,
+0xEF,0xF8,0xFE,0xFC,0xBF,0x2F,0xDA,0xFC, 0xBF,0x2F,0xCB,0xF2,0xFC,0xBF,0xEF,0xFF,
+0xA9,0xBF,0xCF,0xFB,0xFF,0xFF,0xFF,0xFE, 0xDD,0xB7,0x6D,0xF6,0xD9,0xB6,0x6D,0x9B,
+0x76,0xD9,0xBF,0xFB,0xFD,0xA3,0xFF,0xBF, 0xEF,0xFF,0xEF,0xFF,0xFF,0xFF,0x7F,0xDF,
+0xFD,0xEF,0x7B,0xDE,0xF7,0xFD,0xEF,0x7F, 0xFF,0xFF,0x05,0xFF,0xFA,0xFE,0x7F,0xEF,
+0xE3,0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xFF, 0xFF,0x5F,0xFF,0xFF,0xFD,0x7F,0xFB,0xAF,
+0xFF,0x63,0xC8,0xFF,0xBF,0xEF,0xFF,0xFF, 0xFA,0x7F,0xFF,0xFF,0xFF,0xFE,0x9F,0xF7,
+0xFF,0xFA,0xBF,0xFE,0x9F,0xFB,0x7F,0xFF, 0xFF,0xEF,0xD7,0xFF,0xFF,0xF5,0xFF,0xFF,
+0xFF,0xFF,0xFD,0x7F,0xFF,0xFF,0xBF,0xFF, 0xF9,0xBF,0xFF,0xBE,0x27,0x9F,0xE7,0xF9,
+0xFE,0x7F,0x8B,0xE7,0xFE,0x7F,0x9F,0xE2, 0xF9,0xFE,0x7F,0x9F,0xE7,0xF1,0x7F,0xFF,
+0xFF,0xFF,0xFB,0xFE,0xFF,0xFF,0xFF,0xD7, 0xFF,0xFF,0xFF,0xFF,0xF5,0xFF,0xFF,0xFF,
+0xD7,0xFF,0xFA,0xFF,0xFE,0xFF,0xFF,0xFF, 0xFD,0xFF,0xFF,0xFF,0xAF,0xF7,0xFF,0xFF,
+0xFF,0xEB,0xFF,0xFF,0xFF,0xAF,0xFF,0xC4, 0xFF,0xF7,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,
+0xFF,0x5F,0xFF,0xFF,0xFF,0xFF,0xD7,0xFF, 0xFF,0xFF,0xFF,0xFF,0xEB,0xFF,0xFB,0x7A,
+0xDF,0xF7,0xFD,0xFF,0xFF,0xFE,0xBF,0xFF, 0xFF,0x7F,0xFF,0xAF,0xFF,0xFF,0xFF,0xF7,
+0xEF,0xE3,0xFF,0xDD,0xD2,0xFF,0xDF,0xFF, 0xFF,0xF2,0xFC,0xBF,0xCB,0xF6,0xFD,0xBF,
+0x2F,0xCB,0xFF,0x7F,0xDF,0xDE,0xAF,0xFF, 0xDA,0xEE,0xBF,0xAF,0xE9,0xFA,0xF4,0xBD,
+0xAF,0x5A,0xAE,0xBB,0xAB,0x6B,0xDA,0xDE, 0xBF,0xAD,0xD7,0x5E,0xFF,0xFF,0xBF,0xFC,
+0xFF,0xDF,0xFD,0xFF,0xFF,0xFF,0xFF,0xDF, 0xF7,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFA,
+0x1F,0xFF,0xFE,0xFB,0xEF,0xBF,0xFD,0xFF, 0xFD,0xBD,0x77,0xFF,0xFF,0xFF,0xFF,0x9D,
+0xEF,0xFF,0xFF,0xFF,0xEF,0x7D,0xFF,0xFB, 0xFE,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEE, 0xBF,0xE4,0xFB,0xFF,0xFE,0x3F,0xFE,0xFF,
+0xFF,0xFF,0xFF,0xAF,0xEA,0xFE,0xBF,0xAF, 0xEB,0xFA,0xFE,0xFF,0xFF,0xFF,0x55,0xF6,
+0xFF,0xFE,0xF7,0xFF,0x7F,0xFF,0xEB,0xF7, 0x5F,0xC5,0xFD,0x7F,0x5F,0xD7,0xF5,0xFF,
+0x6F,0xFB,0xFF,0x8A,0xFF,0xFF,0xFF,0xFF, 0xEB,0xFF,0xFF,0xFF,0xFF,0xFB,0xBF,0xBF,
+0xEF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF, 0x77,0xDF,0xFB,0xFF,0xFD,0x7F,0xEF,0xFF,
+0xFF,0xFF,0xBF,0x7F,0xFF,0xDF,0xBF,0xFF, 0xFB,0xFF,0xFF,0xFF,0xFE,0xEF,0xDF,0xFF,
+0xFE,0xFF,0x9F,0xEF,0x7D,0xFF,0xF7,0xFF, 0x7F,0xFF,0xFF,0xDF,0xF7,0xFD,0xFF,0xEF,
+0xDF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFB,
+0xFD,0xFF,0xBF,0xDF,0xD1,0xFF,0xF8,0x3B, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0x7E,0xDB,0xFD,0xFF,0x77,0xDB,0xB7,0x7D, 0xBF,0xFB,0xFF,0xF8,0x7F,0xED,0x7B,0x5E,
+0xFF,0xFE,0xFF,0xFF,0x4F,0xD7,0xFD,0x7F, 0xDF,0xD7,0xF5,0xFF,0x7F,0xFF,0xFF,0xFF,
+0xF2,0x3F,0xFE,0xFF,0xBF,0xFF,0xFF,0xFF, 0xFF,0xBF,0xEF,0xFE,0xFF,0x3B,0xEE,0xFF,
+0xFC,0xEF,0xFF,0xFF,0xFF,0x85,0xFF,0xFD, 0xFE,0xFF,0xF5,0xFF,0xFF,0xFE,0xFF,0xDF,
+0xFB,0xFF,0x5F,0xBF,0xFF,0xFD,0xFF,0xFF, 0xFF,0xFF,0xA8,0xFF,0xFF,0x9F,0x9E,0xFF,
+0xFF,0xFF,0x7F,0xF3,0xFF,0xFF,0xCF,0xFF, 0xF7,0xFD,0xFF,0x7F,0xFF,0xFF,0xFC,0x16,
+0xBF,0xCF,0xA3,0xE5,0xEF,0x7F,0xFF,0xF3, 0xE4,0xFF,0xCF,0x93,0xFC,0xFF,0x3F,0xCF,
+0xFF,0xFF,0xFF,0xD6,0x0F,0x7D,0xBF,0x6E, 0xFB,0xF4,0xFC,0xAF,0x6D,0xDB,0x77,0xB7,
+0x6D,0xDB,0xF6,0xFD,0xBF,0xFF,0xFF,0xFF, 0xBF,0x9B,0xFA,0xDE,0xB7,0xB7,0xED,0xF9,
+0x7E,0xB7,0xAC,0xEB,0xD6,0xB3,0xAD,0xEB, 0x7A,0xDF,0xFF,0xFF,0xFF,0xD8,0xBF,0xFF,
+0xB7,0xED,0x9F,0x6F,0xDD,0xF7,0x68,0xDB, 0x37,0xB3,0x6C,0xDB,0x36,0xCD,0xB3,0x7F,
+0xFF,0x7F,0xF5,0x6F,0xFD,0xEF,0x79,0x3D, 0xF7,0x93,0xE4,0x7A,0x9E,0xAD,0xEA,0x7A,
+0x9E,0xF7,0xBD,0xEF,0xFF,0xFF,0xFF,0x76, 0x7F,0xFB,0xC6,0xFF,0xBB,0xEF,0xDA,0xFE,
+0xFD,0xBF,0xFB,0xFE,0xFF,0xBF,0xEF,0xFB, 0xFF,0xFF,0xFB,0xFF,0xA5,0xFF,0xFD,0xAB,
+0x6F,0x78,0xDE,0x17,0x8F,0x79,0xDF,0xFD, 0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0xFF,0xFB,
+0xFF,0xFB,0xFF,0xEF,0xFB,0xEF,0xFB,0xFE, 0xFF,0xBB,0xDA,0xF3,0xEF,0x3B,0xCE,0xF3,
+0xBC,0xEF,0x3F,0xCF,0xDF,0xFF,0xB7,0xFF, 0xFF,0xFF,0xCF,0x73,0xFF,0xBF,0xEF,0xFF,
+0xF3,0xFF,0x3F,0xCF,0xF3,0xFC,0xFF,0x3D, 0xCF,0x9F,0xFE,0x07,0xFF,0xAF,0xEB,0xFE,
+0xFD,0xBF,0xEF,0xEB,0xFA,0xFF,0xAF,0xEB, 0xFA,0xFE,0xBF,0xAF,0xFB,0xFE,0x3F,0xFB,
+0x9B,0xFF,0x7F,0xDF,0xFF,0xF3,0xFE,0xFF, 0xDE,0xF7,0xBF,0x7B,0xDE,0xF7,0xBD,0xEF,
+0x7B,0xFE,0xFF,0xFF,0xDF,0x3F,0xFE,0xFF, 0xB7,0xFF,0xEF,0xF7,0xFF,0xBF,0xED,0xFE,
+0xDF,0xB7,0xED,0xFB,0x7E,0xDF,0xFF,0xFF, 0xFF,0xFD,0x5F,0xEF,0xEB,0xFA,0xFE,0xF5,
+0xBF,0x6F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xF8,0xFF,0xA8,0xFF,
+0xFF,0xBF,0xEF,0xFB,0x6A,0xFB,0xB7,0xEF, 0xFB,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xBF,
+0xEF,0xFB,0xFF,0xE0,0xFF,0xFF,0xFD,0x7F, 0x5C,0xD7,0x7D,0xDF,0xF3,0x5C,0xF5,0xCD,
+0x73,0x5E,0xD7,0xB5,0xFD,0x7F,0xEF,0xFF, 0xDB,0xFF,0xFF,0xE2,0xF8,0xBE,0x2F,0x8F,
+0xE7,0xF8,0xBE,0x6B,0xE2,0xF8,0xBE,0x2F, 0x8B,0xE2,0xF9,0xFE,0x7F,0xE7,0xFF,0xD7,
+0xF5,0xFD,0x7F,0xFF,0xF7,0xF5,0xFD,0x7F, 0xD7,0xF5,0xFD,0x7F,0x5F,0xD7,0xF5,0xFF,
+0xFF,0xFF,0x8F,0xFF,0xAF,0xEB,0xFA,0xFF, 0xFF,0xBF,0xEB,0xFA,0xFF,0x2F,0xEB,0xFA,
+0xFE,0xBF,0xAF,0xEB,0xFF,0xFF,0xFE,0x5F, 0xFF,0x5F,0xFF,0xFF,0xFD,0xFF,0xFF,0xD7,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xBF,0xFE,0xB7,0xFD,
+0xFF,0x7E,0xDF,0xF7,0xAD,0xFF,0x7F,0xF7, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0x7F,
+0xF6,0x7F,0xFF,0xFF,0xFF,0xDB,0xF6,0xFC, 0xAF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xEC,0xBF,0xFF, 0xAF,0xEB,0xFA,0xF6,0xAB,0x8F,0xEB,0xFA,
+0xF7,0xA5,0xEB,0xFA,0xBE,0xBF,0xAF,0xEB, 0xFA,0xFF,0x6D,0xFF,0xFF,0x7F,0xDF,0x33,
+0xDD,0xFF,0x7F,0xFE,0xF7,0xFC,0x7F,0xFB, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA9,
+0xFF,0xFD,0xFF,0xFF,0xFE,0xFF,0xFF,0xDF, 0xFF,0xFF,0xEF,0xEF,0xFD,0xFF,0x7F,0xFF,
+0xFF,0xFF,0xFF,0xFE,0xA7,0xFF,0xFF,0xFF, 0x77,0xDF,0xF7,0xFD,0x9F,0x7F,0xFE,0x77,
+0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xAF,0xBF,0xAF,0xFF,0xF9,0xBE,0xBF,
+0x8F,0xFB,0xFE,0xFE,0xEF,0xFB,0xFE,0xFF, 0xBF,0xEF,0xFB,0xFF,0xFF,0xFD,0xDF,0x6F,
+0xEF,0xFF,0x7F,0xFF,0xBF,0xBF,0xDF,0xFF, 0xFC,0xFF,0xDF,0xF7,0xFD,0xEF,0x7F,0xDF,
+0xFF,0xFF,0xFF,0x3F,0xF6,0xFF,0xCF,0xFF, 0xDB,0xFB,0xF7,0xFF,0xEB,0x7A,0xFF,0xFF,
+0xFF,0xBF,0xEF,0xFB,0xFF,0xFF,0xFF,0xFE, 0x6D,0xFD,0xFF,0x5F,0xFB,0xFF,0xFF,0xF7,
+0xFF,0x5F,0xF5,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xF8,0xFF,0xFB,0xFF,
+0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xE7,0xF6, 0xBF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,
+0xFF,0xC9,0xFF,0xFF,0xFF,0xBD,0xFF,0xBF, 0xAF,0xEF,0xEF,0x3F,0xD1,0xFC,0x7F,0xFB,
+0xC7,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3,0xFF, 0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0x77,0xFF,
+0xDF,0xB7,0xFD,0xF7,0xFD,0xF7,0xFF,0xFF, 0xFF,0xFF,0xFF,0x57,0xFF,0xF7,0xA5,0xFD,
+0x3F,0xDF,0xBF,0xBF,0xFE,0x7F,0xFF,0xFF, 0xFF,0xDF,0xFA,0xFD,0xFF,0xFF,0xFF,0xFE,
+0x87,0xFF,0xE9,0xFF,0xFE,0xEF,0xBF,0xEF, 0xFE,0xFE,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFA,0x9F,0xFF,0x3F, 0xFF,0xFD,0xFD,0x57,0xDF,0xFD,0xF3,0xFF,
+0xDF,0xFD,0xFF,0x5F,0xDF,0xF5,0xFD,0xFF, 0xFF,0xF9,0x8F,0xFF,0xFF,0xFF,0xEE,0x7F,
+0xFF,0xFF,0xBF,0x5E,0xFE,0xEC,0xFB,0x3F, 0x7F,0x9F,0xEF,0xF9,0xFF,0xFF,0xCD,0x6B,
+0xFF,0xFF,0xFF,0xC5,0xF3,0xFC,0xFA,0x38, 0xFF,0xAF,0x3F,0xEE,0x7F,0x9F,0xFF,0xD9,
+0xFF,0xFF,0xFD,0x7A,0xF7,0xFF,0xF3,0xFF, 0xAF,0x6F,0xDB,0xF2,0xB9,0xE9,0xFB,0xFF,
+0xFF,0xFF,0xFE,0xFF,0xFF,0xEF,0xFF,0xFB, 0xC5,0xBF,0xFF,0xEF,0xFF,0x5E,0xB7,0xAD,
+0xCD,0x79,0x7C,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0x93,0xFF,0xEF,
+0xEA,0xFE,0xBF,0xEF,0x5B,0xD2,0xCD,0xF5, 0x6D,0x77,0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,
+0xFF,0xFF,0x66,0xFF,0xD5,0x65,0x7D,0x5F, 0x75,0x9D,0x65,0x7F,0xD6,0xFB,0x4F,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xC7, 0xFF,0xBF,0xEF,0xFA,0xFE,0xFF,0xBF,0xEB,
+0xFF,0xDF,0xFF,0x7E,0xFF,0xFF,0xEF,0xFD, 0x7E,0xD7,0xFF,0x78,0xDF,0xFF,0x5F,0xDF,
+0xF5,0xBF,0x7F,0xDF,0xC5,0xFF,0x3F,0xF6, 0x7E,0xFF,0x0F,0xEF,0xF2,0x3E,0xBF,0xFF,
+0xFB,0x3F,0xFF,0xFB,0x7F,0xFF,0xB3,0xFE, 0xFB,0xF6,0xFD,0xFF,0xDA,0xF7,0xFD,0xFF,
+0x7F,0xDF,0xF7,0xBF,0xFF,0xFA,0x7F,0xFF, 0xFF,0xFF,0xFF,0x9F,0xFF,0xF3,0xDC,0xF9,
+0xBF,0xCE,0xE7,0xF9,0xFE,0x7F,0x9F,0xE7, 0xFF,0xFF,0xE2,0x7F,0xFE,0xFF,0xBF,0xEF,
+0xEB,0xFA,0xFF,0x9F,0x67,0x1E,0xFF,0x8F, 0xE7,0xF8,0xFE,0x7F,0x8F,0xEF,0xFF,0xBD,
+0xBF,0xFF,0xFB,0xFF,0xFF,0xDF,0xF7,0xFF, 0xFC,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFD,0xB3,0xFF,0xFF,0xEF, 0xFF,0xFF,0xBF,0xED,0xFF,0xFB,0xEE,0xFE,
+0xFF,0xFF,0xEF,0xFF,0xFE,0xFF,0xFF,0xFF, 0xFF,0xB5,0xFF,0xB7,0xFD,0xFD,0x6E,0xFF,
+0xFF,0xFE,0xFD,0x2F,0xD8,0xFE,0xBF,0x8F, 0xEB,0xF9,0xFE,0x3F,0xFF,0xFA,0xCF,0xFF,
+0xE7,0xD9,0xFA,0xBF,0xDF,0x77,0xFC,0xFB, 0x3F,0xAB,0xFE,0xFF,0xBF,0xEF,0xFB,0xFE,
+0xFF,0xFF,0xEE,0x1F,0xFF,0xDF,0xF7,0xFF, 0xFF,0xFF,0x5F,0x97,0x35,0xBF,0x5E,0xFE,
+0xBF,0xEF,0xFF,0xF7,0xFD,0xFF,0xFF,0xFA, 0xBF,0xFF,0xBE,0x6F,0x9F,0xE7,0xF8,0xBE,
+0x2F,0x8B,0x66,0x94,0x7D,0x9D,0xE7,0xF9, 0xFE,0x7F,0x9F,0xE7,0xF1,0x7F,0xFF,0xFF,
+0xFF,0xF7,0xF5,0xFD,0x7F,0x5F,0xFB,0xFD, 0x9E,0xFF,0xFB,0xFE,0xFF,0xFF,0xEF,0xFF,
+0xFF,0xA0,0xFF,0xFF,0xFF,0xBF,0xEF,0xEB, 0xFA,0xFE,0xBF,0xB7,0xF7,0xF7,0xFF,0xFF,
+0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF, 0xFD,0xFF,0xFF,0xFF,0xD7,0xFF,0xFF,0xFF,
+0x7F,0xF5,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF, 0xBF,0xFF,0xFF,0xAB,0xFE,0xFB,0xFE,0xFF,
+0xF7,0xAF,0xFF,0xFF,0xDE,0xF7,0xEB,0x5F, 0xDF,0xF7,0xFD,0xFF,0x7F,0xDF,0xFF,0xFF,
+0xB3,0xFF,0xC9,0xFE,0xFF,0xFF,0xFF,0xFF, 0xD6,0xFF,0xFF,0xCB,0xFF,0xFF,0xDF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFC,0x8F,0xFF,0xBA, 0xBE,0xBF,0xAF,0xEB,0x78,0xFE,0xB7,0xAD,
+0x3A,0xFE,0xB7,0xAF,0xEB,0x7A,0xFE,0xBF, 0xAF,0xFF,0x9F,0xFF,0xFF,0xDF,0xFC,0xFF,
+0xFF,0xFE,0xC3,0xFE,0xFF,0xFF,0x33,0xFC, 0xFF,0xBF,0xDF,0xF3,0xFF,0xFF,0xBB,0x9F,
+0xFF,0xFF,0xFF,0xEB,0xDF,0xFF,0xFF,0xAF, 0xF7,0x6F,0xF9,0xBF,0xEF,0xFD,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xE3,0x7F,0xFF,0xFF,0xFF, 0xFB,0xFF,0xFF,0xBF,0xFD,0xFB,0xF7,0xFF,
+0xDF,0xF7,0xFF,0xFE,0xEF,0x5F,0xBD,0xFF, 0xFA,0xFF,0xF8,0xFF,0xBF,0xAF,0xFB,0xFE,
+0xFE,0x3F,0xEF,0xE8,0xFF,0xDF,0xF3,0xFD, 0xFF,0xFF,0xFF,0xFF,0xFF,0xED,0xFF,0xFB,
+0xFD,0xFF,0xAF,0xFF,0xFF,0xFE,0xFE,0xBF, 0xDB,0xFF,0xFF,0xFF,0xBF,0xFF,0xDF,0xFF,
+0xFD,0xFF,0xCB,0xFF,0xFF,0xFF,0xFF,0xFF, 0xBF,0x6F,0xFF,0x7F,0xB7,0xB3,0xFF,0xFF,
+0xDF,0xFF,0xFB,0xEF,0xFF,0xFF,0xFF,0x07, 0xFF,0xFB,0xFF,0xFF,0xFF,0xED,0xFF,0xF5,
+0x7C,0xFF,0x7F,0xFE,0xFF,0xFF,0xEF,0xCF, 0xFF,0xFB,0xFF,0xFF,0x2F,0xFF,0xFF,0xFF,
+0xFF,0xF3,0xFF,0xFB,0xFF,0xFE,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,
+0xFD,0x1B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFE,0x7C,0xFF,0xFF,0xFF,0xFF,
+0xEF,0xFF,0xFF,0xFF,0xFF,0xFB,0xBF,0x7F, 0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD, 0xFF,0xFF,0xF0,0x7F,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xDF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xBF,0xFE,
+0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xEF,0xFE,0xFF,0xBF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xEF,0xFA,0xB5,0xFF,0xFF,0xFF, 0xF7,0xF7,0xFF,0xFF,0xFF,0xFF,0xDF,0xFB,
+0xFC,0xFF,0xFF,0xFE,0xFF,0x7F,0xDF,0xBF, 0xFF,0xCB,0xBF,0xF9,0xFE,0x7F,0x9F,0xE7,
+0xF9,0xFE,0x7F,0x97,0xE1,0xFE,0x79,0x9F, 0xE7,0xFD,0xFE,0x7F,0xDF,0xFE,0x37,0xFF,
+0xFB,0xDE,0xDE,0xBD,0xEF,0xF3,0xFE,0xFB, 0xAF,0xEB,0xFE,0xFF,0xFF,0xCF,0xFF,0xFE,
+0xFF,0xBF,0xFF,0x8F,0xFF,0xEF,0xFB,0xFE, 0xFF,0xBF,0xE7,0xF9,0x5E,0x7F,0xEF,0xFB,
+0xDA,0xFF,0xBF,0xEF,0xFB,0xFE,0xFF,0xFD, 0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,
+0xFF,0xFF,0x7F,0xFF,0xFF,0xF7,0xFB,0x7F, 0xFF,0xFF,0xFF,0xFF,0xFC,0x3F,0xFF,0xBF,
+0xEF,0xFB,0xFE,0xFF,0xBF,0xEF,0x7B,0x7F, 0xBF,0xEF,0xFB,0xFE,0xFF,0xB5,0xEF,0xFB,
+0xBF,0xFA,0x7F,0xFC,0xFF,0x3F,0xCF,0xF3, 0xFC,0xFF,0x3F,0xCF,0xBC,0xFF,0x3F,0xEF,
+0xF3,0xFC,0xFE,0x3F,0xCF,0xFF,0xEE,0xEF, 0xFB,0xFE,0xFF,0xBF,0xEF,0xFB,0x6A,0xD7,
+0xB7,0xFB,0xF8,0xFF,0xB7,0xEF,0xBA,0xFE, 0xFF,0xBF,0x7F,0xE9,0xFF,0xF9,0x7E,0x5F,
+0x97,0xE5,0xF9,0xFE,0x7F,0xBF,0xF9,0x7E, 0x5F,0x9F,0xE5,0xFB,0xFE,0x5F,0xB7,0xFF,
+0xA3,0xFF,0xF7,0xFD,0xFF,0x7F,0xDF,0xF7, 0xFD,0xFF,0x5E,0xF7,0x7D,0xFF,0x77,0xDF,
+0xF7,0xFD,0xFF,0x7F,0xFF,0xD7,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFD,0xDF,0xFB,0x7F,
+0xFF,0xFF,0xEF,0xFF,0xFE,0xFB,0xFF,0xFF, 0xBF,0xFE,0x8F,0xFF,0xDF,0xF7,0xFD,0xFD,
+0x7F,0xDF,0xF7,0xFD,0x3E,0xDF,0xF5,0xBD, 0xFF,0x7F,0xDF,0xF7,0xFD,0xF7,0xFF,0x9F,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFD,0xFF,0xBE,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFD,0x3F,0xFF,0xDF,0xF7, 0xFD,0xFF,0x7F,0xDF,0xF7,0xFD,0xFF,0xCF,
+0x77,0xFC,0xFF,0x5F,0xDF,0xF7,0xFD,0xFF, 0xF4,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFD,0xFF,0xFF,0xFF,0xEE,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xED,0xFB,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xE9,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFB,0xFF,0xFF,0xFF,0xD3,0xFF,0xFF,
+0xBF,0x3F,0xFB,0xFF,0xFF,0xFF,0xFB,0xF3, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xF7, 0xFF,0xFF,0xFF,0xFF,0x17,0xFF,0xFF,0xFF,
+0xDF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF, 0xDF,0xDF,0xFF,0xFD,0xFF,0xFF,0xDF,0xF7,
+0xFF,0x4F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFD,
+0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0x9F,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF, 0xFF,0xFF,0x7A,0x3F,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF2,
+0x7F,0xFF,0xFB,0xFE,0xFF,0xBF,0xEF,0xF8, 0xFE,0xFF,0xBF,0xFB,0xFE,0xFF,0x8F,0xEC,
+0xFB,0xFE,0xFF,0xBF,0xF8,0xF7,0xFE,0xFF, 0xBF,0xEF,0xFB,0xFE,0xFD,0xBF,0xCF,0xEC,
+0xFF,0x3F,0xEF,0xDB,0xF8,0xFF,0xBF,0xCF, 0xFF,0xF9,0xFF,0xFF,0xBF,0xFF,0xFB,0xFF,
+0xFF,0xFF,0xEF,0xFB,0xDF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xBB,0xFF,
+0xEF,0xFB,0xFE,0xEF,0xBF,0xEE,0xEB,0xFB, 0xFE,0xFF,0xEF,0xFE,0xEE,0xBF,0xFE,0xEB,
+0xFF,0xEF,0xFF,0x17,0xFF,0x7E,0xEB,0xBB, 0xFE,0xBF,0xBE,0xFB,0xEF,0x5B,0xF7,0xBD,
+0xFB,0xCF,0xBF,0xBF,0xBB,0xFB,0x7E,0xCC, 0xEF,0xFF
+
+};
diff --git a/drivers/usb/dabusb.c b/drivers/usb/dabusb.c
index a9fb06dbe..56e7cc400 100644
--- a/drivers/usb/dabusb.c
+++ b/drivers/usb/dabusb.c
@@ -44,8 +44,7 @@
#include "usb.h"
#include "dabusb.h"
-#include "bitstream.h"
-#include "firmware.h"
+#include "dabfirmware.h"
/* --------------------------------------------------------------------- */
#define NRDABUSB 4
diff --git a/drivers/usb/dc2xx.c b/drivers/usb/dc2xx.c
index a290f7c4d..7cc2caf9f 100644
--- a/drivers/usb/dc2xx.c
+++ b/drivers/usb/dc2xx.c
@@ -148,7 +148,7 @@ static ssize_t camera_read (struct file *file,
* they matter in the application protocol.
*/
for (retries = 0; retries < MAX_READ_RETRY; retries++) {
- unsigned long count;
+ int count;
int result;
if (signal_pending (current)) {
@@ -216,7 +216,7 @@ static ssize_t camera_write (struct file *file,
}
while (thistime) {
int result;
- unsigned long count;
+ int count;
if (signal_pending (current)) {
if (!bytes_written)
diff --git a/drivers/usb/devices.c b/drivers/usb/devices.c
index 1fc6d5001..483a770f4 100644
--- a/drivers/usb/devices.c
+++ b/drivers/usb/devices.c
@@ -309,7 +309,7 @@ static char *usb_dump_device_strings (char *start, char *end, struct usb_device
return start;
}
-static char *usb_dump_desc(char *start, char *end, const struct usb_device *dev)
+static char *usb_dump_desc(char *start, char *end, struct usb_device *dev)
{
int i;
@@ -365,7 +365,7 @@ static char *usb_dump_string(char *start, char *end, const struct usb_device *de
/*****************************************************************/
-static char *usb_device_dump(char *start, char *end, const struct usb_device *usbdev,
+static char *usb_device_dump(char *start, char *end, struct usb_device *usbdev,
int bus, int level, int index, int count)
{
int chix;
diff --git a/drivers/usb/firmware.h b/drivers/usb/firmware.h
deleted file mode 100644
index a742558fb..000000000
--- a/drivers/usb/firmware.h
+++ /dev/null
@@ -1,3213 +0,0 @@
-//$Id: firmware.h,v 1.1 1999/12/17 08:55:05 fliegl Exp $
-static INTEL_HEX_RECORD firmware[] = {
-{ 2,
- 0x0,
- 0,
- {0x21,0x57}
-},
-{ 3,
- 0x3,
- 0,
- {0x02,0x01,0x66}
-},
-{ 3,
- 0xb,
- 0,
- {0x02,0x01,0x66}
-},
-{ 3,
- 0x13,
- 0,
- {0x02,0x01,0x66}
-},
-{ 3,
- 0x1b,
- 0,
- {0x02,0x01,0x66}
-},
-{ 3,
- 0x23,
- 0,
- {0x02,0x01,0x66}
-},
-{ 3,
- 0x2b,
- 0,
- {0x02,0x01,0x66}
-},
-{ 3,
- 0x33,
- 0,
- {0x02,0x03,0x0f}
-},
-{ 3,
- 0x3b,
- 0,
- {0x02,0x01,0x66}
-},
-{ 3,
- 0x43,
- 0,
- {0x02,0x01,0x00}
-},
-{ 3,
- 0x4b,
- 0,
- {0x02,0x01,0x66}
-},
-{ 3,
- 0x53,
- 0,
- {0x02,0x01,0x66}
-},
-{ 3,
- 0x5b,
- 0,
- {0x02,0x04,0xbd}
-},
-{ 3,
- 0x63,
- 0,
- {0x02,0x01,0x67}
-},
-{ 3,
- 0x100,
- 0,
- {0x02,0x0c,0x5a}
-},
-{ 3,
- 0x104,
- 0,
- {0x02,0x01,0xed}
-},
-{ 3,
- 0x108,
- 0,
- {0x02,0x02,0x51}
-},
-{ 3,
- 0x10c,
- 0,
- {0x02,0x02,0x7c}
-},
-{ 3,
- 0x110,
- 0,
- {0x02,0x02,0xe4}
-},
-{ 1,
- 0x114,
- 0,
- {0x32}
-},
-{ 1,
- 0x118,
- 0,
- {0x32}
-},
-{ 3,
- 0x11c,
- 0,
- {0x02,0x05,0xfd}
-},
-{ 3,
- 0x120,
- 0,
- {0x02,0x00,0x00}
-},
-{ 3,
- 0x124,
- 0,
- {0x02,0x00,0x00}
-},
-{ 3,
- 0x128,
- 0,
- {0x02,0x04,0x3c}
-},
-{ 3,
- 0x12c,
- 0,
- {0x02,0x04,0x6a}
-},
-{ 3,
- 0x130,
- 0,
- {0x02,0x00,0x00}
-},
-{ 3,
- 0x134,
- 0,
- {0x02,0x00,0x00}
-},
-{ 3,
- 0x138,
- 0,
- {0x02,0x00,0x00}
-},
-{ 3,
- 0x13c,
- 0,
- {0x02,0x00,0x00}
-},
-{ 3,
- 0x140,
- 0,
- {0x02,0x00,0x00}
-},
-{ 3,
- 0x144,
- 0,
- {0x02,0x00,0x00}
-},
-{ 3,
- 0x148,
- 0,
- {0x02,0x00,0x00}
-},
-{ 3,
- 0x14c,
- 0,
- {0x02,0x00,0x00}
-},
-{ 3,
- 0x150,
- 0,
- {0x02,0x00,0x00}
-},
-{ 3,
- 0x154,
- 0,
- {0x02,0x00,0x00}
-},
-{ 10,
- 0x157,
- 0,
- {0x75,0x81,0x7f,0xe5,0x82,0x60,0x03,0x02,0x01,0x61}
-},
-{ 5,
- 0x161,
- 0,
- {0x12,0x07,0x6f,0x21,0x64}
-},
-{ 1,
- 0x166,
- 0,
- {0x32}
-},
-{ 14,
- 0x167,
- 0,
- {0xc0,0xd0,0xc0,0x86,0xc0,0x82,0xc0,0x83,0xc0,0xe0,0x90,0x7f,0x97,0xe0}
-},
-{ 14,
- 0x175,
- 0,
- {0x44,0x80,0xf0,0x90,0x7f,0x69,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0}
-},
-{ 14,
- 0x183,
- 0,
- {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0}
-},
-{ 14,
- 0x191,
- 0,
- {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x90,0x7f,0x97,0xe0}
-},
-{ 3,
- 0x19f,
- 0,
- {0x55,0x7f,0xf0}
-},
-{ 14,
- 0x1a2,
- 0,
- {0x90,0x7f,0x9a,0xe0,0x30,0xe4,0x23,0x90,0x7f,0x68,0xf0,0xf0,0xf0,0xf0}
-},
-{ 14,
- 0x1b0,
- 0,
- {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0}
-},
-{ 14,
- 0x1be,
- 0,
- {0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0}
-},
-{ 14,
- 0x1cc,
- 0,
- {0xe5,0xd8,0xc2,0xe3,0xf5,0xd8,0xd0,0xe0,0xd0,0x83,0xd0,0x82,0xd0,0x86}
-},
-{ 3,
- 0x1da,
- 0,
- {0xd0,0xd0,0x32}
-},
-{ 8,
- 0x1dd,
- 0,
- {0x75,0x86,0x00,0x90,0xff,0xc3,0x7c,0x05}
-},
-{ 7,
- 0x1e5,
- 0,
- {0xa3,0xe5,0x82,0x45,0x83,0x70,0xf9}
-},
-{ 1,
- 0x1ec,
- 0,
- {0x22}
-},
-{ 14,
- 0x1ed,
- 0,
- {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0xd0}
-},
-{ 14,
- 0x1fb,
- 0,
- {0x75,0xd0,0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91}
-},
-{ 13,
- 0x209,
- 0,
- {0x90,0x88,0x00,0xe0,0xf5,0x41,0x90,0x7f,0xab,0x74,0x02,0xf0,0x90}
-},
-{ 9,
- 0x216,
- 0,
- {0x7f,0xab,0x74,0x02,0xf0,0xe5,0x32,0x60,0x21}
-},
-{ 4,
- 0x21f,
- 0,
- {0x7a,0x00,0x7b,0x00}
-},
-{ 11,
- 0x223,
- 0,
- {0xc3,0xea,0x94,0x18,0xeb,0x64,0x80,0x94,0x80,0x50,0x12}
-},
-{ 14,
- 0x22e,
- 0,
- {0x90,0x7f,0x69,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0x0a,0xba,0x00}
-},
-{ 2,
- 0x23c,
- 0,
- {0x01,0x0b}
-},
-{ 2,
- 0x23e,
- 0,
- {0x80,0xe3}
-},
-{ 2,
- 0x240,
- 0,
- {0xd0,0x86}
-},
-{ 14,
- 0x242,
- 0,
- {0xd0,0xd0,0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0}
-},
-{ 1,
- 0x250,
- 0,
- {0x32}
-},
-{ 14,
- 0x251,
- 0,
- {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0}
-},
-{ 14,
- 0x25f,
- 0,
- {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xab,0x74}
-},
-{ 4,
- 0x26d,
- 0,
- {0x04,0xf0,0xd0,0x86}
-},
-{ 11,
- 0x271,
- 0,
- {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32}
-},
-{ 14,
- 0x27c,
- 0,
- {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04}
-},
-{ 14,
- 0x28a,
- 0,
- {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0}
-},
-{ 13,
- 0x298,
- 0,
- {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90}
-},
-{ 12,
- 0x2a5,
- 0,
- {0x7f,0xab,0x74,0x08,0xf0,0x75,0x6e,0x00,0x75,0x6f,0x02,0x12}
-},
-{ 6,
- 0x2b1,
- 0,
- {0x11,0x44,0x75,0x70,0x39,0x75}
-},
-{ 6,
- 0x2b7,
- 0,
- {0x71,0x0c,0x75,0x72,0x02,0x12}
-},
-{ 12,
- 0x2bd,
- 0,
- {0x11,0x75,0x90,0x7f,0xd6,0xe4,0xf0,0x75,0xd8,0x20,0xd0,0x86}
-},
-{ 14,
- 0x2c9,
- 0,
- {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04}
-},
-{ 13,
- 0x2d7,
- 0,
- {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32}
-},
-{ 14,
- 0x2e4,
- 0,
- {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0}
-},
-{ 14,
- 0x2f2,
- 0,
- {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xab,0x74}
-},
-{ 4,
- 0x300,
- 0,
- {0x10,0xf0,0xd0,0x86}
-},
-{ 11,
- 0x304,
- 0,
- {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32}
-},
-{ 14,
- 0x30f,
- 0,
- {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04}
-},
-{ 14,
- 0x31d,
- 0,
- {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0}
-},
-{ 12,
- 0x32b,
- 0,
- {0x00,0xc0,0x86,0x75,0x86,0x00,0x75,0x6e,0x00,0x75,0x6f,0x02}
-},
-{ 7,
- 0x337,
- 0,
- {0x12,0x11,0x44,0x75,0x70,0x40,0x75}
-},
-{ 6,
- 0x33e,
- 0,
- {0x71,0x0c,0x75,0x72,0x02,0x12}
-},
-{ 14,
- 0x344,
- 0,
- {0x11,0x75,0x90,0x7f,0xd6,0x74,0x02,0xf0,0x90,0x7f,0xd6,0x74,0x06,0xf0}
-},
-{ 5,
- 0x352,
- 0,
- {0x75,0xd8,0x10,0xd0,0x86}
-},
-{ 14,
- 0x357,
- 0,
- {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04}
-},
-{ 13,
- 0x365,
- 0,
- {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32}
-},
-{ 13,
- 0x372,
- 0,
- {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x90,0x7f,0xa6,0x74,0x9a,0xf0,0x12}
-},
-{ 12,
- 0x37f,
- 0,
- {0x10,0x1b,0x90,0x7f,0xa6,0xe5,0x42,0xf0,0x12,0x10,0x1b,0x90}
-},
-{ 13,
- 0x38b,
- 0,
- {0x7f,0xa6,0xe5,0x43,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa5,0x74,0x40}
-},
-{ 1,
- 0x398,
- 0,
- {0xf0}
-},
-{ 1,
- 0x399,
- 0,
- {0x22}
-},
-{ 13,
- 0x39a,
- 0,
- {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x90,0x7f,0xa6,0x74,0x9a,0xf0,0x12}
-},
-{ 12,
- 0x3a7,
- 0,
- {0x10,0x1b,0x90,0x7f,0xa6,0xe5,0x44,0xf0,0x12,0x10,0x1b,0x90}
-},
-{ 12,
- 0x3b3,
- 0,
- {0x7f,0xa6,0xe5,0x45,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa6,0xe5}
-},
-{ 11,
- 0x3bf,
- 0,
- {0x46,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa5,0x74,0x40,0xf0}
-},
-{ 1,
- 0x3ca,
- 0,
- {0x22}
-},
-{ 10,
- 0x3cb,
- 0,
- {0x75,0x44,0x02,0x75,0x45,0x00,0x75,0x46,0x00,0x12}
-},
-{ 9,
- 0x3d5,
- 0,
- {0x03,0x9a,0x75,0x42,0x03,0x75,0x43,0x00,0x12}
-},
-{ 2,
- 0x3de,
- 0,
- {0x03,0x72}
-},
-{ 1,
- 0x3e0,
- 0,
- {0x22}
-},
-{ 12,
- 0x3e1,
- 0,
- {0x90,0x88,0x00,0xe5,0x36,0xf0,0x90,0x88,0x00,0x74,0x10,0x25}
-},
-{ 9,
- 0x3ed,
- 0,
- {0x36,0xf0,0x12,0x01,0xdd,0x75,0x42,0x01,0x75}
-},
-{ 9,
- 0x3f6,
- 0,
- {0x43,0x18,0x12,0x03,0x72,0x75,0x44,0x02,0x75}
-},
-{ 9,
- 0x3ff,
- 0,
- {0x45,0x00,0x75,0x46,0x00,0x12,0x03,0x9a,0x75}
-},
-{ 8,
- 0x408,
- 0,
- {0x42,0x03,0x75,0x43,0x44,0x12,0x03,0x72}
-},
-{ 1,
- 0x410,
- 0,
- {0x22}
-},
-{ 14,
- 0x411,
- 0,
- {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0}
-},
-{ 14,
- 0x41f,
- 0,
- {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xaa,0x74}
-},
-{ 4,
- 0x42d,
- 0,
- {0x02,0xf0,0xd0,0x86}
-},
-{ 11,
- 0x431,
- 0,
- {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32}
-},
-{ 14,
- 0x43c,
- 0,
- {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0}
-},
-{ 14,
- 0x44a,
- 0,
- {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xa9,0x74}
-},
-{ 7,
- 0x458,
- 0,
- {0x04,0xf0,0x75,0x30,0x01,0xd0,0x86}
-},
-{ 11,
- 0x45f,
- 0,
- {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32}
-},
-{ 14,
- 0x46a,
- 0,
- {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0}
-},
-{ 14,
- 0x478,
- 0,
- {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90,0x7f,0xaa,0x74}
-},
-{ 7,
- 0x486,
- 0,
- {0x04,0xf0,0x75,0x31,0x01,0xd0,0x86}
-},
-{ 11,
- 0x48d,
- 0,
- {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32}
-},
-{ 14,
- 0x498,
- 0,
- {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0}
-},
-{ 12,
- 0x4a6,
- 0,
- {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe5,0xf5,0x91,0xd0,0x86}
-},
-{ 11,
- 0x4b2,
- 0,
- {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32}
-},
-{ 14,
- 0x4bd,
- 0,
- {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0xd0,0x75,0xd0,0x00,0xc0}
-},
-{ 12,
- 0x4cb,
- 0,
- {0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe7,0xf5,0x91,0xd0,0x86}
-},
-{ 11,
- 0x4d7,
- 0,
- {0xd0,0xd0,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32}
-},
-{ 12,
- 0x4e2,
- 0,
- {0x90,0x7f,0xea,0xe0,0xfa,0x8a,0x20,0x90,0x7f,0x96,0xe4,0xf0}
-},
-{ 1,
- 0x4ee,
- 0,
- {0x22}
-},
-{ 7,
- 0x4ef,
- 0,
- {0x90,0x7f,0xea,0xe0,0xfa,0x8a,0x21}
-},
-{ 1,
- 0x4f6,
- 0,
- {0x22}
-},
-{ 14,
- 0x4f7,
- 0,
- {0x90,0x17,0x13,0xe0,0xfa,0x90,0x17,0x15,0xe0,0xfb,0x74,0x80,0x2a,0xfa}
-},
-{ 14,
- 0x505,
- 0,
- {0x74,0x80,0x2b,0xfb,0xea,0x03,0x03,0x54,0x3f,0xfc,0xea,0xc4,0x23,0x54}
-},
-{ 14,
- 0x513,
- 0,
- {0x1f,0xfa,0x2c,0xfa,0xeb,0x03,0x03,0x54,0x3f,0xfc,0xeb,0xc4,0x23,0x54}
-},
-{ 11,
- 0x521,
- 0,
- {0x1f,0xfb,0x2c,0xfb,0x90,0x17,0x0a,0xe0,0xfc,0x60,0x02}
-},
-{ 2,
- 0x52c,
- 0,
- {0x7a,0x00}
-},
-{ 7,
- 0x52e,
- 0,
- {0x90,0x17,0x0c,0xe0,0xfc,0x60,0x02}
-},
-{ 2,
- 0x535,
- 0,
- {0x7b,0x00}
-},
-{ 11,
- 0x537,
- 0,
- {0xea,0x2b,0xfc,0xc3,0x13,0xf5,0x3a,0x75,0x44,0x02,0x8b}
-},
-{ 7,
- 0x542,
- 0,
- {0x45,0x8a,0x46,0x12,0x03,0x9a,0x75}
-},
-{ 9,
- 0x549,
- 0,
- {0x6e,0x08,0x75,0x6f,0x00,0x12,0x11,0x44,0x75}
-},
-{ 4,
- 0x552,
- 0,
- {0x70,0x47,0x75,0x71}
-},
-{ 8,
- 0x556,
- 0,
- {0x0c,0x75,0x72,0x02,0x12,0x11,0x75,0x85}
-},
-{ 5,
- 0x55e,
- 0,
- {0x3a,0x73,0x12,0x11,0xa0}
-},
-{ 1,
- 0x563,
- 0,
- {0x22}
-},
-{ 14,
- 0x564,
- 0,
- {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x65,0x02,0xf0,0x90}
-},
-{ 14,
- 0x572,
- 0,
- {0x7f,0xeb,0xe0,0xfa,0x90,0x7f,0xea,0xe0,0xfb,0x90,0x7f,0xef,0xe0,0xfc}
-},
-{ 14,
- 0x580,
- 0,
- {0x33,0x95,0xe0,0xfd,0x8c,0x05,0x7c,0x00,0x90,0x7f,0xee,0xe0,0xfe,0x33}
-},
-{ 14,
- 0x58e,
- 0,
- {0x95,0xe0,0xff,0xec,0x2e,0xfc,0xed,0x3f,0xfd,0x90,0x7f,0xe9,0xe0,0xfe}
-},
-{ 5,
- 0x59c,
- 0,
- {0xbe,0x01,0x02,0x80,0x03}
-},
-{ 3,
- 0x5a1,
- 0,
- {0x02,0x05,0xf9}
-},
-{ 6,
- 0x5a4,
- 0,
- {0xbc,0x01,0x21,0xbd,0x00,0x1e}
-},
-{ 14,
- 0x5aa,
- 0,
- {0xea,0xc4,0x03,0x54,0xf8,0xfc,0xeb,0x25,0xe0,0xfd,0x2c,0x24,0x00,0xfc}
-},
-{ 14,
- 0x5b8,
- 0,
- {0xe4,0x34,0x17,0xfd,0x90,0x7e,0xc0,0xe0,0xfe,0x8c,0x82,0x8d,0x83,0xf0}
-},
-{ 2,
- 0x5c6,
- 0,
- {0x80,0x31}
-},
-{ 14,
- 0x5c8,
- 0,
- {0xea,0xc4,0x03,0x54,0xf8,0xfa,0xeb,0x25,0xe0,0xfb,0x2a,0xfa,0x24,0x00}
-},
-{ 14,
- 0x5d6,
- 0,
- {0xfb,0xe4,0x34,0x17,0xfc,0x90,0x7e,0xc0,0xe0,0xfd,0x8b,0x82,0x8c,0x83}
-},
-{ 14,
- 0x5e4,
- 0,
- {0xf0,0x74,0x01,0x2a,0x24,0x00,0xfa,0xe4,0x34,0x17,0xfb,0x90,0x7e,0xc1}
-},
-{ 7,
- 0x5f2,
- 0,
- {0xe0,0xfc,0x8a,0x82,0x8b,0x83,0xf0}
-},
-{ 3,
- 0x5f9,
- 0,
- {0x75,0x38,0x01}
-},
-{ 1,
- 0x5fc,
- 0,
- {0x22}
-},
-{ 14,
- 0x5fd,
- 0,
- {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04}
-},
-{ 14,
- 0x60b,
- 0,
- {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0}
-},
-{ 13,
- 0x619,
- 0,
- {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90}
-},
-{ 13,
- 0x626,
- 0,
- {0x7f,0xaa,0x74,0x01,0xf0,0x12,0x05,0x64,0x75,0x37,0x00,0xd0,0x86}
-},
-{ 14,
- 0x633,
- 0,
- {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04}
-},
-{ 13,
- 0x641,
- 0,
- {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32}
-},
-{ 14,
- 0x64e,
- 0,
- {0x90,0x7f,0xeb,0xe0,0xfa,0x90,0x7f,0xea,0xe0,0xfb,0x90,0x7f,0xee,0xe0}
-},
-{ 14,
- 0x65c,
- 0,
- {0xfc,0x33,0x95,0xe0,0xfd,0x90,0x7f,0x96,0xe0,0xfe,0x90,0x7f,0x96,0x74}
-},
-{ 14,
- 0x66a,
- 0,
- {0x80,0x65,0x06,0xf0,0x90,0x7f,0x00,0x74,0x01,0xf0,0xea,0xc4,0x03,0x54}
-},
-{ 14,
- 0x678,
- 0,
- {0xf8,0xfe,0xeb,0x25,0xe0,0xfb,0x2e,0xfe,0x24,0x00,0xfb,0xe4,0x34,0x17}
-},
-{ 14,
- 0x686,
- 0,
- {0xff,0x8b,0x82,0x8f,0x83,0xe0,0xfb,0x74,0x01,0x2e,0x24,0x00,0xfe,0xe4}
-},
-{ 14,
- 0x694,
- 0,
- {0x34,0x17,0xff,0x8e,0x82,0x8f,0x83,0xe0,0xfe,0x90,0x7f,0xe9,0xe0,0xff}
-},
-{ 3,
- 0x6a2,
- 0,
- {0xbf,0x81,0x0a}
-},
-{ 10,
- 0x6a5,
- 0,
- {0x90,0x7f,0x00,0xeb,0xf0,0x90,0x7f,0x01,0xee,0xf0}
-},
-{ 8,
- 0x6af,
- 0,
- {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x82,0x1a}
-},
-{ 3,
- 0x6b7,
- 0,
- {0xba,0x01,0x0c}
-},
-{ 12,
- 0x6ba,
- 0,
- {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0b}
-},
-{ 11,
- 0x6c6,
- 0,
- {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0x74,0xb5,0xf0}
-},
-{ 8,
- 0x6d1,
- 0,
- {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x83,0x1b}
-},
-{ 3,
- 0x6d9,
- 0,
- {0xba,0x01,0x0d}
-},
-{ 13,
- 0x6dc,
- 0,
- {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0b}
-},
-{ 11,
- 0x6e9,
- 0,
- {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0x74,0x12,0xf0}
-},
-{ 8,
- 0x6f4,
- 0,
- {0x90,0x7f,0xe9,0xe0,0xfb,0xbb,0x84,0x1c}
-},
-{ 3,
- 0x6fc,
- 0,
- {0xba,0x01,0x0d}
-},
-{ 13,
- 0x6ff,
- 0,
- {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x80,0x0c}
-},
-{ 12,
- 0x70c,
- 0,
- {0x90,0x7f,0x00,0x74,0x80,0xf0,0x90,0x7f,0x01,0x74,0x01,0xf0}
-},
-{ 5,
- 0x718,
- 0,
- {0x90,0x7f,0xb5,0xec,0xf0}
-},
-{ 1,
- 0x71d,
- 0,
- {0x22}
-},
-{ 12,
- 0x71e,
- 0,
- {0x75,0x36,0x0d,0x90,0x88,0x00,0x74,0x1d,0xf0,0x75,0x6b,0x80}
-},
-{ 10,
- 0x72a,
- 0,
- {0x75,0x6c,0x3c,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75}
-},
-{ 9,
- 0x734,
- 0,
- {0x6c,0x0f,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75}
-},
-{ 9,
- 0x73d,
- 0,
- {0x6c,0x06,0x12,0x10,0xe2,0x75,0x6b,0x80,0x75}
-},
-{ 7,
- 0x746,
- 0,
- {0x6c,0x01,0x12,0x10,0xe2,0x7a,0x00}
-},
-{ 3,
- 0x74d,
- 0,
- {0xba,0xff,0x00}
-},
-{ 2,
- 0x750,
- 0,
- {0x50,0x0a}
-},
-{ 10,
- 0x752,
- 0,
- {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xf1}
-},
-{ 10,
- 0x75c,
- 0,
- {0x75,0x6b,0x80,0x75,0x6c,0x3c,0x12,0x10,0xe2,0x75}
-},
-{ 8,
- 0x766,
- 0,
- {0x6b,0x80,0x75,0x6c,0x0f,0x12,0x10,0xe2}
-},
-{ 1,
- 0x76e,
- 0,
- {0x22}
-},
-{ 14,
- 0x76f,
- 0,
- {0x90,0x7f,0xa1,0xe4,0xf0,0x90,0x7f,0xaf,0x74,0x01,0xf0,0x90,0x7f,0x92}
-},
-{ 14,
- 0x77d,
- 0,
- {0x74,0x02,0xf0,0x75,0x8e,0x31,0x75,0x89,0x21,0x75,0x88,0x00,0x75,0xc8}
-},
-{ 14,
- 0x78b,
- 0,
- {0x00,0x75,0x8d,0x40,0x75,0x98,0x40,0x75,0xc0,0x40,0x75,0x87,0x00,0x75}
-},
-{ 9,
- 0x799,
- 0,
- {0x20,0x00,0x75,0x21,0x00,0x75,0x22,0x00,0x75}
-},
-{ 5,
- 0x7a2,
- 0,
- {0x23,0x00,0x75,0x47,0x00}
-},
-{ 7,
- 0x7a7,
- 0,
- {0xc3,0xe5,0x47,0x94,0x20,0x50,0x11}
-},
-{ 13,
- 0x7ae,
- 0,
- {0xe5,0x47,0x24,0x00,0xf5,0x82,0xe4,0x34,0x17,0xf5,0x83,0xe4,0xf0}
-},
-{ 4,
- 0x7bb,
- 0,
- {0x05,0x47,0x80,0xe8}
-},
-{ 9,
- 0x7bf,
- 0,
- {0xe4,0xf5,0x40,0xf5,0x3f,0xe4,0xf5,0x3c,0xf5}
-},
-{ 7,
- 0x7c8,
- 0,
- {0x3b,0xe4,0xf5,0x3e,0xf5,0x3d,0x75}
-},
-{ 11,
- 0x7cf,
- 0,
- {0x32,0x00,0x75,0x37,0x00,0x75,0x39,0x00,0x90,0x7f,0x93}
-},
-{ 14,
- 0x7da,
- 0,
- {0x74,0x3c,0xf0,0x90,0x7f,0x9c,0x74,0xff,0xf0,0x90,0x7f,0x96,0x74,0x80}
-},
-{ 14,
- 0x7e8,
- 0,
- {0xf0,0x90,0x7f,0x94,0x74,0x70,0xf0,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90}
-},
-{ 14,
- 0x7f6,
- 0,
- {0x7f,0x97,0xe4,0xf0,0x90,0x7f,0x95,0x74,0xc2,0xf0,0x90,0x7f,0x98,0x74}
-},
-{ 14,
- 0x804,
- 0,
- {0x28,0xf0,0x90,0x7f,0x9e,0x74,0x28,0xf0,0x90,0x7f,0xf0,0xe4,0xf0,0x90}
-},
-{ 14,
- 0x812,
- 0,
- {0x7f,0xf1,0xe4,0xf0,0x90,0x7f,0xf2,0xe4,0xf0,0x90,0x7f,0xf3,0xe4,0xf0}
-},
-{ 14,
- 0x820,
- 0,
- {0x90,0x7f,0xf4,0xe4,0xf0,0x90,0x7f,0xf5,0xe4,0xf0,0x90,0x7f,0xf6,0xe4}
-},
-{ 14,
- 0x82e,
- 0,
- {0xf0,0x90,0x7f,0xf7,0xe4,0xf0,0x90,0x7f,0xf8,0xe4,0xf0,0x90,0x7f,0xf9}
-},
-{ 14,
- 0x83c,
- 0,
- {0x74,0x38,0xf0,0x90,0x7f,0xfa,0x74,0xa0,0xf0,0x90,0x7f,0xfb,0x74,0xa0}
-},
-{ 14,
- 0x84a,
- 0,
- {0xf0,0x90,0x7f,0xfc,0x74,0xa0,0xf0,0x90,0x7f,0xfd,0x74,0xa0,0xf0,0x90}
-},
-{ 14,
- 0x858,
- 0,
- {0x7f,0xfe,0x74,0xa0,0xf0,0x90,0x7f,0xff,0x74,0xa0,0xf0,0x90,0x7f,0xe0}
-},
-{ 14,
- 0x866,
- 0,
- {0x74,0x03,0xf0,0x90,0x7f,0xe1,0x74,0x01,0xf0,0x90,0x7f,0xdd,0x74,0x80}
-},
-{ 11,
- 0x874,
- 0,
- {0xf0,0x12,0x12,0x43,0x12,0x07,0x1e,0x7a,0x00,0x7b,0x00}
-},
-{ 9,
- 0x87f,
- 0,
- {0xc3,0xea,0x94,0x1e,0xeb,0x94,0x00,0x50,0x17}
-},
-{ 12,
- 0x888,
- 0,
- {0x90,0x88,0x00,0xe0,0xf5,0x47,0x90,0x88,0x0b,0xe0,0xf5,0x47}
-},
-{ 9,
- 0x894,
- 0,
- {0x90,0x7f,0x68,0xf0,0x0a,0xba,0x00,0x01,0x0b}
-},
-{ 2,
- 0x89d,
- 0,
- {0x80,0xe0}
-},
-{ 12,
- 0x89f,
- 0,
- {0x12,0x03,0xe1,0x90,0x7f,0xd6,0xe4,0xf0,0x7a,0x00,0x7b,0x00}
-},
-{ 13,
- 0x8ab,
- 0,
- {0x8a,0x04,0x8b,0x05,0xc3,0xea,0x94,0xe0,0xeb,0x94,0x2e,0x50,0x1a}
-},
-{ 14,
- 0x8b8,
- 0,
- {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0}
-},
-{ 10,
- 0x8c6,
- 0,
- {0x04,0xd0,0x03,0xd0,0x02,0x0a,0xba,0x00,0x01,0x0b}
-},
-{ 2,
- 0x8d0,
- 0,
- {0x80,0xd9}
-},
-{ 13,
- 0x8d2,
- 0,
- {0x90,0x7f,0xd6,0x74,0x02,0xf0,0x90,0x7f,0xd6,0x74,0x06,0xf0,0x90}
-},
-{ 14,
- 0x8df,
- 0,
- {0x7f,0xde,0x74,0x05,0xf0,0x90,0x7f,0xdf,0x74,0x05,0xf0,0x90,0x7f,0xac}
-},
-{ 14,
- 0x8ed,
- 0,
- {0xe4,0xf0,0x90,0x7f,0xad,0x74,0x05,0xf0,0x75,0xa8,0x80,0x75,0xf8,0x10}
-},
-{ 13,
- 0x8fb,
- 0,
- {0x90,0x7f,0xae,0x74,0x0b,0xf0,0x90,0x7f,0xe2,0x74,0x88,0xf0,0x90}
-},
-{ 12,
- 0x908,
- 0,
- {0x7f,0xab,0x74,0x08,0xf0,0x75,0xe8,0x11,0x75,0x32,0x01,0x75}
-},
-{ 12,
- 0x914,
- 0,
- {0x31,0x00,0x75,0x30,0x00,0xc0,0x04,0xc0,0x05,0x12,0x04,0xf7}
-},
-{ 10,
- 0x920,
- 0,
- {0xd0,0x05,0xd0,0x04,0x75,0x34,0x00,0x75,0x35,0x01}
-},
-{ 13,
- 0x92a,
- 0,
- {0x90,0x7f,0xae,0x74,0x03,0xf0,0x8c,0x02,0xba,0x00,0x02,0x80,0x03}
-},
-{ 3,
- 0x937,
- 0,
- {0x02,0x0a,0x3f}
-},
-{ 12,
- 0x93a,
- 0,
- {0x85,0x33,0x34,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90,0x7f,0x97}
-},
-{ 14,
- 0x946,
- 0,
- {0x74,0x08,0xf0,0x90,0x7f,0x9d,0x74,0x88,0xf0,0x90,0x7f,0x9a,0xe0,0xfa}
-},
-{ 12,
- 0x954,
- 0,
- {0x74,0x05,0x5a,0xf5,0x33,0x90,0x7f,0x9d,0x74,0x8f,0xf0,0x90}
-},
-{ 13,
- 0x960,
- 0,
- {0x7f,0x97,0x74,0x02,0xf0,0x90,0x7f,0x9d,0x74,0x82,0xf0,0xe5,0x33}
-},
-{ 13,
- 0x96d,
- 0,
- {0x25,0xe0,0xfa,0x90,0x7f,0x9a,0xe0,0x54,0x05,0xfb,0x4a,0xf5,0x33}
-},
-{ 2,
- 0x97a,
- 0,
- {0x60,0x0c}
-},
-{ 12,
- 0x97c,
- 0,
- {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x4a,0xf0}
-},
-{ 11,
- 0x988,
- 0,
- {0x75,0x6e,0x00,0x75,0x6f,0x00,0xc0,0x04,0xc0,0x05,0x12}
-},
-{ 14,
- 0x993,
- 0,
- {0x11,0x44,0xd0,0x05,0xd0,0x04,0x90,0x17,0x13,0xe0,0xfa,0x74,0x80,0x2a}
-},
-{ 6,
- 0x9a1,
- 0,
- {0xfa,0xe5,0x33,0xb4,0x04,0x29}
-},
-{ 3,
- 0x9a7,
- 0,
- {0xba,0xa0,0x00}
-},
-{ 2,
- 0x9aa,
- 0,
- {0x50,0x24}
-},
-{ 13,
- 0x9ac,
- 0,
- {0x90,0x17,0x13,0xe0,0x04,0xfb,0x0b,0x90,0x17,0x13,0xeb,0xf0,0x90}
-},
-{ 14,
- 0x9b9,
- 0,
- {0x17,0x13,0xe0,0xfb,0x90,0x17,0x15,0xf0,0xc0,0x02,0xc0,0x04,0xc0,0x05}
-},
-{ 9,
- 0x9c7,
- 0,
- {0x12,0x04,0xf7,0xd0,0x05,0xd0,0x04,0xd0,0x02}
-},
-{ 5,
- 0x9d0,
- 0,
- {0xe5,0x33,0xb4,0x02,0x26}
-},
-{ 6,
- 0x9d5,
- 0,
- {0xc3,0x74,0x04,0x9a,0x50,0x20}
-},
-{ 13,
- 0x9db,
- 0,
- {0x90,0x17,0x13,0xe0,0xfa,0x1a,0x1a,0x90,0x17,0x13,0xea,0xf0,0x90}
-},
-{ 13,
- 0x9e8,
- 0,
- {0x17,0x13,0xe0,0xfa,0x90,0x17,0x15,0xf0,0xc0,0x04,0xc0,0x05,0x12}
-},
-{ 6,
- 0x9f5,
- 0,
- {0x04,0xf7,0xd0,0x05,0xd0,0x04}
-},
-{ 5,
- 0x9fb,
- 0,
- {0xe5,0x33,0xb4,0x08,0x1d}
-},
-{ 4,
- 0xa00,
- 0,
- {0xe5,0x34,0x70,0x19}
-},
-{ 10,
- 0xa04,
- 0,
- {0x74,0x01,0x25,0x35,0x54,0x0f,0xf5,0x35,0x85,0x35}
-},
-{ 12,
- 0xa0e,
- 0,
- {0x75,0x75,0x76,0x00,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0}
-},
-{ 3,
- 0xa1a,
- 0,
- {0x05,0xd0,0x04}
-},
-{ 5,
- 0xa1d,
- 0,
- {0xe5,0x33,0xb4,0x01,0x1d}
-},
-{ 4,
- 0xa22,
- 0,
- {0xe5,0x34,0x70,0x19}
-},
-{ 10,
- 0xa26,
- 0,
- {0xe5,0x35,0x24,0xff,0x54,0x0f,0xf5,0x35,0x85,0x35}
-},
-{ 12,
- 0xa30,
- 0,
- {0x75,0x75,0x76,0x00,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0}
-},
-{ 3,
- 0xa3c,
- 0,
- {0x05,0xd0,0x04}
-},
-{ 14,
- 0xa3f,
- 0,
- {0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0,0x04,0x90,0x7f,0x96}
-},
-{ 14,
- 0xa4d,
- 0,
- {0xe0,0xfa,0x90,0x7f,0x96,0x74,0x7f,0x5a,0xf0,0x90,0x7f,0x97,0x74,0x08}
-},
-{ 10,
- 0xa5b,
- 0,
- {0xf0,0xc3,0xec,0x94,0x00,0xed,0x94,0x02,0x40,0x08}
-},
-{ 8,
- 0xa65,
- 0,
- {0x90,0x7f,0x96,0xe0,0xfa,0x20,0xe6,0x08}
-},
-{ 8,
- 0xa6d,
- 0,
- {0xc3,0xe4,0x9c,0x74,0x08,0x9d,0x50,0x13}
-},
-{ 14,
- 0xa75,
- 0,
- {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x40,0x65,0x02,0xf0,0x7c}
-},
-{ 5,
- 0xa83,
- 0,
- {0x00,0x7d,0x00,0x80,0x05}
-},
-{ 5,
- 0xa88,
- 0,
- {0x0c,0xbc,0x00,0x01,0x0d}
-},
-{ 5,
- 0xa8d,
- 0,
- {0xe5,0x38,0xb4,0x01,0x0e}
-},
-{ 13,
- 0xa92,
- 0,
- {0xc0,0x04,0xc0,0x05,0x12,0x04,0xf7,0xd0,0x05,0xd0,0x04,0x75,0x38}
-},
-{ 1,
- 0xa9f,
- 0,
- {0x00}
-},
-{ 7,
- 0xaa0,
- 0,
- {0xe5,0x31,0x70,0x03,0x02,0x09,0x2a}
-},
-{ 10,
- 0xaa7,
- 0,
- {0x90,0x7f,0xc9,0xe0,0xfa,0x70,0x03,0x02,0x0c,0x2d}
-},
-{ 14,
- 0xab1,
- 0,
- {0x90,0x7f,0x96,0xe0,0xfa,0x90,0x7f,0x96,0x74,0x80,0x65,0x02,0xf0,0x90}
-},
-{ 9,
- 0xabf,
- 0,
- {0x7d,0xc0,0xe0,0xfa,0xba,0x2c,0x02,0x80,0x03}
-},
-{ 3,
- 0xac8,
- 0,
- {0x02,0x0b,0x36}
-},
-{ 5,
- 0xacb,
- 0,
- {0x75,0x32,0x00,0x7b,0x00}
-},
-{ 3,
- 0xad0,
- 0,
- {0xbb,0x64,0x00}
-},
-{ 2,
- 0xad3,
- 0,
- {0x50,0x1c}
-},
-{ 14,
- 0xad5,
- 0,
- {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0}
-},
-{ 13,
- 0xae3,
- 0,
- {0x04,0xd0,0x03,0xd0,0x02,0x90,0x88,0x0f,0xe0,0xf5,0x47,0x0b,0x80}
-},
-{ 1,
- 0xaf0,
- 0,
- {0xdf}
-},
-{ 13,
- 0xaf1,
- 0,
- {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x07,0x1e,0x12,0x03,0xe1,0x12}
-},
-{ 12,
- 0xafe,
- 0,
- {0x04,0xf7,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x75,0x6e,0x00,0x75}
-},
-{ 13,
- 0xb0a,
- 0,
- {0x6f,0x01,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x11,0x44,0xd0,0x05}
-},
-{ 9,
- 0xb17,
- 0,
- {0xd0,0x04,0xd0,0x02,0x75,0x70,0x4d,0x75,0x71}
-},
-{ 11,
- 0xb20,
- 0,
- {0x0c,0x75,0x72,0x02,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12}
-},
-{ 11,
- 0xb2b,
- 0,
- {0x11,0x75,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x02,0x0c,0x2d}
-},
-{ 3,
- 0xb36,
- 0,
- {0xba,0x2a,0x3b}
-},
-{ 13,
- 0xb39,
- 0,
- {0x90,0x7f,0x98,0x74,0x20,0xf0,0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12}
-},
-{ 14,
- 0xb46,
- 0,
- {0x01,0xdd,0xd0,0x05,0xd0,0x04,0xd0,0x02,0x90,0x7f,0x98,0x74,0x28,0xf0}
-},
-{ 2,
- 0xb54,
- 0,
- {0x7b,0x00}
-},
-{ 3,
- 0xb56,
- 0,
- {0xbb,0x0a,0x00}
-},
-{ 5,
- 0xb59,
- 0,
- {0x40,0x03,0x02,0x0c,0x2d}
-},
-{ 14,
- 0xb5e,
- 0,
- {0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0x12,0x01,0xdd,0xd0,0x05,0xd0}
-},
-{ 8,
- 0xb6c,
- 0,
- {0x04,0xd0,0x03,0xd0,0x02,0x0b,0x80,0xe2}
-},
-{ 3,
- 0xb74,
- 0,
- {0xba,0x2b,0x1a}
-},
-{ 8,
- 0xb77,
- 0,
- {0x90,0x7f,0xc9,0xe0,0xfb,0xbb,0x40,0x12}
-},
-{ 14,
- 0xb7f,
- 0,
- {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x12,0x05,0xd0,0x05,0xd0,0x04,0xd0}
-},
-{ 4,
- 0xb8d,
- 0,
- {0x02,0x02,0x0c,0x2d}
-},
-{ 3,
- 0xb91,
- 0,
- {0xba,0x10,0x1f}
-},
-{ 14,
- 0xb94,
- 0,
- {0x90,0x7f,0x96,0xe0,0xfb,0x90,0x7f,0x96,0x74,0x80,0x65,0x03,0xf0,0xc0}
-},
-{ 14,
- 0xba2,
- 0,
- {0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x3d,0xd0,0x05,0xd0,0x04,0xd0,0x02}
-},
-{ 3,
- 0xbb0,
- 0,
- {0x02,0x0c,0x2d}
-},
-{ 3,
- 0xbb3,
- 0,
- {0xba,0x11,0x12}
-},
-{ 14,
- 0xbb6,
- 0,
- {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x6a,0xd0,0x05,0xd0,0x04,0xd0}
-},
-{ 4,
- 0xbc4,
- 0,
- {0x02,0x02,0x0c,0x2d}
-},
-{ 3,
- 0xbc8,
- 0,
- {0xba,0x12,0x12}
-},
-{ 14,
- 0xbcb,
- 0,
- {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x10,0x8f,0xd0,0x05,0xd0,0x04,0xd0}
-},
-{ 4,
- 0xbd9,
- 0,
- {0x02,0x02,0x0c,0x2d}
-},
-{ 3,
- 0xbdd,
- 0,
- {0xba,0x13,0x0b}
-},
-{ 11,
- 0xbe0,
- 0,
- {0x90,0x7d,0xc1,0xe0,0xfb,0x90,0x88,0x00,0xf0,0x80,0x42}
-},
-{ 3,
- 0xbeb,
- 0,
- {0xba,0x14,0x11}
-},
-{ 14,
- 0xbee,
- 0,
- {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x11,0xdd,0xd0,0x05,0xd0,0x04,0xd0}
-},
-{ 3,
- 0xbfc,
- 0,
- {0x02,0x80,0x2e}
-},
-{ 3,
- 0xbff,
- 0,
- {0xba,0x15,0x1d}
-},
-{ 12,
- 0xc02,
- 0,
- {0x90,0x7d,0xc1,0xe0,0xf5,0x75,0x90,0x7d,0xc2,0xe0,0xf5,0x76}
-},
-{ 14,
- 0xc0e,
- 0,
- {0xc0,0x02,0xc0,0x04,0xc0,0x05,0x12,0x13,0xfe,0xd0,0x05,0xd0,0x04,0xd0}
-},
-{ 3,
- 0xc1c,
- 0,
- {0x02,0x80,0x0e}
-},
-{ 3,
- 0xc1f,
- 0,
- {0xba,0x16,0x0b}
-},
-{ 11,
- 0xc22,
- 0,
- {0xc0,0x04,0xc0,0x05,0x12,0x13,0xa3,0xd0,0x05,0xd0,0x04}
-},
-{ 11,
- 0xc2d,
- 0,
- {0x90,0x7f,0xc9,0xe4,0xf0,0x75,0x31,0x00,0x02,0x09,0x2a}
-},
-{ 1,
- 0xc38,
- 0,
- {0x22}
-},
-{ 7,
- 0xc39,
- 0,
- {0x53,0x55,0x50,0x45,0x4e,0x44,0x00}
-},
-{ 7,
- 0xc40,
- 0,
- {0x52,0x45,0x53,0x55,0x4d,0x45,0x00}
-},
-{ 6,
- 0xc47,
- 0,
- {0x20,0x56,0x6f,0x6c,0x20,0x00}
-},
-{ 13,
- 0xc4d,
- 0,
- {0x44,0x41,0x42,0x55,0x53,0x42,0x20,0x76,0x31,0x2e,0x30,0x30,0x00}
-},
-{ 14,
- 0xc5a,
- 0,
- {0xc0,0xe0,0xc0,0xf0,0xc0,0x82,0xc0,0x83,0xc0,0x02,0xc0,0x03,0xc0,0x04}
-},
-{ 14,
- 0xc68,
- 0,
- {0xc0,0x05,0xc0,0x06,0xc0,0x07,0xc0,0x00,0xc0,0x01,0xc0,0xd0,0x75,0xd0}
-},
-{ 13,
- 0xc76,
- 0,
- {0x00,0xc0,0x86,0x75,0x86,0x00,0xe5,0x91,0xc2,0xe4,0xf5,0x91,0x90}
-},
-{ 14,
- 0xc83,
- 0,
- {0x7f,0xab,0x74,0x01,0xf0,0x90,0x7f,0xe8,0xe0,0xfa,0x90,0x7f,0xe9,0xe0}
-},
-{ 6,
- 0xc91,
- 0,
- {0xfb,0xbb,0x00,0x02,0x80,0x03}
-},
-{ 3,
- 0xc97,
- 0,
- {0x02,0x0d,0x38}
-},
-{ 3,
- 0xc9a,
- 0,
- {0xba,0x80,0x14}
-},
-{ 14,
- 0xc9d,
- 0,
- {0x90,0x7f,0x00,0x74,0x01,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5}
-},
-{ 6,
- 0xcab,
- 0,
- {0x74,0x02,0xf0,0x02,0x0e,0xcd}
-},
-{ 5,
- 0xcb1,
- 0,
- {0xba,0x82,0x02,0x80,0x03}
-},
-{ 3,
- 0xcb6,
- 0,
- {0x02,0x0d,0x1d}
-},
-{ 8,
- 0xcb9,
- 0,
- {0x90,0x7f,0xec,0xe0,0xfc,0xbc,0x01,0x00}
-},
-{ 2,
- 0xcc1,
- 0,
- {0x40,0x21}
-},
-{ 6,
- 0xcc3,
- 0,
- {0xc3,0x74,0x07,0x9c,0x40,0x1b}
-},
-{ 14,
- 0xcc9,
- 0,
- {0xec,0x24,0xff,0x25,0xe0,0xfd,0x24,0xc6,0xf5,0x82,0xe4,0x34,0x7f,0xf5}
-},
-{ 13,
- 0xcd7,
- 0,
- {0x83,0xe0,0xfd,0x53,0x05,0x01,0x90,0x7f,0x00,0xed,0xf0,0x80,0x2b}
-},
-{ 3,
- 0xce4,
- 0,
- {0xbc,0x81,0x00}
-},
-{ 2,
- 0xce7,
- 0,
- {0x40,0x21}
-},
-{ 6,
- 0xce9,
- 0,
- {0xc3,0x74,0x87,0x9c,0x40,0x1b}
-},
-{ 14,
- 0xcef,
- 0,
- {0xec,0x24,0x7f,0x25,0xe0,0xfc,0x24,0xb6,0xf5,0x82,0xe4,0x34,0x7f,0xf5}
-},
-{ 13,
- 0xcfd,
- 0,
- {0x83,0xe0,0xfc,0x53,0x04,0x01,0x90,0x7f,0x00,0xec,0xf0,0x80,0x05}
-},
-{ 5,
- 0xd0a,
- 0,
- {0x90,0x7f,0x00,0xe4,0xf0}
-},
-{ 14,
- 0xd0f,
- 0,
- {0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5,0x74,0x02,0xf0,0x02,0x0e,0xcd}
-},
-{ 5,
- 0xd1d,
- 0,
- {0xba,0x81,0x02,0x80,0x03}
-},
-{ 3,
- 0xd22,
- 0,
- {0x02,0x0e,0xc5}
-},
-{ 14,
- 0xd25,
- 0,
- {0x90,0x7f,0x00,0xe4,0xf0,0x90,0x7f,0x01,0xe4,0xf0,0x90,0x7f,0xb5,0x74}
-},
-{ 5,
- 0xd33,
- 0,
- {0x02,0xf0,0x02,0x0e,0xcd}
-},
-{ 3,
- 0xd38,
- 0,
- {0xbb,0x01,0x2d}
-},
-{ 6,
- 0xd3b,
- 0,
- {0xba,0x00,0x03,0x02,0x0e,0xcd}
-},
-{ 3,
- 0xd41,
- 0,
- {0xba,0x02,0x11}
-},
-{ 13,
- 0xd44,
- 0,
- {0x75,0x59,0x00,0xc0,0x02,0xc0,0x03,0x12,0x0e,0xf0,0xd0,0x03,0xd0}
-},
-{ 4,
- 0xd51,
- 0,
- {0x02,0x02,0x0e,0xcd}
-},
-{ 5,
- 0xd55,
- 0,
- {0xba,0x21,0x02,0x80,0x03}
-},
-{ 3,
- 0xd5a,
- 0,
- {0x02,0x0e,0xcd}
-},
-{ 11,
- 0xd5d,
- 0,
- {0x75,0x37,0x01,0x90,0x7f,0xc5,0xe4,0xf0,0x02,0x0e,0xcd}
-},
-{ 3,
- 0xd68,
- 0,
- {0xbb,0x03,0x1f}
-},
-{ 6,
- 0xd6b,
- 0,
- {0xba,0x00,0x03,0x02,0x0e,0xcd}
-},
-{ 5,
- 0xd71,
- 0,
- {0xba,0x02,0x02,0x80,0x03}
-},
-{ 3,
- 0xd76,
- 0,
- {0x02,0x0e,0xcd}
-},
-{ 13,
- 0xd79,
- 0,
- {0x75,0x59,0x01,0xc0,0x02,0xc0,0x03,0x12,0x0e,0xf0,0xd0,0x03,0xd0}
-},
-{ 4,
- 0xd86,
- 0,
- {0x02,0x02,0x0e,0xcd}
-},
-{ 3,
- 0xd8a,
- 0,
- {0xbb,0x06,0x54}
-},
-{ 5,
- 0xd8d,
- 0,
- {0xba,0x80,0x02,0x80,0x03}
-},
-{ 3,
- 0xd92,
- 0,
- {0x02,0x0e,0xc5}
-},
-{ 8,
- 0xd95,
- 0,
- {0x90,0x7f,0xeb,0xe0,0xfc,0xbc,0x01,0x15}
-},
-{ 12,
- 0xd9d,
- 0,
- {0x7c,0xfb,0x7d,0x0f,0x8d,0x06,0x7f,0x00,0x90,0x7f,0xd4,0xee}
-},
-{ 9,
- 0xda9,
- 0,
- {0xf0,0x90,0x7f,0xd5,0xec,0xf0,0x02,0x0e,0xcd}
-},
-{ 10,
- 0xdb2,
- 0,
- {0x90,0x7f,0xeb,0xe0,0xfc,0xbc,0x02,0x02,0x80,0x03}
-},
-{ 3,
- 0xdbc,
- 0,
- {0x02,0x0e,0xc5}
-},
-{ 10,
- 0xdbf,
- 0,
- {0x90,0x7f,0xea,0xe0,0xfc,0xbc,0x00,0x02,0x80,0x03}
-},
-{ 3,
- 0xdc9,
- 0,
- {0x02,0x0e,0xc5}
-},
-{ 12,
- 0xdcc,
- 0,
- {0x7c,0x3b,0x7d,0x0f,0x8d,0x06,0x7f,0x00,0x90,0x7f,0xd4,0xee}
-},
-{ 9,
- 0xdd8,
- 0,
- {0xf0,0x90,0x7f,0xd5,0xec,0xf0,0x02,0x0e,0xcd}
-},
-{ 6,
- 0xde1,
- 0,
- {0xbb,0x07,0x03,0x02,0x0e,0xc5}
-},
-{ 3,
- 0xde7,
- 0,
- {0xbb,0x08,0x10}
-},
-{ 13,
- 0xdea,
- 0,
- {0xac,0x48,0x90,0x7f,0x00,0xec,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0}
-},
-{ 3,
- 0xdf7,
- 0,
- {0x02,0x0e,0xcd}
-},
-{ 3,
- 0xdfa,
- 0,
- {0xbb,0x09,0x31}
-},
-{ 5,
- 0xdfd,
- 0,
- {0xba,0x00,0x02,0x80,0x03}
-},
-{ 3,
- 0xe02,
- 0,
- {0x02,0x0e,0xc5}
-},
-{ 14,
- 0xe05,
- 0,
- {0x90,0x7f,0xea,0xe0,0xfc,0xc3,0x74,0x01,0x9c,0x50,0x03,0x02,0x0e,0xc5}
-},
-{ 8,
- 0xe13,
- 0,
- {0x90,0x7f,0xea,0xe0,0xfc,0xbc,0x00,0x0a}
-},
-{ 10,
- 0xe1b,
- 0,
- {0x90,0x17,0x21,0xe4,0xf0,0x90,0x17,0x22,0xe4,0xf0}
-},
-{ 9,
- 0xe25,
- 0,
- {0x90,0x7f,0xea,0xe0,0xf5,0x48,0x02,0x0e,0xcd}
-},
-{ 3,
- 0xe2e,
- 0,
- {0xbb,0x0a,0x27}
-},
-{ 5,
- 0xe31,
- 0,
- {0xba,0x81,0x02,0x80,0x03}
-},
-{ 3,
- 0xe36,
- 0,
- {0x02,0x0e,0xc5}
-},
-{ 14,
- 0xe39,
- 0,
- {0x90,0x7f,0xec,0xe0,0xfa,0x24,0x20,0xfa,0xe4,0x34,0x17,0xfc,0x8a,0x82}
-},
-{ 14,
- 0xe47,
- 0,
- {0x8c,0x83,0xe0,0xfa,0x90,0x7f,0x00,0xf0,0x90,0x7f,0xb5,0x74,0x01,0xf0}
-},
-{ 3,
- 0xe55,
- 0,
- {0x02,0x0e,0xcd}
-},
-{ 5,
- 0xe58,
- 0,
- {0xbb,0x0b,0x02,0x80,0x03}
-},
-{ 3,
- 0xe5d,
- 0,
- {0x02,0x0e,0xa9}
-},
-{ 13,
- 0xe60,
- 0,
- {0x90,0x17,0x20,0xe4,0xf0,0x90,0x7f,0xec,0xe0,0xfa,0xba,0x01,0x1a}
-},
-{ 8,
- 0xe6d,
- 0,
- {0x90,0x7f,0xed,0xe0,0xfa,0xba,0x00,0x12}
-},
-{ 14,
- 0xe75,
- 0,
- {0x90,0x7f,0xea,0xe0,0xfa,0x90,0x17,0x21,0xf0,0xc0,0x03,0x12,0x04,0xe2}
-},
-{ 4,
- 0xe83,
- 0,
- {0xd0,0x03,0x80,0x46}
-},
-{ 8,
- 0xe87,
- 0,
- {0x90,0x7f,0xec,0xe0,0xfa,0xba,0x02,0x3e}
-},
-{ 8,
- 0xe8f,
- 0,
- {0x90,0x7f,0xed,0xe0,0xfa,0xba,0x00,0x36}
-},
-{ 13,
- 0xe97,
- 0,
- {0xc0,0x03,0x12,0x04,0xef,0xd0,0x03,0x90,0x7f,0xea,0xe0,0xfa,0x90}
-},
-{ 5,
- 0xea4,
- 0,
- {0x17,0x22,0xf0,0x80,0x24}
-},
-{ 5,
- 0xea9,
- 0,
- {0xbb,0x12,0x02,0x80,0x17}
-},
-{ 5,
- 0xeae,
- 0,
- {0xbb,0x81,0x02,0x80,0x0d}
-},
-{ 5,
- 0xeb3,
- 0,
- {0xbb,0x83,0x02,0x80,0x08}
-},
-{ 5,
- 0xeb8,
- 0,
- {0xbb,0x82,0x02,0x80,0x03}
-},
-{ 3,
- 0xebd,
- 0,
- {0xbb,0x84,0x05}
-},
-{ 5,
- 0xec0,
- 0,
- {0x12,0x06,0x4e,0x80,0x08}
-},
-{ 8,
- 0xec5,
- 0,
- {0x90,0x7f,0xb4,0x74,0x03,0xf0,0x80,0x06}
-},
-{ 6,
- 0xecd,
- 0,
- {0x90,0x7f,0xb4,0x74,0x02,0xf0}
-},
-{ 2,
- 0xed3,
- 0,
- {0xd0,0x86}
-},
-{ 14,
- 0xed5,
- 0,
- {0xd0,0xd0,0xd0,0x01,0xd0,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04}
-},
-{ 13,
- 0xee3,
- 0,
- {0xd0,0x03,0xd0,0x02,0xd0,0x83,0xd0,0x82,0xd0,0xf0,0xd0,0xe0,0x32}
-},
-{ 11,
- 0xef0,
- 0,
- {0x90,0x7f,0xec,0xe0,0xf5,0x5a,0xc3,0x94,0x01,0x40,0x1d}
-},
-{ 7,
- 0xefb,
- 0,
- {0xc3,0x74,0x07,0x95,0x5a,0x40,0x16}
-},
-{ 13,
- 0xf02,
- 0,
- {0xe5,0x5a,0x24,0xff,0x25,0xe0,0xfa,0x24,0xc6,0xf5,0x82,0xe4,0x34}
-},
-{ 9,
- 0xf0f,
- 0,
- {0x7f,0xf5,0x83,0xaa,0x59,0xea,0xf0,0x80,0x22}
-},
-{ 7,
- 0xf18,
- 0,
- {0xc3,0xe5,0x5a,0x94,0x81,0x40,0x1b}
-},
-{ 7,
- 0xf1f,
- 0,
- {0xc3,0x74,0x87,0x95,0x5a,0x40,0x14}
-},
-{ 13,
- 0xf26,
- 0,
- {0xe5,0x5a,0x24,0xff,0x25,0xe0,0xfa,0x24,0xb6,0xf5,0x82,0xe4,0x34}
-},
-{ 7,
- 0xf33,
- 0,
- {0x7f,0xf5,0x83,0xaa,0x59,0xea,0xf0}
-},
-{ 1,
- 0xf3a,
- 0,
- {0x22}
-},
-{ 14,
- 0xf3b,
- 0,
- {0x09,0x02,0xba,0x00,0x03,0x01,0x00,0x40,0x00,0x09,0x04,0x00,0x00,0x00}
-},
-{ 14,
- 0xf49,
- 0,
- {0x01,0x01,0x00,0x00,0x09,0x24,0x01,0x00,0x01,0x3d,0x00,0x01,0x01,0x0c}
-},
-{ 14,
- 0xf57,
- 0,
- {0x24,0x02,0x01,0x10,0x07,0x00,0x02,0x03,0x00,0x00,0x00,0x0d,0x24,0x06}
-},
-{ 14,
- 0xf65,
- 0,
- {0x03,0x01,0x02,0x15,0x00,0x03,0x00,0x03,0x00,0x00,0x09,0x24,0x03,0x02}
-},
-{ 14,
- 0xf73,
- 0,
- {0x01,0x01,0x00,0x01,0x00,0x09,0x24,0x03,0x04,0x02,0x03,0x00,0x03,0x00}
-},
-{ 14,
- 0xf81,
- 0,
- {0x09,0x24,0x03,0x05,0x03,0x06,0x00,0x01,0x00,0x09,0x04,0x01,0x00,0x00}
-},
-{ 14,
- 0xf8f,
- 0,
- {0x01,0x02,0x00,0x00,0x09,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00,0x07}
-},
-{ 14,
- 0xf9d,
- 0,
- {0x24,0x01,0x02,0x01,0x01,0x00,0x0b,0x24,0x02,0x01,0x02,0x02,0x10,0x01}
-},
-{ 14,
- 0xfab,
- 0,
- {0x80,0xbb,0x00,0x09,0x05,0x88,0x05,0x00,0x01,0x01,0x00,0x00,0x07,0x25}
-},
-{ 14,
- 0xfb9,
- 0,
- {0x01,0x00,0x00,0x00,0x00,0x09,0x04,0x02,0x00,0x02,0x00,0x00,0x00,0x00}
-},
-{ 14,
- 0xfc7,
- 0,
- {0x07,0x05,0x82,0x02,0x40,0x00,0x00,0x07,0x05,0x02,0x02,0x40,0x00,0x00}
-},
-{ 14,
- 0xfd5,
- 0,
- {0x09,0x04,0x02,0x01,0x03,0x00,0x00,0x00,0x00,0x07,0x05,0x82,0x02,0x40}
-},
-{ 14,
- 0xfe3,
- 0,
- {0x00,0x00,0x07,0x05,0x02,0x02,0x40,0x00,0x00,0x09,0x05,0x89,0x05,0xa0}
-},
-{ 10,
- 0xff1,
- 0,
- {0x01,0x01,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00}
-},
-{ 14,
- 0xffb,
- 0,
- {0x12,0x01,0x00,0x01,0x00,0x00,0x00,0x40,0x47,0x05,0x99,0x99,0x00,0x01}
-},
-{ 14,
- 0x1009,
- 0,
- {0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x02,0xba}
-},
-{ 4,
- 0x1017,
- 0,
- {0x00,0x03,0x01,0x00}
-},
-{ 2,
- 0x101b,
- 0,
- {0x7a,0x00}
-},
-{ 3,
- 0x101d,
- 0,
- {0xba,0x05,0x00}
-},
-{ 2,
- 0x1020,
- 0,
- {0x50,0x17}
-},
-{ 8,
- 0x1022,
- 0,
- {0x90,0x7f,0xa5,0xe0,0xfb,0x30,0xe0,0x05}
-},
-{ 5,
- 0x102a,
- 0,
- {0x90,0x00,0x01,0x80,0x0d}
-},
-{ 10,
- 0x102f,
- 0,
- {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xe4}
-},
-{ 3,
- 0x1039,
- 0,
- {0x90,0x00,0x01}
-},
-{ 1,
- 0x103c,
- 0,
- {0x22}
-},
-{ 14,
- 0x103d,
- 0,
- {0x90,0x7d,0xc1,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x7c,0x00,0x7d}
-},
-{ 4,
- 0x104b,
- 0,
- {0x7e,0xeb,0x60,0x12}
-},
-{ 14,
- 0x104f,
- 0,
- {0x89,0x82,0x8a,0x83,0xe0,0xa3,0xa9,0x82,0xaa,0x83,0x8c,0x82,0x8d,0x83}
-},
-{ 4,
- 0x105d,
- 0,
- {0xf0,0x0c,0xdb,0xee}
-},
-{ 8,
- 0x1061,
- 0,
- {0x90,0x7d,0xc3,0xe0,0x90,0x7f,0xb9,0xf0}
-},
-{ 1,
- 0x1069,
- 0,
- {0x22}
-},
-{ 14,
- 0x106a,
- 0,
- {0x90,0x7d,0xc1,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x7c,0xc4,0x7d}
-},
-{ 4,
- 0x1078,
- 0,
- {0x7d,0xeb,0x60,0xe5}
-},
-{ 14,
- 0x107c,
- 0,
- {0x8c,0x82,0x8d,0x83,0xe0,0x0c,0x89,0x82,0x8a,0x83,0xf0,0xa3,0xa9,0x82}
-},
-{ 4,
- 0x108a,
- 0,
- {0xaa,0x83,0xdb,0xee}
-},
-{ 1,
- 0x108e,
- 0,
- {0x22}
-},
-{ 14,
- 0x108f,
- 0,
- {0x90,0x7f,0xa5,0x74,0x80,0xf0,0x05,0x86,0x90,0x7d,0xc1,0xe0,0x05,0x86}
-},
-{ 14,
- 0x109d,
- 0,
- {0xa3,0xf0,0x12,0x10,0x1b,0x90,0x7f,0xa6,0x05,0x86,0xa3,0xa3,0xe0,0xf9}
-},
-{ 5,
- 0x10ab,
- 0,
- {0x60,0x16,0xa3,0x05,0x86}
-},
-{ 13,
- 0x10b0,
- 0,
- {0x90,0x7f,0xa6,0x05,0x86,0xe0,0xa3,0x05,0x86,0xf0,0xc0,0x01,0x12}
-},
-{ 6,
- 0x10bd,
- 0,
- {0x10,0x1b,0xd0,0x01,0xd9,0xed}
-},
-{ 6,
- 0x10c3,
- 0,
- {0x90,0x7f,0xa5,0x74,0x40,0xf0}
-},
-{ 1,
- 0x10c9,
- 0,
- {0x22}
-},
-{ 8,
- 0x10ca,
- 0,
- {0x90,0x88,0x02,0x74,0x01,0xf0,0x7a,0x00}
-},
-{ 3,
- 0x10d2,
- 0,
- {0xba,0xff,0x00}
-},
-{ 2,
- 0x10d5,
- 0,
- {0x50,0x0a}
-},
-{ 10,
- 0x10d7,
- 0,
- {0xc0,0x02,0x12,0x01,0xdd,0xd0,0x02,0x0a,0x80,0xf1}
-},
-{ 1,
- 0x10e1,
- 0,
- {0x22}
-},
-{ 5,
- 0x10e2,
- 0,
- {0xe5,0x6b,0xb4,0xc0,0x08}
-},
-{ 8,
- 0x10e7,
- 0,
- {0x90,0x88,0x03,0xe5,0x6c,0xf0,0x80,0x06}
-},
-{ 6,
- 0x10ef,
- 0,
- {0x90,0x88,0x02,0xe5,0x6c,0xf0}
-},
-{ 4,
- 0x10f5,
- 0,
- {0x7a,0x00,0x7b,0x00}
-},
-{ 11,
- 0x10f9,
- 0,
- {0xc3,0xea,0x94,0x32,0xeb,0x64,0x80,0x94,0x80,0x50,0x07}
-},
-{ 5,
- 0x1104,
- 0,
- {0x0a,0xba,0x00,0x01,0x0b}
-},
-{ 2,
- 0x1109,
- 0,
- {0x80,0xee}
-},
-{ 1,
- 0x110b,
- 0,
- {0x22}
-},
-{ 10,
- 0x110c,
- 0,
- {0x90,0x88,0x03,0xe5,0x6d,0xf0,0x05,0x39,0x7a,0x00}
-},
-{ 3,
- 0x1116,
- 0,
- {0xba,0x28,0x00}
-},
-{ 2,
- 0x1119,
- 0,
- {0x50,0x03}
-},
-{ 3,
- 0x111b,
- 0,
- {0x0a,0x80,0xf8}
-},
-{ 5,
- 0x111e,
- 0,
- {0xe5,0x39,0xb4,0x10,0x08}
-},
-{ 8,
- 0x1123,
- 0,
- {0x90,0x88,0x02,0x74,0xc0,0xf0,0x80,0x0e}
-},
-{ 5,
- 0x112b,
- 0,
- {0xe5,0x39,0xb4,0x20,0x09}
-},
-{ 9,
- 0x1130,
- 0,
- {0x90,0x88,0x02,0x74,0x80,0xf0,0x75,0x39,0x00}
-},
-{ 2,
- 0x1139,
- 0,
- {0x7a,0x00}
-},
-{ 3,
- 0x113b,
- 0,
- {0xba,0x28,0x00}
-},
-{ 2,
- 0x113e,
- 0,
- {0x50,0x03}
-},
-{ 3,
- 0x1140,
- 0,
- {0x0a,0x80,0xf8}
-},
-{ 1,
- 0x1143,
- 0,
- {0x22}
-},
-{ 4,
- 0x1144,
- 0,
- {0xe5,0x6f,0x60,0x02}
-},
-{ 2,
- 0x1148,
- 0,
- {0x80,0x07}
-},
-{ 7,
- 0x114a,
- 0,
- {0x7a,0x00,0x75,0x39,0x00,0x80,0x05}
-},
-{ 5,
- 0x1151,
- 0,
- {0x7a,0x40,0x75,0x39,0x10}
-},
-{ 9,
- 0x1156,
- 0,
- {0xe5,0x6e,0x2a,0xfa,0xe5,0x6e,0x25,0x39,0xf5}
-},
-{ 10,
- 0x115f,
- 0,
- {0x39,0x90,0x88,0x02,0x74,0x80,0x2a,0xf0,0x7a,0x00}
-},
-{ 8,
- 0x1169,
- 0,
- {0xc3,0xea,0x64,0x80,0x94,0xa8,0x50,0x03}
-},
-{ 3,
- 0x1171,
- 0,
- {0x0a,0x80,0xf5}
-},
-{ 1,
- 0x1174,
- 0,
- {0x22}
-},
-{ 6,
- 0x1175,
- 0,
- {0xaa,0x70,0xab,0x71,0xac,0x72}
-},
-{ 12,
- 0x117b,
- 0,
- {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x12,0x14,0xee,0xfd,0x60,0x18}
-},
-{ 13,
- 0x1187,
- 0,
- {0x8d,0x6d,0xc0,0x02,0xc0,0x03,0xc0,0x04,0x12,0x11,0x0c,0xd0,0x04}
-},
-{ 9,
- 0x1194,
- 0,
- {0xd0,0x03,0xd0,0x02,0x0a,0xba,0x00,0x01,0x0b}
-},
-{ 2,
- 0x119d,
- 0,
- {0x80,0xdc}
-},
-{ 1,
- 0x119f,
- 0,
- {0x22}
-},
-{ 13,
- 0x11a0,
- 0,
- {0xe5,0x73,0xc4,0x54,0x0f,0xfa,0x53,0x02,0x0f,0xc3,0x74,0x09,0x9a}
-},
-{ 2,
- 0x11ad,
- 0,
- {0x50,0x06}
-},
-{ 6,
- 0x11af,
- 0,
- {0x74,0x37,0x2a,0xfb,0x80,0x04}
-},
-{ 4,
- 0x11b5,
- 0,
- {0x74,0x30,0x2a,0xfb}
-},
-{ 12,
- 0x11b9,
- 0,
- {0x8b,0x6d,0xc0,0x03,0x12,0x11,0x0c,0xd0,0x03,0xaa,0x73,0x53}
-},
-{ 8,
- 0x11c5,
- 0,
- {0x02,0x0f,0xc3,0x74,0x09,0x9a,0x50,0x06}
-},
-{ 6,
- 0x11cd,
- 0,
- {0x74,0x37,0x2a,0xfb,0x80,0x04}
-},
-{ 4,
- 0x11d3,
- 0,
- {0x74,0x30,0x2a,0xfb}
-},
-{ 5,
- 0x11d7,
- 0,
- {0x8b,0x6d,0x12,0x11,0x0c}
-},
-{ 1,
- 0x11dc,
- 0,
- {0x22}
-},
-{ 7,
- 0x11dd,
- 0,
- {0x90,0x7d,0xc3,0xe0,0xfa,0x60,0x0f}
-},
-{ 12,
- 0x11e4,
- 0,
- {0x90,0x7d,0xc1,0xe0,0xf5,0x6e,0x90,0x7d,0xc2,0xe0,0xf5,0x6f}
-},
-{ 3,
- 0x11f0,
- 0,
- {0x12,0x11,0x44}
-},
-{ 12,
- 0x11f3,
- 0,
- {0x90,0x7d,0xff,0xe4,0xf0,0x75,0x70,0xc4,0x75,0x71,0x7d,0x75}
-},
-{ 5,
- 0x11ff,
- 0,
- {0x72,0x01,0x12,0x11,0x75}
-},
-{ 1,
- 0x1204,
- 0,
- {0x22}
-},
-{ 2,
- 0x1205,
- 0,
- {0x7a,0x04}
-},
-{ 3,
- 0x1207,
- 0,
- {0xba,0x40,0x00}
-},
-{ 2,
- 0x120a,
- 0,
- {0x50,0x36}
-},
-{ 14,
- 0x120c,
- 0,
- {0xea,0x24,0xc0,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfb,0x7c,0x00}
-},
-{ 3,
- 0x121a,
- 0,
- {0xbc,0x08,0x00}
-},
-{ 2,
- 0x121d,
- 0,
- {0x50,0x20}
-},
-{ 6,
- 0x121f,
- 0,
- {0x8b,0x05,0xed,0x30,0xe7,0x0b}
-},
-{ 11,
- 0x1225,
- 0,
- {0x90,0x7f,0x96,0x74,0x42,0xf0,0x74,0xc3,0xf0,0x80,0x08}
-},
-{ 8,
- 0x1230,
- 0,
- {0x90,0x7f,0x96,0xe4,0xf0,0x74,0x81,0xf0}
-},
-{ 7,
- 0x1238,
- 0,
- {0xeb,0x25,0xe0,0xfb,0x0c,0x80,0xdb}
-},
-{ 3,
- 0x123f,
- 0,
- {0x0a,0x80,0xc5}
-},
-{ 1,
- 0x1242,
- 0,
- {0x22}
-},
-{ 4,
- 0x1243,
- 0,
- {0x7a,0x00,0x7b,0xef}
-},
-{ 3,
- 0x1247,
- 0,
- {0xba,0x10,0x00}
-},
-{ 2,
- 0x124a,
- 0,
- {0x50,0x20}
-},
-{ 14,
- 0x124c,
- 0,
- {0x74,0x11,0x2b,0xfb,0x24,0x00,0xfc,0xe4,0x34,0x18,0xfd,0x8c,0x82,0x8d}
-},
-{ 14,
- 0x125a,
- 0,
- {0x83,0xe4,0xf0,0xea,0x24,0x00,0xf5,0x82,0xe4,0x34,0x19,0xf5,0x83,0xe4}
-},
-{ 4,
- 0x1268,
- 0,
- {0xf0,0x0a,0x80,0xdb}
-},
-{ 1,
- 0x126c,
- 0,
- {0x22}
-},
-{ 14,
- 0x126d,
- 0,
- {0x74,0xf8,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0}
-},
-{ 14,
- 0x127b,
- 0,
- {0x74,0xf9,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0}
-},
-{ 14,
- 0x1289,
- 0,
- {0x74,0xfa,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0}
-},
-{ 14,
- 0x1297,
- 0,
- {0x74,0xfb,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0}
-},
-{ 14,
- 0x12a5,
- 0,
- {0x74,0xff,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0xe4,0xf0}
-},
-{ 1,
- 0x12b3,
- 0,
- {0x22}
-},
-{ 14,
- 0x12b4,
- 0,
- {0x12,0x03,0xcb,0x12,0x12,0x6d,0x7a,0xc0,0x7b,0x87,0x7c,0x01,0x74,0x01}
-},
-{ 14,
- 0x12c2,
- 0,
- {0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x74}
-},
-{ 14,
- 0x12d0,
- 0,
- {0x01,0x12,0x14,0xbf,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e}
-},
-{ 14,
- 0x12de,
- 0,
- {0x83,0x8f,0xf0,0x74,0x06,0x12,0x14,0xbf,0x74,0x01,0x2a,0xfd,0xe4,0x3b}
-},
-{ 14,
- 0x12ec,
- 0,
- {0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83,0x8c,0xf0,0xe4,0x12,0x14,0xbf,0x74}
-},
-{ 14,
- 0x12fa,
- 0,
- {0x01,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0}
-},
-{ 14,
- 0x1308,
- 0,
- {0x74,0x0b,0x12,0x14,0xbf,0x74,0x01,0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07}
-},
-{ 14,
- 0x1316,
- 0,
- {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x74,0x08,0x12,0x14,0xbf,0x74,0x01,0x2d}
-},
-{ 14,
- 0x1324,
- 0,
- {0xfa,0xe4,0x3e,0xfb,0x8f,0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0,0x74,0x01}
-},
-{ 14,
- 0x1332,
- 0,
- {0x12,0x14,0xbf,0x2a,0xfd,0xe4,0x3b,0xfe,0x8c,0x07,0x8a,0x82,0x8b,0x83}
-},
-{ 14,
- 0x1340,
- 0,
- {0x8c,0xf0,0xe4,0x12,0x14,0xbf,0x74,0x01,0x2d,0xfa,0xe4,0x3e,0xfb,0x8f}
-},
-{ 14,
- 0x134e,
- 0,
- {0x04,0x8d,0x82,0x8e,0x83,0x8f,0xf0,0x74,0x03,0x12,0x14,0xbf,0x7d,0x00}
-},
-{ 3,
- 0x135c,
- 0,
- {0xbd,0x06,0x00}
-},
-{ 2,
- 0x135f,
- 0,
- {0x50,0x12}
-},
-{ 11,
- 0x1361,
- 0,
- {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0x0a,0xba,0x00,0x01,0x0b}
-},
-{ 7,
- 0x136c,
- 0,
- {0xe4,0x12,0x14,0xbf,0x0d,0x80,0xe9}
-},
-{ 13,
- 0x1373,
- 0,
- {0x8a,0x82,0x8b,0x83,0x8c,0xf0,0xe5,0x74,0x12,0x14,0xbf,0x74,0xf9}
-},
-{ 14,
- 0x1380,
- 0,
- {0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0x74,0x0f,0xf0,0x74}
-},
-{ 14,
- 0x138e,
- 0,
- {0xfe,0x24,0x00,0xf5,0x82,0x74,0x03,0x34,0x84,0xf5,0x83,0x74,0x01,0xf0}
-},
-{ 6,
- 0x139c,
- 0,
- {0x12,0x03,0xe1,0x12,0x04,0xf7}
-},
-{ 1,
- 0x13a2,
- 0,
- {0x22}
-},
-{ 13,
- 0x13a3,
- 0,
- {0x90,0x7d,0xc1,0xe0,0xfa,0x24,0x00,0xfb,0xe4,0x34,0x19,0xfc,0x90}
-},
-{ 14,
- 0x13b0,
- 0,
- {0x7d,0xc2,0xe0,0xfd,0x8b,0x82,0x8c,0x83,0xf0,0x75,0xf0,0x11,0xea,0xa4}
-},
-{ 3,
- 0x13be,
- 0,
- {0xfa,0x7b,0x00}
-},
-{ 3,
- 0x13c1,
- 0,
- {0xbb,0x10,0x00}
-},
-{ 2,
- 0x13c4,
- 0,
- {0x50,0x24}
-},
-{ 14,
- 0x13c6,
- 0,
- {0xea,0x24,0x00,0xfc,0xe4,0x34,0x18,0xfd,0xeb,0x2c,0xfc,0xe4,0x3d,0xfd}
-},
-{ 14,
- 0x13d4,
- 0,
- {0x74,0x04,0x2b,0x24,0xc0,0xf5,0x82,0xe4,0x34,0x7d,0xf5,0x83,0xe0,0xfe}
-},
-{ 8,
- 0x13e2,
- 0,
- {0x8c,0x82,0x8d,0x83,0xf0,0x0b,0x80,0xd7}
-},
-{ 14,
- 0x13ea,
- 0,
- {0xea,0x24,0x00,0xfa,0xe4,0x34,0x18,0xfb,0x74,0x10,0x2a,0xf5,0x82,0xe4}
-},
-{ 5,
- 0x13f8,
- 0,
- {0x3b,0xf5,0x83,0xe4,0xf0}
-},
-{ 1,
- 0x13fd,
- 0,
- {0x22}
-},
-{ 4,
- 0x13fe,
- 0,
- {0xe5,0x76,0x60,0x02}
-},
-{ 2,
- 0x1402,
- 0,
- {0x80,0x16}
-},
-{ 12,
- 0x1404,
- 0,
- {0x74,0x0f,0x55,0x75,0xfa,0x8a,0x75,0x24,0x00,0xf5,0x82,0xe4}
-},
-{ 10,
- 0x1410,
- 0,
- {0x34,0x19,0xf5,0x83,0xe0,0xf5,0x74,0x12,0x12,0xb4}
-},
-{ 10,
- 0x141a,
- 0,
- {0x12,0x10,0xca,0x75,0x6e,0x00,0x75,0x6f,0x00,0x12}
-},
-{ 6,
- 0x1424,
- 0,
- {0x11,0x44,0x75,0x70,0xb9,0x75}
-},
-{ 6,
- 0x142a,
- 0,
- {0x71,0x14,0x75,0x72,0x02,0x12}
-},
-{ 11,
- 0x1430,
- 0,
- {0x11,0x75,0xe5,0x76,0xb4,0x02,0x04,0x74,0x01,0x80,0x01}
-},
-{ 1,
- 0x143b,
- 0,
- {0xe4}
-},
-{ 3,
- 0x143c,
- 0,
- {0xfa,0x70,0x0f}
-},
-{ 12,
- 0x143f,
- 0,
- {0x74,0x01,0x25,0x75,0xf5,0x73,0xc0,0x02,0x12,0x11,0xa0,0xd0}
-},
-{ 3,
- 0x144b,
- 0,
- {0x02,0x80,0x0a}
-},
-{ 10,
- 0x144e,
- 0,
- {0x85,0x75,0x73,0xc0,0x02,0x12,0x11,0xa0,0xd0,0x02}
-},
-{ 12,
- 0x1458,
- 0,
- {0x75,0x6e,0x00,0x75,0x6f,0x01,0xc0,0x02,0x12,0x11,0x44,0xd0}
-},
-{ 4,
- 0x1464,
- 0,
- {0x02,0xea,0x70,0x1a}
-},
-{ 13,
- 0x1468,
- 0,
- {0x75,0xf0,0x11,0xe5,0x75,0xa4,0xfa,0x24,0x00,0xfa,0xe4,0x34,0x18}
-},
-{ 9,
- 0x1475,
- 0,
- {0xfb,0x8a,0x70,0x8b,0x71,0x75,0x72,0x01,0x12}
-},
-{ 4,
- 0x147e,
- 0,
- {0x11,0x75,0x80,0x36}
-},
-{ 2,
- 0x1482,
- 0,
- {0x7a,0x00}
-},
-{ 3,
- 0x1484,
- 0,
- {0xba,0x10,0x00}
-},
-{ 2,
- 0x1487,
- 0,
- {0x50,0x2f}
-},
-{ 13,
- 0x1489,
- 0,
- {0xea,0x24,0x00,0xf5,0x82,0xe4,0x34,0x19,0xf5,0x83,0xe0,0xfb,0xe5}
-},
-{ 4,
- 0x1496,
- 0,
- {0x75,0xb5,0x03,0x1b}
-},
-{ 14,
- 0x149a,
- 0,
- {0x75,0xf0,0x11,0xea,0xa4,0xfb,0x24,0x00,0xfb,0xe4,0x34,0x18,0xfc,0x8b}
-},
-{ 9,
- 0x14a8,
- 0,
- {0x70,0x8c,0x71,0x75,0x72,0x01,0xc0,0x02,0x12}
-},
-{ 4,
- 0x14b1,
- 0,
- {0x11,0x75,0xd0,0x02}
-},
-{ 3,
- 0x14b5,
- 0,
- {0x0a,0x80,0xcc}
-},
-{ 1,
- 0x14b8,
- 0,
- {0x22}
-},
-{ 6,
- 0x14b9,
- 0,
- {0x50,0x72,0x6f,0x67,0x20,0x00}
-},
-{ 14,
- 0x14bf,
- 0,
- {0xc8,0xc0,0xe0,0xc8,0xc0,0xe0,0xe5,0xf0,0x60,0x0b,0x14,0x60,0x0f,0x14}
-},
-{ 7,
- 0x14cd,
- 0,
- {0x60,0x11,0x14,0x60,0x12,0x80,0x15}
-},
-{ 7,
- 0x14d4,
- 0,
- {0xd0,0xe0,0xa8,0x82,0xf6,0x80,0x0e}
-},
-{ 5,
- 0x14db,
- 0,
- {0xd0,0xe0,0xf0,0x80,0x09}
-},
-{ 4,
- 0x14e0,
- 0,
- {0xd0,0xe0,0x80,0x05}
-},
-{ 5,
- 0x14e4,
- 0,
- {0xd0,0xe0,0xa8,0x82,0xf2}
-},
-{ 4,
- 0x14e9,
- 0,
- {0xc8,0xd0,0xe0,0xc8}
-},
-{ 1,
- 0x14ed,
- 0,
- {0x22}
-},
-{ 14,
- 0x14ee,
- 0,
- {0xc8,0xc0,0xe0,0xe5,0xf0,0x60,0x0d,0x14,0x60,0x0f,0x14,0x60,0x0f,0x14}
-},
-{ 6,
- 0x14fc,
- 0,
- {0x60,0x10,0x74,0xff,0x80,0x0f}
-},
-{ 5,
- 0x1502,
- 0,
- {0xa8,0x82,0xe6,0x80,0x0a}
-},
-{ 3,
- 0x1507,
- 0,
- {0xe0,0x80,0x07}
-},
-{ 4,
- 0x150a,
- 0,
- {0xe4,0x93,0x80,0x03}
-},
-{ 3,
- 0x150e,
- 0,
- {0xa8,0x82,0xe2}
-},
-{ 4,
- 0x1511,
- 0,
- {0xf8,0xd0,0xe0,0xc8}
-},
-{ 1,
- 0x1515,
- 0,
- {0x22}
-},
-{ 0,
- 0x0,
- 1,
- {0}
-}
-};
diff --git a/drivers/usb/graphire.c b/drivers/usb/graphire.c
index cfda14d5c..8921c7db8 100644
--- a/drivers/usb/graphire.c
+++ b/drivers/usb/graphire.c
@@ -1,11 +1,16 @@
/*
- * graphire.c Version 0.1
+ * graphire.c Version 0.2
*
- * Copyright (c) 1999 Vojtech Pavlik
+ * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz>
+ * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk>
*
* USB Wacom Graphire tablet support
*
* Sponsored by SuSE
+ *
+ * ChangeLog:
+ * v0.1 (vp) - Initial release
+ * v0.2 (aba) - Support for all buttons / combinations
*/
/*
@@ -57,14 +62,19 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
* byte 7: pen presure high bits / mouse distance
*
* There are also two single-byte feature reports (2 and 3).
+ *
+ * Resolution:
+ * X: 0 - 10206
+ * Y: 0 - 7422
+ *
+ * (0,0) is upper left corner
*/
-#define USB_VENDOR_ID_WACOM 0xffff /* FIXME */
-#define USB_DEVICE_ID_WACOM_GRAPHIRE 0xffff /* FIXME */
+#define USB_VENDOR_ID_WACOM 0x056a
+#define USB_DEVICE_ID_WACOM_GRAPHIRE 0x0010
struct graphire {
signed char data[8];
- int oldx, oldy;
struct input_dev dev;
struct urb irq;
};
@@ -80,44 +90,38 @@ static void graphire_irq(struct urb *urb)
if (data[0] != 2)
dbg("received unknown report #%d", data[0]);
- input_report_abs(dev, ABS_X, data[2] | ((__u32)data[3] << 8));
- input_report_abs(dev, ABS_Y, data[4] | ((__u32)data[5] << 8));
-
- input_report_key(dev, BTN_NEAR, !!(data[1] & 0x80));
+ if ( data[1] & 0x80 ) {
+ input_report_abs(dev, ABS_X, data[2] | ((__u32)data[3] << 8));
+ input_report_abs(dev, ABS_Y, 7422 - (data[4] | ((__u32)data[5] << 8)));
+ }
switch ((data[1] >> 5) & 3) {
case 0: /* Pen */
- input_report_key(dev, BTN_PEN, !!(data[1] & 0x01));
- input_report_key(dev, BTN_PEN_SIDE, !!(data[1] & 0x02));
- input_report_key(dev, BTN_PEN_SIDE2, !!(data[1] & 0x04));
+ input_report_key(dev, BTN_TOOL_PEN, !!(data[1] & 0x80));
+ input_report_key(dev, BTN_TOUCH, !!(data[1] & 0x01));
+ input_report_key(dev, BTN_STYLUS, !!(data[1] & 0x02));
+ input_report_key(dev, BTN_STYLUS2, !!(data[1] & 0x04));
input_report_abs(dev, ABS_PRESSURE, data[6] | ((__u32)data[7] << 8));
break;
case 1: /* Rubber */
- input_report_key(dev, BTN_RUBBER, !!(data[1] & 0x01));
- input_report_key(dev, BTN_PEN_SIDE, !!(data[1] & 0x02));
- input_report_key(dev, BTN_PEN_SIDE2, !!(data[1] & 0x04));
+ input_report_key(dev, BTN_TOOL_RUBBER, !!(data[1] & 0x80));
+ input_report_key(dev, BTN_TOUCH, !!(data[1] & 0x01));
+ input_report_key(dev, BTN_STYLUS, !!(data[1] & 0x02));
+ input_report_key(dev, BTN_STYLUS2, !!(data[1] & 0x04));
input_report_abs(dev, ABS_PRESSURE, data[6] | ((__u32)data[7] << 8));
break;
case 2: /* Mouse */
- input_report_key(dev, BTN_LEFT, !!(data[0] & 0x01));
- input_report_key(dev, BTN_RIGHT, !!(data[0] & 0x02));
- input_report_key(dev, BTN_MIDDLE, !!(data[0] & 0x04));
+ input_report_key(dev, BTN_TOOL_MOUSE, data[7] > 24);
+ input_report_key(dev, BTN_LEFT, !!(data[1] & 0x01));
+ input_report_key(dev, BTN_RIGHT, !!(data[1] & 0x02));
+ input_report_key(dev, BTN_MIDDLE, !!(data[1] & 0x04));
input_report_abs(dev, ABS_DISTANCE, data[7]);
-
- if (data[1] & 0x80) {
- input_report_rel(dev, REL_X, dev->abs[ABS_X] - graphire->oldx);
- input_report_rel(dev, REL_Y, dev->abs[ABS_Y] - graphire->oldy);
- }
-
input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
break;
}
-
- graphire->oldx = dev->abs[ABS_X];
- graphire->oldy = dev->abs[ABS_Y];
}
static void *graphire_probe(struct usb_device *dev, unsigned int ifnum)
@@ -136,11 +140,16 @@ static void *graphire_probe(struct usb_device *dev, unsigned int ifnum)
graphire->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
graphire->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- graphire->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_PEN) | BIT(BTN_RUBBER);
- graphire->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_PEN_SIDE) | BIT(BTN_PEN_SIDE2) | BIT(BTN_NEAR);
- graphire->dev.relbit[0] |= BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL);
+ graphire->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE);
+ graphire->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
+ graphire->dev.relbit[0] |= BIT(REL_WHEEL);
graphire->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_DISTANCE);
+ graphire->dev.absmax[ABS_X] = 10206;
+ graphire->dev.absmax[ABS_Y] = 7422;
+ graphire->dev.absmax[ABS_PRESSURE] = 511;
+ graphire->dev.absmax[ABS_DISTANCE] = 32;
+
FILL_INT_URB(&graphire->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress),
graphire->data, 8, graphire_irq, graphire, endpoint->bInterval);
@@ -151,7 +160,7 @@ static void *graphire_probe(struct usb_device *dev, unsigned int ifnum)
input_register_device(&graphire->dev);
- printk(KERN_INFO "input%d: Wacom Graphire USB\n", graphire->dev.number);
+ printk(KERN_INFO "input%d: Wacom Graphire\n", graphire->dev.number);
return graphire;
}
diff --git a/drivers/usb/hid.c b/drivers/usb/hid.c
index ec1a4639d..28c4cc507 100644
--- a/drivers/usb/hid.c
+++ b/drivers/usb/hid.c
@@ -742,7 +742,11 @@ static void hid_configure_usage(struct hid_device *device, struct hid_field *fie
switch (device->application) {
case HID_GD_GAMEPAD: usage->code += 0x10;
case HID_GD_JOYSTICK: usage->code += 0x10;
- case HID_GD_MOUSE: usage->code += 0x10;
+ case HID_GD_MOUSE: usage->code += 0x10; break;
+ default:
+ if (field->physical == HID_GD_POINTER)
+ usage->code += 0x10;
+ break;
}
break;
@@ -769,7 +773,49 @@ static void hid_configure_usage(struct hid_device *device, struct hid_field *fie
usage->type = EV_LED; bit = input->ledbit; max = LED_MAX;
break;
+ case HID_UP_DIGITIZER:
+
+ switch (usage->hid & 0xff) {
+
+ case 0x30: /* TipPressure */
+
+ usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX;
+ usage->code = ABS_PRESSURE;
+ clear_bit(usage->code, bit);
+ break;
+
+ case 0x32: /* InRange */
+
+ usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
+ switch (field->physical & 0xff) {
+ case 0x21: usage->code = BTN_TOOL_MOUSE; break;
+ case 0x22: usage->code = BTN_TOOL_FINGER; break;
+ default: usage->code = BTN_TOOL_PEN; break;
+ }
+ break;
+
+ case 0x33: /* Touch */
+ case 0x42: /* TipSwitch */
+ case 0x43: /* TipSwitch2 */
+
+ usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
+ usage->code = BTN_TOUCH;
+ clear_bit(usage->code, bit);
+ break;
+
+ case 0x44: /* BarrelSwitch */
+
+ usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
+ usage->code = BTN_STYLUS;
+ clear_bit(usage->code, bit);
+ break;
+
+ default: goto unknown;
+ }
+ break;
+
default:
+ unknown:
if (field->flags & HID_MAIN_ITEM_RELATIVE) {
usage->code = REL_MISC;
@@ -777,7 +823,7 @@ static void hid_configure_usage(struct hid_device *device, struct hid_field *fie
break;
}
- if (field->logical_minimum == 0 && field->logical_maximum == 1) {
+ if (field->report_size == 1) {
usage->code = BTN_MISC;
usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX;
break;
@@ -959,7 +1005,7 @@ static void hid_irq(struct urb *urb)
static void hid_read_report(struct hid_device *hid, struct hid_report *report)
{
#if 0
- int rlen = ((report->size - 1) >> 3) + 1 + hid->report_enum[HID_INPUT_REPORT].numbered;
+ int rlen = ((report->size - 1) >> 3) + 1;
char rdata[rlen];
struct urb urb;
int read, j;
@@ -973,7 +1019,7 @@ static void hid_read_report(struct hid_device *hid, struct hid_report *report)
dbg("getting report type %d id %d len %d", report->type + 1, report->id, rlen);
- if ((read = usb_get_report(hid->dev, report->type + 1, report->id, hid->ifnum, rdata, rlen)) != rlen) {
+ if ((read = usb_get_report(hid->dev, hid->ifnum, report->type + 1, report->id, rdata, rlen)) != rlen) {
dbg("reading report failed rlen %d read %d", rlen, read);
#ifdef DEBUG
printk(KERN_DEBUG __FILE__ ": report = ");
@@ -1013,13 +1059,6 @@ static void hid_output_field(struct hid_field *field, __u8 *data)
void hid_output_report(struct hid_report *report, __u8 *data)
{
unsigned n;
-
-#if 0
- /* skip the ID if we have a single report */
- if (report->device->report_enum[report->type].numbered)
- *data++ = report->id;
-#endif
-
for (n = 0; n < report->maxfield; n++)
hid_output_field(report->field[n], data);
};
@@ -1142,7 +1181,7 @@ static void hid_init_input(struct hid_device *hid)
hid_configure_usage(hid, report->field[i], report->field[i]->usage + j);
if (k == HID_INPUT_REPORT) {
- usb_set_idle(hid->dev, 0, report->id);
+ usb_set_idle(hid->dev, hid->ifnum, report->id, 0);
hid_read_report(hid, report);
}
}
@@ -1151,7 +1190,7 @@ static void hid_init_input(struct hid_device *hid)
static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
{
- struct usb_interface_descriptor *interface = &dev->actconfig->interface[ifnum].altsetting[0];
+ struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0;
struct hid_descriptor *hdesc;
struct hid_device *hid;
unsigned rsize = 0;
@@ -1178,7 +1217,7 @@ static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
{
__u8 rdesc[rsize];
- if ((n = usb_get_class_descriptor(dev, USB_DT_REPORT, 0, ifnum, rdesc, rsize)) < 0) {
+ if ((n = usb_get_class_descriptor(dev, interface->bInterfaceNumber, USB_DT_REPORT, 0, rdesc, rsize)) < 0) {
dbg("reading report descriptor failed");
return NULL;
}
@@ -1226,19 +1265,22 @@ static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum)
return NULL;
}
+ hid->version = hdesc->bcdHID;
+ hid->country = hdesc->bCountryCode;
+ hid->dev = dev;
+ hid->ifnum = interface->bInterfaceNumber;
+
hid->dr.requesttype = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
hid->dr.request = USB_REQ_SET_REPORT;
hid->dr.value = 0x200;
- hid->dr.index = interface->bInterfaceNumber;
+ hid->dr.index = hid->ifnum;
hid->dr.length = 1;
FILL_CONTROL_URB(&hid->urbout, dev, usb_sndctrlpipe(dev, 0),
(void*) &hid->dr, hid->bufout, 1, hid_ctrl, hid);
- hid->version = hdesc->bcdHID;
- hid->country = hdesc->bCountryCode;
- hid->dev = dev;
- hid->ifnum = ifnum;
+ if (interface->bInterfaceSubClass == 1)
+ usb_set_protocol(dev, hid->ifnum, 1);
return hid;
}
diff --git a/drivers/usb/hid.h b/drivers/usb/hid.h
index ab652442f..e53135f1e 100644
--- a/drivers/usb/hid.h
+++ b/drivers/usb/hid.h
@@ -30,7 +30,6 @@
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/malloc.h>
#include <linux/list.h>
@@ -164,6 +163,7 @@ struct hid_item {
#define HID_USAGE 0x0000ffff
+#define HID_GD_POINTER 0x00010001
#define HID_GD_MOUSE 0x00010002
#define HID_GD_JOYSTICK 0x00010004
#define HID_GD_GAMEPAD 0x00010005
diff --git a/drivers/usb/hub.c b/drivers/usb/hub.c
index c066c3c43..3eca7a857 100644
--- a/drivers/usb/hub.c
+++ b/drivers/usb/hub.c
@@ -5,7 +5,7 @@
* (C) Copyright 1999 Johannes Erdfelt
* (C) Copyright 1999 Gregory P. Smith
*
- * $Id: hub.c,v 1.15 1999/12/27 15:17:45 acher Exp $
+ * $Id: hub.c,v 1.21 2000/01/16 21:19:44 acher Exp $
*/
#include <linux/kernel.h>
@@ -22,15 +22,6 @@
#include "usb.h"
#include "hub.h"
-#ifdef __alpha
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-extern long __kernel_thread(unsigned long, int (*)(void *), void *);
-static inline long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
- return __kernel_thread(flags | CLONE_VM, fn, arg);
-}
-#endif
-#endif
/* Wakes up khubd */
static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED;
@@ -112,6 +103,16 @@ static int hub_irq(int status, void *__buffer, int len, void *dev_id)
return 1;
}
+static void usb_hub_power_on(struct usb_hub *hub)
+{
+ int i;
+
+ /* Enable power to the ports */
+ dbg("enabling power on all ports");
+ for (i = 0; i < hub->nports; i++)
+ usb_set_port_feature(hub->dev, i + 1, USB_PORT_FEAT_POWER);
+}
+
static int usb_hub_configure(struct usb_hub *hub)
{
struct usb_device *dev = hub->dev;
@@ -191,10 +192,8 @@ static int usb_hub_configure(struct usb_hub *hub)
dbg("%sover-current condition exists",
(le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? "" : "no ");
- /* Enable power to the ports */
- dbg("enabling power on all ports");
- for (i = 0; i < hub->nports; i++)
- usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
+ usb_hub_power_on(hub);
+
return 0;
}
@@ -322,13 +321,17 @@ static void usb_hub_port_connect_change(struct usb_device *hub, int port)
portchange = le16_to_cpu(portsts.wPortChange);
dbg("portstatus %x, change %x, %s", portstatus, portchange,
portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low Speed" : "High Speed");
- /* If it's not in CONNECT and ENABLE state, we're done */
- if ((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
- (!(portstatus & USB_PORT_STAT_ENABLE))) {
- /* Disconnect anything that may have been there */
+
+ /* Clear the connection change status */
+ usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION);
+
+ /* Disconnect any existing devices under this port */
+ if (((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
+ (!(portstatus & USB_PORT_STAT_ENABLE)))|| (hub->children[port])) {
usb_disconnect(&hub->children[port]);
- /* We're done now, we already disconnected the device */
- return;
+ /* Return now if nothing is connected */
+ if (!(portstatus & USB_PORT_STAT_CONNECTION))
+ return;
}
wait_ms(400);
@@ -350,7 +353,11 @@ static void usb_hub_port_connect_change(struct usb_device *hub, int port)
dbg("portstatus %x, change %x, %s", portstatus ,portchange,
portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low Speed" : "High Speed");
- if ((portstatus&(1<<USB_PORT_FEAT_ENABLE)))
+ if ((portchange & USB_PORT_STAT_C_CONNECTION) ||
+ !(portstatus & USB_PORT_STAT_CONNECTION))
+ return;
+
+ if (portstatus & USB_PORT_STAT_ENABLE)
break;
wait_ms(200);
@@ -361,6 +368,9 @@ static void usb_hub_port_connect_change(struct usb_device *hub, int port)
err("Maybe the USB cable is bad?");
return;
}
+
+ usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_RESET);
+
/* Allocate a new device struct for it */
usb = usb_alloc_dev(hub, hub->bus);
@@ -432,8 +442,6 @@ static void usb_hub_events(void)
if (portchange & USB_PORT_STAT_C_CONNECTION) {
dbg("port %d connection change", i + 1);
- usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_CONNECTION);
-
usb_hub_port_connect_change(dev, i);
}
@@ -442,12 +450,15 @@ static void usb_hub_events(void)
usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_ENABLE);
}
- if (portchange & USB_PORT_STAT_C_SUSPEND)
+ if (portstatus & USB_PORT_STAT_SUSPEND) {
dbg("port %d suspend change", i + 1);
-
+ usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_SUSPEND);
+ }
+
if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
- dbg("port %d over-current change", i + 1);
+ err("port %d over-current change", i + 1);
usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_OVER_CURRENT);
+ usb_hub_power_on(hub);
}
if (portchange & USB_PORT_STAT_C_RESET) {
@@ -468,7 +479,9 @@ static void usb_hub_events(void)
}
if (hubchange & HUB_CHANGE_OVERCURRENT) {
dbg("hub overcurrent change");
+ wait_ms(500); //Cool down
usb_clear_hub_feature(dev, C_HUB_OVER_CURRENT);
+ usb_hub_power_on(hub);
}
}
} /* end while (1) */
@@ -491,6 +504,7 @@ static int usb_hub_thread(void *__hub)
* This thread doesn't need any user-level access,
* so get rid of all our resources
*/
+ exit_files(current); /* daemonize doesn't do exit_files */
daemonize();
/* Setup a nice name */
diff --git a/drivers/usb/ibmcam.c b/drivers/usb/ibmcam.c
new file mode 100644
index 000000000..2e9d43fa8
--- /dev/null
+++ b/drivers/usb/ibmcam.c
@@ -0,0 +1,2346 @@
+/*
+ * USB IBM C-It Video Camera driver
+ *
+ * Supports IBM C-It Video Camera.
+ *
+ * This driver is based on earlier work of:
+ *
+ * (C) Copyright 1999 Johannes Erdfelt
+ * (C) Copyright 1999 Randy Dunlap
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/malloc.h>
+#include <linux/mm.h>
+#include <linux/smp_lock.h>
+#include <linux/videodev.h>
+#include <linux/vmalloc.h>
+#include <linux/wrapper.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+
+#include "usb.h"
+#include "ibmcam.h"
+
+#define ENABLE_HEXDUMP 0 /* Enable if you need it */
+static int debug = 0;
+
+/* Completion states of the data parser */
+typedef enum {
+ scan_Continue, /* Just parse next item */
+ scan_NextFrame, /* Frame done, send it to V4L */
+ scan_Out, /* Not enough data for frame */
+ scan_EndParse /* End parsing */
+} scan_state_t;
+
+/* Bit flags (options) */
+#define FLAGS_RETRY_VIDIOCSYNC (1 << 0)
+#define FLAGS_MONOCHROME (1 << 1)
+#define FLAGS_DISPLAY_HINTS (1 << 2)
+#define FLAGS_OVERLAY_STATS (1 << 3)
+#define FLAGS_FORCE_TESTPATTERN (1 << 4)
+
+static int flags = 0; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */
+
+/* This is the size of V4L frame that we provide */
+static const int imgwidth = V4L_FRAME_WIDTH_USED;
+static const int imgheight = V4L_FRAME_HEIGHT;
+static const int min_imgwidth = 8;
+static const int min_imgheight = 4;
+
+#define LIGHTING_MIN 0 /* 0=Bright 1=Med 2=Low */
+#define LIGHTING_MAX 2
+static int lighting = (LIGHTING_MIN + LIGHTING_MAX) / 2; /* Medium */
+
+#define SHARPNESS_MIN 0
+#define SHARPNESS_MAX 6
+static int sharpness = 4; /* Low noise, good details */
+
+#define FRAMERATE_MIN 0
+#define FRAMERATE_MAX 6
+static int framerate = 2; /* Lower, reliable frame rate (8-12 fps) */
+
+enum {
+ VIDEOSIZE_128x96 = 0,
+ VIDEOSIZE_176x144,
+ VIDEOSIZE_352x288
+};
+
+static int videosize = VIDEOSIZE_352x288;
+
+/*
+ * The value of 'scratchbufsize' affects quality of the picture
+ * in many ways. Shorter buffers may cause loss of data when client
+ * is too slow. Larger buffers are memory-consuming and take longer
+ * to work with. This setting can be adjusted, but the default value
+ * should be OK for most desktop users.
+ */
+#define DEFAULT_SCRATCH_BUF_SIZE (0x10000) /* 64 KB */
+static const int scratchbufsize = DEFAULT_SCRATCH_BUF_SIZE;
+
+/*
+ * Here we define several initialization variables. They may
+ * be used to automatically set color, hue, brightness and
+ * contrast to desired values. This is particularly useful in
+ * case of webcams (which have no controls and no on-screen
+ * output) and also when a client V4L software is used that
+ * does not have some of those controls. In any case it's
+ * good to have startup values as options.
+ *
+ * These values are all in [0..255] range. This simplifies
+ * operation. Note that actual values of V4L variables may
+ * be scaled up (as much as << 8). User can see that only
+ * on overlay output, however, or through a V4L client.
+ */
+static int init_brightness = 128;
+static int init_contrast = 192;
+static int init_color = 128;
+static int init_hue = 128;
+
+MODULE_PARM(debug, "i");
+MODULE_PARM(flags, "i");
+MODULE_PARM(framerate, "i");
+MODULE_PARM(lighting, "i");
+MODULE_PARM(sharpness, "i");
+MODULE_PARM(videosize, "i");
+MODULE_PARM(init_brightness, "i");
+MODULE_PARM(init_contrast, "i");
+MODULE_PARM(init_color, "i");
+MODULE_PARM(init_hue, "i");
+
+MODULE_AUTHOR ("module author");
+MODULE_DESCRIPTION ("IBM/Xirlink C-it USB Camera Driver for Linux (c) 2000");
+
+/* Still mysterious i2c commands */
+static const unsigned short unknown_88 = 0x0088;
+static const unsigned short unknown_89 = 0x0089;
+static const unsigned short bright_3x[3] = { 0x0031, 0x0032, 0x0033 };
+static const unsigned short contrast_14 = 0x0014;
+static const unsigned short light_27 = 0x0027;
+static const unsigned short sharp_13 = 0x0013;
+
+/*******************************/
+/* Memory management functions */
+/*******************************/
+
+#define MDEBUG(x) do { } while(0) /* Debug memory management */
+
+static struct usb_driver ibmcam_driver;
+
+/* Given PGD from the address space's page table, return the kernel
+ * virtual mapping of the physical memory mapped at ADR.
+ */
+static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
+{
+ unsigned long ret = 0UL;
+ pmd_t *pmd;
+ pte_t *ptep, pte;
+
+ if (!pgd_none(*pgd)) {
+ pmd = pmd_offset(pgd, adr);
+ if (!pmd_none(*pmd)) {
+ ptep = pte_offset(pmd, adr);
+ pte = *ptep;
+ if (pte_present(pte))
+ ret = page_address(pte_page(pte)) | (adr & (PAGE_SIZE-1));
+ }
+ }
+ MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
+ return ret;
+}
+
+static inline unsigned long uvirt_to_bus(unsigned long adr)
+{
+ unsigned long kva, ret;
+
+ kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
+ ret = virt_to_bus((void *)kva);
+ MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
+ return ret;
+}
+
+static inline unsigned long kvirt_to_bus(unsigned long adr)
+{
+ unsigned long va, kva, ret;
+
+ va = VMALLOC_VMADDR(adr);
+ kva = uvirt_to_kva(pgd_offset_k(va), va);
+ ret = virt_to_bus((void *)kva);
+ MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
+ return ret;
+}
+
+/* Here we want the physical address of the memory.
+ * This is used when initializing the contents of the
+ * area and marking the pages as reserved.
+ */
+static inline unsigned long kvirt_to_pa(unsigned long adr)
+{
+ unsigned long va, kva, ret;
+
+ va = VMALLOC_VMADDR(adr);
+ kva = uvirt_to_kva(pgd_offset_k(va), va);
+ ret = __pa(kva);
+ MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
+ return ret;
+}
+
+static void *rvmalloc(unsigned long size)
+{
+ void *mem;
+ unsigned long adr, page;
+
+ /* Round it off to PAGE_SIZE */
+ size += (PAGE_SIZE - 1);
+ size &= ~(PAGE_SIZE - 1);
+
+ mem = vmalloc(size);
+ if (!mem)
+ return NULL;
+
+ memset(mem, 0, size); /* Clear the ram out, no junk to the user */
+ adr = (unsigned long) mem;
+ while (size > 0) {
+ page = kvirt_to_pa(adr);
+ mem_map_reserve(MAP_NR(__va(page)));
+ adr += PAGE_SIZE;
+ if (size > PAGE_SIZE)
+ size -= PAGE_SIZE;
+ else
+ size = 0;
+ }
+
+ return mem;
+}
+
+static void rvfree(void *mem, unsigned long size)
+{
+ unsigned long adr, page;
+
+ if (!mem)
+ return;
+
+ size += (PAGE_SIZE - 1);
+ size &= ~(PAGE_SIZE - 1);
+
+ adr=(unsigned long) mem;
+ while (size > 0) {
+ page = kvirt_to_pa(adr);
+ mem_map_unreserve(MAP_NR(__va(page)));
+ adr += PAGE_SIZE;
+ if (size > PAGE_SIZE)
+ size -= PAGE_SIZE;
+ else
+ size = 0;
+ }
+ vfree(mem);
+}
+
+/*
+ * usb_ibmcam_overlaychar()
+ *
+ * History:
+ * 1/2/00 Created.
+ */
+void usb_ibmcam_overlaychar(
+ struct usb_ibmcam *ibmcam,
+ struct ibmcam_frame *frame,
+ int x, int y, int ch)
+{
+ static const unsigned short digits[16] = {
+ 0xF6DE, /* 0 */
+ 0x2492, /* 1 */
+ 0xE7CE, /* 2 */
+ 0xE79E, /* 3 */
+ 0xB792, /* 4 */
+ 0xF39E, /* 5 */
+ 0xF3DE, /* 6 */
+ 0xF492, /* 7 */
+ 0xF7DE, /* 8 */
+ 0xF79E, /* 9 */
+ 0x77DA, /* a */
+ 0xD75C, /* b */
+ 0xF24E, /* c */
+ 0xD6DC, /* d */
+ 0xF34E, /* e */
+ 0xF348 /* f */
+ };
+ unsigned short digit;
+ int ix, iy;
+
+ if ((ibmcam == NULL) || (frame == NULL))
+ return;
+
+ if (ch >= '0' && ch <= '9')
+ ch -= '0';
+ else if (ch >= 'A' && ch <= 'F')
+ ch = 10 + (ch - 'A');
+ else if (ch >= 'a' && ch <= 'f')
+ ch = 10 + (ch - 'a');
+ else
+ return;
+ digit = digits[ch];
+
+ for (iy=0; iy < 5; iy++) {
+ for (ix=0; ix < 3; ix++) {
+ if (digit & 0x8000) {
+ IBMCAM_PUTPIXEL(frame, x+ix, y+iy, 0xFF, 0xFF, 0xFF);
+ }
+ digit = digit << 1;
+ }
+ }
+}
+
+/*
+ * usb_ibmcam_overlaystring()
+ *
+ * History:
+ * 1/2/00 Created.
+ */
+void usb_ibmcam_overlaystring(
+ struct usb_ibmcam *ibmcam,
+ struct ibmcam_frame *frame,
+ int x, int y, const char *str)
+{
+ while (*str) {
+ usb_ibmcam_overlaychar(ibmcam, frame, x, y, *str);
+ str++;
+ x += 4; /* 3 pixels character + 1 space */
+ }
+}
+
+/*
+ * usb_ibmcam_overlaystats()
+ *
+ * Overlays important debugging information.
+ *
+ * History:
+ * 1/2/00 Created.
+ */
+void usb_ibmcam_overlaystats(struct usb_ibmcam *ibmcam, struct ibmcam_frame *frame)
+{
+ const int y_diff = 8;
+ char tmp[16];
+ int x = 10;
+ int y = 10;
+
+ sprintf(tmp, "%8x", ibmcam->frame_num);
+ usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8lx", ibmcam->urb_count);
+ usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8lx", ibmcam->urb_length);
+ usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8lx", ibmcam->data_count);
+ usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8lx", ibmcam->header_count);
+ usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8lx", ibmcam->scratch_ovf_count);
+ usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8lx", ibmcam->iso_skip_count);
+ usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8lx", ibmcam->iso_err_count);
+ usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8x", ibmcam->vpic.colour);
+ usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8x", ibmcam->vpic.hue);
+ usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8x", ibmcam->vpic.brightness >> 8);
+ usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8x", ibmcam->vpic.contrast >> 12);
+ usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8d", ibmcam->vpic.whiteness >> 8);
+ usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);
+ y += y_diff;
+}
+
+/*
+ * usb_ibmcam_testpattern()
+ *
+ * Procedure forms a test pattern (yellow grid on blue background).
+ *
+ * Parameters:
+ * fullframe: if TRUE then entire frame is filled, otherwise the procedure
+ * continues from the current scanline.
+ * pmode 0: fill the frame with solid blue color (like on VCR or TV)
+ * 1: Draw a colored grid
+ *
+ * History:
+ * 1/2/00 Created.
+ */
+void usb_ibmcam_testpattern(struct usb_ibmcam *ibmcam, int fullframe, int pmode)
+{
+ static const char proc[] = "usb_ibmcam_testpattern";
+ struct ibmcam_frame *frame;
+ unsigned char *f;
+ int num_cell = 0;
+ int scan_length = 0;
+ static int num_pass = 0;
+
+ if (ibmcam == NULL) {
+ printk(KERN_ERR "%s: ibmcam == NULL\n", proc);
+ return;
+ }
+ if ((ibmcam->curframe < 0) || (ibmcam->curframe >= IBMCAM_NUMFRAMES)) {
+ printk(KERN_ERR "%s: ibmcam->curframe=%d.\n", proc, ibmcam->curframe);
+ return;
+ }
+
+ /* Grab the current frame */
+ frame = &ibmcam->frame[ibmcam->curframe];
+
+ /* Optionally start at the beginning */
+ if (fullframe) {
+ frame->curline = 0;
+ frame->scanlength = 0;
+ }
+
+ /* Form every scan line */
+ for (; frame->curline < imgheight; frame->curline++) {
+ int i;
+
+ f = frame->data + (imgwidth * 3 * frame->curline);
+ for (i=0; i < imgwidth; i++) {
+ unsigned char cb=0x80;
+ unsigned char cg = 0;
+ unsigned char cr = 0;
+
+ if (pmode == 1) {
+ if (frame->curline % 32 == 0)
+ cb = 0, cg = cr = 0xFF;
+ else if (i % 32 == 0) {
+ if (frame->curline % 32 == 1)
+ num_cell++;
+ cb = 0, cg = cr = 0xFF;
+ } else {
+ cb = ((num_cell*7) + num_pass) & 0xFF;
+ cg = ((num_cell*5) + num_pass*2) & 0xFF;
+ cr = ((num_cell*3) + num_pass*3) & 0xFF;
+ }
+ } else {
+ /* Just the blue screen */
+ }
+
+ *f++ = cb;
+ *f++ = cg;
+ *f++ = cr;
+ scan_length += 3;
+ }
+ }
+
+ frame->grabstate = FRAME_DONE;
+ frame->scanlength += scan_length;
+ ++num_pass;
+
+ /* We do this unconditionally, regardless of FLAGS_OVERLAY_STATS */
+ usb_ibmcam_overlaystats(ibmcam, frame);
+}
+
+static unsigned char *ibmcam_find_header(const unsigned char hdr_sig, unsigned char *data, int len)
+{
+ while (len >= 4)
+ {
+ if ((data[0] == 0x00) && (data[1] == 0xFF) && (data[2] == 0x00))
+ {
+#if 0
+ /* This code helps to detect new frame markers */
+ printk(KERN_DEBUG "Header sig: 00 FF 00 %02X\n", data[3]);
+#endif
+ if (data[3] == hdr_sig) {
+ if (debug > 2)
+ printk(KERN_DEBUG "Header found.\n");
+ return data;
+ }
+ }
+ ++data;
+ --len;
+ }
+ return NULL;
+}
+
+/* How much data is left in the scratch buf? */
+#define scratch_left(x) (ibmcam->scratchlen - (int)((char *)x - (char *)ibmcam->scratch))
+
+/* Grab the remaining */
+static void usb_ibmcam_align_scratch(struct usb_ibmcam *ibmcam, unsigned char *data)
+{
+ unsigned long left;
+
+ left = scratch_left(data);
+ memmove(ibmcam->scratch, data, left);
+ ibmcam->scratchlen = left;
+}
+
+/*
+ * usb_ibmcam_find_header()
+ *
+ * Locate one of supported header markers in the scratch buffer.
+ * Once found, remove all preceding bytes AND the marker (4 bytes)
+ * from the scratch buffer. Whatever follows must be video lines.
+ *
+ * History:
+ * 1/21/00 Created.
+ */
+static scan_state_t usb_ibmcam_find_header(struct usb_ibmcam *ibmcam)
+{
+ struct ibmcam_frame *frame;
+ unsigned char *data, *tmp;
+
+ data = ibmcam->scratch;
+ frame = &ibmcam->frame[ibmcam->curframe];
+ tmp = ibmcam_find_header(frame->hdr_sig, data, scratch_left(data));
+
+ if (tmp == NULL) {
+ /* No header - entire scratch buffer is useless! */
+ if (debug > 2)
+ printk(KERN_DEBUG "Skipping frame, no header\n");
+ ibmcam->scratchlen = 0;
+ return scan_EndParse;
+ }
+ /* Header found */
+ data = tmp+4;
+
+ ibmcam->has_hdr = 1;
+ ibmcam->header_count++;
+ frame->scanstate = STATE_LINES;
+ frame->curline = 0;
+
+ if (flags & FLAGS_FORCE_TESTPATTERN) {
+ usb_ibmcam_testpattern(ibmcam, 1, 1);
+ return scan_NextFrame;
+ }
+ usb_ibmcam_align_scratch(ibmcam, data);
+ return scan_Continue;
+}
+
+/*
+ * usb_ibmcam_parse_lines()
+ *
+ * Parse one line (TODO: more than one!) from the scratch buffer, put
+ * decoded RGB value into the current frame buffer and add the written
+ * number of bytes (RGB) to the *pcopylen.
+ *
+ * History:
+ * 1/21/00 Created.
+ */
+static scan_state_t usb_ibmcam_parse_lines(struct usb_ibmcam *ibmcam, long *pcopylen)
+{
+ struct ibmcam_frame *frame;
+ unsigned char *data, *f, *chromaLine;
+ unsigned int len;
+ const int v4l_linesize = imgwidth * V4L_BYTES_PER_PIXEL; /* V4L line offset */
+ int y, u, v, i, frame_done=0, mono_plane, hue_corr, color_corr;
+
+ hue_corr = (ibmcam->vpic.hue - 0x8000) >> 10; /* -32..+31 */
+ color_corr = (ibmcam->vpic.colour - 0x8000) >> 10; /* -32..+31 */
+
+ data = ibmcam->scratch;
+ frame = &ibmcam->frame[ibmcam->curframe];
+
+ len = frame->frmwidth * 3; /* 1 line of mono + 1 line of color */
+ /*printk(KERN_DEBUG "len=%d. left=%d.\n",len,scratch_left(data));*/
+
+ mono_plane = ((frame->curline & 1) == 0);
+
+ /*
+ * Lines are organized this way (or are they?)
+ *
+ * I420:
+ * ~~~~
+ * ___________________________________
+ * |-----Y-----|---UVUVUV...UVUV-----| \
+ * |-----------+---------------------| \
+ * |<-- 176 -->|<------ 176*2 ------>| Total 72. pairs of lines
+ * |... ... ...| /
+ * |___________|_____________________| /
+ * - odd line- ------- even line ---
+ *
+ * another format:
+ * ~~~~~~~~~~~~~~
+ * ___________________________________
+ * |-----Y-----|---UVUVUV...UVUV-----| \
+ * |-----------+---------------------| \
+ * |<-- 352 -->|<------ 352*2 ------>| Total 144. pairs of lines
+ * |... ... ...| /
+ * |___________|_____________________| /
+ * - odd line- ------- even line ---
+ */
+
+ /* Make sure there's enough data for the entire line */
+ if (scratch_left(data) < (len+1024)) {
+ /*printk(KERN_DEBUG "out of data, need %u.\n", len);*/
+ return scan_Out;
+ }
+
+ /*
+ * Make sure that our writing into output buffer
+ * will not exceed the buffer. Mind that we may write
+ * not into current output scanline but in several after
+ * it as well (if we enlarge image vertically.)
+ */
+ if ((frame->curline + 1) >= V4L_FRAME_HEIGHT)
+ return scan_NextFrame;
+
+ /*
+ * Now we are sure that entire line (representing all 'frame->frmwidth'
+ * pixels from the camera) is available in the scratch buffer. We
+ * start copying the line left-aligned to the V4L buffer (which
+ * might be larger - not smaller, hopefully). If the camera
+ * line is shorter then we should pad the V4L buffer with something
+ * (black in this case) to complete the line.
+ */
+ f = frame->data + (v4l_linesize * frame->curline);
+
+ /*
+ * chromaLine points to 1st pixel of the line with chrominance.
+ * If current line is monochrome then chromaLine points to next
+ * line after monochrome one. If current line has chrominance
+ * then chromaLine points to this very line. Such method allows
+ * to access chrominance data uniformly.
+ *
+ * To obtain chrominance data from the 'chromaLine' use this:
+ * v = chromaLine[0]; // 0-1:[0], 2-3:[4], 4-5:[8]...
+ * u = chromaLine[2]; // 0-1:[2], 2-3:[6], 4-5:[10]...
+ *
+ * Indices must be calculated this way:
+ * v_index = (i >> 1) << 2;
+ * u_index = (i >> 1) << 2 + 2;
+ *
+ * where 'i' is the column number [0..frame->frmwidth-1]
+ */
+ chromaLine = data;
+ if (mono_plane)
+ chromaLine += frame->frmwidth;
+
+ for (i = 0; i < frame->frmwidth; i++, data += (mono_plane ? 1 : 2))
+ {
+ unsigned char rv, gv, bv; /* RGB components */
+
+ /*
+ * Search for potential Start-Of-Frame marker. It should
+ * not be here, of course, but if your formats don't match
+ * you might exceed the frame. We must match the marker to
+ * each byte of multi-byte data element if it is multi-byte.
+ */
+#if 1
+ if (scratch_left(data) >= (4+2)) {
+ unsigned char *dp;
+ int j;
+
+ for (j=0, dp=data; j < 2; j++, dp++) {
+ if ((dp[0] == 0x00) && (dp[1] == 0xFF) &&
+ (dp[2] == 0x00) && (dp[3] == frame->hdr_sig)) {
+ ibmcam->has_hdr = 2;
+ frame_done++;
+ break;
+ }
+ }
+ }
+#endif
+
+ /* Check for various visual debugging hints (colorized pixels) */
+ if ((flags & FLAGS_DISPLAY_HINTS) && (ibmcam->has_hdr)) {
+ /*
+ * This is bad and should not happen. This means that
+ * we somehow overshoot the line and encountered new
+ * frame! Obviously our camera/V4L frame size is out
+ * of whack. This cyan dot will help you to figure
+ * out where exactly the new frame arrived.
+ */
+ if (ibmcam->has_hdr == 1) {
+ bv = 0; /* Yellow marker */
+ gv = 0xFF;
+ rv = 0xFF;
+ } else {
+ bv = 0xFF; /* Cyan marker */
+ gv = 0xFF;
+ rv = 0;
+ }
+ ibmcam->has_hdr = 0;
+ goto make_pixel;
+ }
+
+ y = mono_plane ? data[0] : data[1];
+
+ if (flags & FLAGS_MONOCHROME) /* Use monochrome for debugging */
+ rv = gv = bv = y;
+ else {
+ if (frame->order_uv) {
+ u = chromaLine[(i >> 1) << 2] + hue_corr;
+ v = chromaLine[((i >> 1) << 2) + 2] + color_corr;
+ } else {
+ v = chromaLine[(i >> 1) << 2] + color_corr;
+ u = chromaLine[((i >> 1) << 2) + 2] + hue_corr;
+ }
+ YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv);
+ }
+
+ make_pixel:
+ /*
+ * The purpose of creating the pixel here, in one,
+ * dedicated place is that we may need to make the
+ * pixel wider and taller than it actually is. This
+ * may be used if camera generates small frames for
+ * sake of frame rate (or any other reason.)
+ *
+ * The output data consists of B, G, R bytes
+ * (in this order).
+ */
+#if USES_IBMCAM_PUTPIXEL
+ IBMCAM_PUTPIXEL(frame, i, frame->curline, rv, gv, bv);
+#else
+ *f++ = bv;
+ *f++ = gv;
+ *f++ = rv;
+#endif
+ /*
+ * Typically we do not decide within a legitimate frame
+ * that we want to end the frame. However debugging code
+ * may detect marker of new frame within the data. Then
+ * this condition activates. The 'data' pointer is already
+ * pointing at the new marker, so we'd better leave it as is.
+ */
+ if (frame_done)
+ break; /* End scanning of lines */
+ }
+ /*
+ * Account for number of bytes that we wrote into output V4L frame.
+ * We do it here, after we are done with the scanline, because we
+ * may fill more than one output scanline if we do vertical
+ * enlargement.
+ */
+ frame->curline++;
+ *pcopylen += v4l_linesize;
+ usb_ibmcam_align_scratch(ibmcam, data);
+
+ if (frame_done || (frame->curline >= frame->frmheight))
+ return scan_NextFrame;
+ else
+ return scan_Continue;
+}
+
+/*
+ * ibmcam_parse_data()
+ *
+ * Generic routine to parse the scratch buffer. It employs either
+ * usb_ibmcam_find_header() or usb_ibmcam_parse_lines() to do most
+ * of work.
+ *
+ * History:
+ * 1/21/00 Created.
+ */
+static void ibmcam_parse_data(struct usb_ibmcam *ibmcam)
+{
+ struct ibmcam_frame *frame;
+ unsigned char *data = ibmcam->scratch;
+ scan_state_t newstate;
+ long copylen = 0;
+
+ /* Grab the current frame and the previous frame */
+ frame = &ibmcam->frame[ibmcam->curframe];
+
+ /* printk(KERN_DEBUG "parsing %u.\n", ibmcam->scratchlen); */
+
+ while (1) {
+
+ newstate = scan_Out;
+ if (scratch_left(data)) {
+ if (frame->scanstate == STATE_SCANNING)
+ newstate = usb_ibmcam_find_header(ibmcam);
+ else if (frame->scanstate == STATE_LINES)
+ newstate = usb_ibmcam_parse_lines(ibmcam, &copylen);
+ }
+ if (newstate == scan_Continue)
+ continue;
+ else if ((newstate == scan_NextFrame) || (newstate == scan_Out))
+ break;
+ else
+ return; /* scan_EndParse */
+ }
+
+ if (newstate == scan_NextFrame) {
+ frame->grabstate = FRAME_DONE;
+ ibmcam->curframe = -1;
+ ibmcam->frame_num++;
+
+ /* Optionally display statistics on the screen */
+ if (flags & FLAGS_OVERLAY_STATS)
+ usb_ibmcam_overlaystats(ibmcam, frame);
+
+ /* This will cause the process to request another frame. */
+ if (waitqueue_active(&frame->wq))
+ wake_up_interruptible(&frame->wq);
+ }
+
+ /* Update the frame's uncompressed length. */
+ frame->scanlength += copylen;
+}
+
+#if ENABLE_HEXDUMP
+static void ibmcam_hexdump(const unsigned char *data, int len)
+{
+ char tmp[80];
+ int i, k;
+
+ for (i=k=0; len > 0; i++, len--) {
+ if (i > 0 && (i%16 == 0)) {
+ printk("%s\n", tmp);
+ k=0;
+ }
+ k += sprintf(&tmp[k], "%02x ", data[i]);
+ }
+ if (k > 0)
+ printk("%s\n", tmp);
+}
+#endif
+
+/*
+ * Make all of the blocks of data contiguous
+ */
+static int ibmcam_compress_isochronous(struct usb_ibmcam *ibmcam, urb_t *urb)
+{
+ unsigned char *cdata, *data, *data0;
+ int i, totlen = 0;
+
+ data = data0 = ibmcam->scratch + ibmcam->scratchlen;
+ for (i = 0; i < urb->number_of_packets; i++) {
+ int n = urb->iso_frame_desc[i].actual_length;
+ int st = urb->iso_frame_desc[i].status;
+
+ cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+
+ /* Detect and ignore errored packets */
+ if (st < 0) {
+ if (debug >= 1) {
+ printk(KERN_ERR "ibmcam data error: [%d] len=%d, status=%X\n",
+ i, n, st);
+ }
+ ibmcam->iso_err_count++;
+ continue;
+ }
+
+ /* Detect and ignore empty packets */
+ if (n <= 0) {
+ ibmcam->iso_skip_count++;
+ continue;
+ }
+
+ /*
+ * If camera continues to feed us with data but there is no
+ * consumption (if, for example, V4L client fell asleep) we
+ * may overflow the buffer. We have to move old data over to
+ * free room for new data. This is bad for old data. If we
+ * just drop new data then it's bad for new data... choose
+ * your favorite evil here.
+ */
+ if ((ibmcam->scratchlen + n) > scratchbufsize) {
+#if 0
+ ibmcam->scratch_ovf_count++;
+ if (debug >= 3)
+ printk(KERN_ERR "ibmcam: scratch buf overflow! "
+ "scr_len: %d, n: %d\n", ibmcam->scratchlen, n );
+ return totlen;
+#else
+ int mv;
+
+ ibmcam->scratch_ovf_count++;
+ if (debug >= 3) {
+ printk(KERN_ERR "ibmcam: scratch buf overflow! "
+ "scr_len: %d, n: %d\n", ibmcam->scratchlen, n );
+ }
+ mv = (ibmcam->scratchlen + n) - scratchbufsize;
+ if (ibmcam->scratchlen >= mv) {
+ int newslen = ibmcam->scratchlen - mv;
+ memmove(ibmcam->scratch, ibmcam->scratch + mv, newslen);
+ ibmcam->scratchlen = newslen;
+ data = data0 = ibmcam->scratch + ibmcam->scratchlen;
+ } else {
+ printk(KERN_ERR "ibmcam: scratch buf too small\n");
+ return totlen;
+ }
+#endif
+ }
+
+ /* Now we know that there is enough room in scratch buffer */
+ memmove(data, cdata, n);
+ data += n;
+ totlen += n;
+ ibmcam->scratchlen += n;
+ }
+#if 0
+ if (totlen > 0) {
+ static int foo=0;
+ if (foo < 1) {
+ printk(KERN_DEBUG "+%d.\n", totlen);
+ ibmcam_hexdump(data0, (totlen > 64) ? 64:totlen);
+ ++foo;
+ }
+ }
+#endif
+ return totlen;
+}
+
+static void ibmcam_isoc_irq(struct urb *urb)
+{
+ int len;
+ struct usb_ibmcam *ibmcam = urb->context;
+ struct ibmcam_sbuf *sbuf;
+ int i;
+
+ /* We don't want to do anything if we are about to be removed! */
+ if (ibmcam->remove_pending)
+ return;
+
+#if 0
+ if (urb->actual_length > 0) {
+ printk(KERN_DEBUG "ibmcam_isoc_irq: %p status %d, "
+ " errcount = %d, length = %d\n", urb, urb->status,
+ urb->error_count, urb->actual_length);
+ } else {
+ static int c = 0;
+ if (c++ % 100 == 0)
+ printk(KERN_DEBUG "ibmcam_isoc_irq: no data\n");
+ }
+#endif
+
+ if (!ibmcam->streaming) {
+ if (debug >= 1)
+ printk(KERN_DEBUG "ibmcam: oops, not streaming, but interrupt\n");
+ return;
+ }
+
+ sbuf = &ibmcam->sbuf[ibmcam->cursbuf];
+
+ /* Copy the data received into our scratch buffer */
+ len = ibmcam_compress_isochronous(ibmcam, urb);
+
+ ibmcam->urb_count++;
+ ibmcam->urb_length = len;
+ ibmcam->data_count += len;
+
+#if 0 /* This code prints few initial bytes of ISO data: used to decode markers */
+ if (ibmcam->urb_count % 64 == 1) {
+ if (ibmcam->urb_count == 1) {
+ ibmcam_hexdump(ibmcam->scratch,
+ (ibmcam->scratchlen > 32) ? 32 : ibmcam->scratchlen);
+ }
+ }
+#endif
+
+ /* If we collected enough data let's parse! */
+ if (ibmcam->scratchlen) {
+ /* If we don't have a frame we're current working on, complain */
+ if (ibmcam->curframe >= 0)
+ ibmcam_parse_data(ibmcam);
+ else {
+ if (debug >= 1)
+ printk(KERN_DEBUG "ibmcam: received data, but no frame available\n");
+ }
+ }
+
+ for (i = 0; i < FRAMES_PER_DESC; i++) {
+ sbuf->urb->iso_frame_desc[i].status = 0;
+ sbuf->urb->iso_frame_desc[i].actual_length = 0;
+ }
+
+ /* Move to the next sbuf */
+ ibmcam->cursbuf = (ibmcam->cursbuf + 1) % IBMCAM_NUMSBUF;
+
+ return;
+}
+
+static int usb_ibmcam_veio(
+ struct usb_device *dev,
+ unsigned char req,
+ unsigned short value,
+ unsigned short index)
+{
+ static const char proc[] = "usb_ibmcam_veio";
+ unsigned char cp[8] = { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef };
+ const unsigned short len = sizeof(cp);
+ int i;
+
+ if (req == 1) {
+ i = usb_control_msg(
+ dev,
+ usb_rcvctrlpipe(dev, 0),
+ req,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
+ value,
+ index,
+ cp,
+ len,
+ HZ);
+#if 0
+ printk(KERN_DEBUG "USB => %02x%02x%02x%02x%02x%02x%02x%02x "
+ "(req=$%02x val=$%04x ind=$%04x len=%d.)\n",
+ cp[0],cp[1],cp[2],cp[3],cp[4],cp[5],cp[6],cp[7],
+ req, value, index, len);
+#endif
+ } else {
+ i = usb_control_msg(
+ dev,
+ usb_sndctrlpipe(dev, 0),
+ req,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT,
+ value,
+ index,
+ NULL,
+ 0,
+ HZ);
+ }
+ if (i < 0)
+ printk(KERN_ERR "%s: ERROR=%d.\n", proc, i);
+ return i;
+}
+
+/*
+ * usb_ibmcam_calculate_fps()
+ *
+ * This procedure roughly calculates the real frame rate based
+ * on FPS code (framerate=NNN option). Actual FPS differs
+ * slightly depending on lighting conditions, so that actual frame
+ * rate is determined by the camera. Since I don't know how to ask
+ * the camera what FPS is now I have to use the FPS code instead.
+ *
+ * The FPS code is in range [0..6], 0 is slowest, 6 is fastest.
+ * Corresponding real FPS should be in range [3..30] frames per second.
+ * The conversion formula is obvious:
+ *
+ * real_fps = 3 + (fps_code * 4.5)
+ *
+ * History:
+ * 1/18/00 Created.
+ */
+static int usb_ibmcam_calculate_fps(void)
+{
+ return 3 + framerate*4 + framerate/2;
+}
+
+/*
+ * usb_ibmcam_send_FF_04_02()
+ *
+ * This procedure sends magic 3-command prefix to the camera.
+ * The purpose of this prefix is not known.
+ *
+ * History:
+ * 1/2/00 Created.
+ */
+static void usb_ibmcam_send_FF_04_02(struct usb_device *dev)
+{
+ usb_ibmcam_veio(dev, 0, 0x00FF, 0x0127);
+ usb_ibmcam_veio(dev, 0, 0x0004, 0x0124);
+ usb_ibmcam_veio(dev, 0, 0x0002, 0x0124);
+}
+
+static void usb_ibmcam_send_00_04_06(struct usb_device *dev)
+{
+ usb_ibmcam_veio(dev, 0, 0x0000, 0x0127);
+ usb_ibmcam_veio(dev, 0, 0x0004, 0x0124);
+ usb_ibmcam_veio(dev, 0, 0x0006, 0x0124);
+}
+
+static void usb_ibmcam_send_x_00(struct usb_device *dev, unsigned short x)
+{
+ usb_ibmcam_veio(dev, 0, x, 0x0127);
+ usb_ibmcam_veio(dev, 0, 0x0000, 0x0124);
+}
+
+static void usb_ibmcam_send_x_00_05(struct usb_device *dev, unsigned short x)
+{
+ usb_ibmcam_send_x_00(dev, x);
+ usb_ibmcam_veio(dev, 0, 0x0005, 0x0124);
+}
+
+static void usb_ibmcam_send_x_00_05_02(struct usb_device *dev, unsigned short x)
+{
+ usb_ibmcam_veio(dev, 0, x, 0x0127);
+ usb_ibmcam_veio(dev, 0, 0x0000, 0x0124);
+ usb_ibmcam_veio(dev, 0, 0x0005, 0x0124);
+ usb_ibmcam_veio(dev, 0, 0x0002, 0x0124);
+}
+
+static void usb_ibmcam_send_x_01_00_05(struct usb_device *dev, unsigned short x)
+{
+ usb_ibmcam_veio(dev, 0, x, 0x0127);
+ usb_ibmcam_veio(dev, 0, 0x0001, 0x0124);
+ usb_ibmcam_veio(dev, 0, 0x0000, 0x0124);
+ usb_ibmcam_veio(dev, 0, 0x0005, 0x0124);
+}
+
+static void usb_ibmcam_send_x_00_05_02_01(struct usb_device *dev, unsigned short x)
+{
+ usb_ibmcam_veio(dev, 0, x, 0x0127);
+ usb_ibmcam_veio(dev, 0, 0x0000, 0x0124);
+ usb_ibmcam_veio(dev, 0, 0x0005, 0x0124);
+ usb_ibmcam_veio(dev, 0, 0x0002, 0x0124);
+ usb_ibmcam_veio(dev, 0, 0x0001, 0x0124);
+}
+
+static void usb_ibmcam_send_x_00_05_02_08_01(struct usb_device *dev, unsigned short x)
+{
+ usb_ibmcam_veio(dev, 0, x, 0x0127);
+ usb_ibmcam_veio(dev, 0, 0x0000, 0x0124);
+ usb_ibmcam_veio(dev, 0, 0x0005, 0x0124);
+ usb_ibmcam_veio(dev, 0, 0x0002, 0x0124);
+ usb_ibmcam_veio(dev, 0, 0x0008, 0x0124);
+ usb_ibmcam_veio(dev, 0, 0x0001, 0x0124);
+}
+
+static void usb_ibmcam_Packet_Format1(struct usb_device *dev, unsigned char fkey, unsigned char val)
+{
+ usb_ibmcam_send_x_01_00_05 (dev, unknown_88);
+ usb_ibmcam_send_x_00_05 (dev, fkey);
+ usb_ibmcam_send_x_00_05_02_08_01(dev, val);
+ usb_ibmcam_send_x_00_05 (dev, unknown_88);
+ usb_ibmcam_send_x_00_05_02_01 (dev, fkey);
+ usb_ibmcam_send_x_00_05 (dev, unknown_89);
+ usb_ibmcam_send_x_00 (dev, fkey);
+ usb_ibmcam_send_00_04_06 (dev);
+ usb_ibmcam_veio (dev, 1, 0x0000, 0x0126);
+ usb_ibmcam_send_FF_04_02 (dev);
+}
+
+static void usb_ibmcam_PacketFormat2(struct usb_device *dev, unsigned char fkey, unsigned char val)
+{
+ usb_ibmcam_send_x_01_00_05 (dev, unknown_88);
+ usb_ibmcam_send_x_00_05 (dev, fkey);
+ usb_ibmcam_send_x_00_05_02 (dev, val);
+}
+
+/*
+ * usb_ibmcam_adjust_contrast()
+ *
+ * The contrast value changes from 0 (high contrast) to 15 (low contrast).
+ * This is in reverse to usual order of things (such as TV controls), so
+ * we reverse it again here.
+ *
+ * TODO: we probably don't need to send the setup 5 times...
+ *
+ * History:
+ * 1/2/00 Created.
+ */
+static void usb_ibmcam_adjust_contrast(struct usb_ibmcam *ibmcam)
+{
+ struct usb_device *dev = ibmcam->dev;
+ unsigned char new_contrast = ibmcam->vpic.contrast >> 12;
+ const int ntries = 5;
+
+ if (new_contrast >= 16)
+ new_contrast = 15;
+ new_contrast = 15 - new_contrast;
+ if (new_contrast != ibmcam->vpic_old.contrast) {
+ int i;
+ ibmcam->vpic_old.contrast = new_contrast;
+ for (i=0; i < ntries; i++) {
+ usb_ibmcam_Packet_Format1(dev, contrast_14, new_contrast);
+ usb_ibmcam_send_FF_04_02(dev);
+ }
+ /*usb_ibmcam_veio(dev, 0, 0x00FF, 0x0127);*/
+ }
+}
+
+/*
+ * usb_ibmcam_change_lighting_conditions()
+ *
+ * We have 3 levels of lighting conditions: 0=Bright, 1=Medium, 2=Low.
+ * Low lighting forces slower FPS. Lighting is set as a module parameter.
+ *
+ * History:
+ * 1/5/00 Created.
+ */
+static void usb_ibmcam_change_lighting_conditions(struct usb_ibmcam *ibmcam)
+{
+ static const char proc[] = "usb_ibmcam_change_lighting_conditions";
+ struct usb_device *dev = ibmcam->dev;
+ const int ntries = 5;
+ int i;
+
+ RESTRICT_TO_RANGE(lighting, LIGHTING_MIN, LIGHTING_MAX);
+ if (debug > 0)
+ printk(KERN_INFO "%s: Set lighting to %hu.\n", proc, lighting);
+
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, light_27, (unsigned short) lighting);
+}
+
+static void usb_ibmcam_set_sharpness(struct usb_ibmcam *ibmcam)
+{
+ static const char proc[] = "usb_ibmcam_set_sharpness";
+ struct usb_device *dev = ibmcam->dev;
+ static const unsigned short sa[] = { 0x11, 0x13, 0x16, 0x18, 0x1a, 0x8, 0x0a };
+ unsigned short i, sv;
+
+ RESTRICT_TO_RANGE(sharpness, SHARPNESS_MIN, SHARPNESS_MAX);
+ if (debug > 0)
+ printk(KERN_INFO "%s: Set sharpness to %hu.\n", proc, sharpness);
+
+ sv = sa[sharpness - SHARPNESS_MIN];
+ for (i=0; i < 2; i++) {
+ usb_ibmcam_send_x_01_00_05 (dev, unknown_88);
+ usb_ibmcam_send_x_00_05 (dev, sharp_13);
+ usb_ibmcam_send_x_00_05_02 (dev, sv);
+ }
+}
+
+static void usb_ibmcam_set_brightness(struct usb_ibmcam *ibmcam)
+{
+ static const char proc[] = "usb_ibmcam_set_brightness";
+ struct usb_device *dev = ibmcam->dev;
+ static const unsigned short n = 1;
+ unsigned short i, j, bv[3];
+
+ bv[0] = bv[1] = bv[2] = ibmcam->vpic.brightness >> 10;
+ if (bv[0] == (ibmcam->vpic_old.brightness >> 10))
+ return;
+ ibmcam->vpic_old.brightness = ibmcam->vpic.brightness;
+
+ if (debug > 0)
+ printk(KERN_INFO "%s: Set brightness to (%hu,%hu,%hu)\n",
+ proc, bv[0], bv[1], bv[2]);
+
+ for (j=0; j < 3; j++)
+ for (i=0; i < n; i++)
+ usb_ibmcam_Packet_Format1(dev, bright_3x[j], bv[j]);
+}
+
+static void usb_ibmcam_adjust_picture(struct usb_ibmcam *ibmcam)
+{
+ usb_ibmcam_adjust_contrast(ibmcam);
+ usb_ibmcam_set_brightness(ibmcam);
+}
+
+static int usb_ibmcam_setup(struct usb_ibmcam *ibmcam)
+{
+ struct usb_device *dev = ibmcam->dev;
+ const int ntries = 5;
+ int i;
+
+ usb_ibmcam_veio(dev, 1, 0, 0x128);
+ usb_ibmcam_veio(dev, 1, 0x00, 0x0100);
+ usb_ibmcam_veio(dev, 0, 0x01, 0x0100); /* LED On */
+ usb_ibmcam_veio(dev, 1, 0x00, 0x0100);
+ usb_ibmcam_veio(dev, 0, 0x81, 0x0100); /* LED Off */
+ usb_ibmcam_veio(dev, 1, 0x00, 0x0100);
+ usb_ibmcam_veio(dev, 0, 0x01, 0x0100); /* LED On */
+ usb_ibmcam_veio(dev, 0, 0x01, 0x0108);
+
+ usb_ibmcam_veio(dev, 0, 0x03, 0x0112);
+ usb_ibmcam_veio(dev, 1, 0x00, 0x0115);
+ usb_ibmcam_veio(dev, 0, 0x06, 0x0115);
+ usb_ibmcam_veio(dev, 1, 0x00, 0x0116);
+ usb_ibmcam_veio(dev, 0, 0x44, 0x0116);
+ usb_ibmcam_veio(dev, 1, 0x00, 0x0116);
+ usb_ibmcam_veio(dev, 0, 0x40, 0x0116);
+ usb_ibmcam_veio(dev, 1, 0x00, 0x0115);
+ usb_ibmcam_veio(dev, 0, 0x0e, 0x0115);
+ usb_ibmcam_veio(dev, 0, 0x19, 0x012c);
+
+ usb_ibmcam_Packet_Format1(dev, 0x00, 0x1e);
+ usb_ibmcam_Packet_Format1(dev, 0x39, 0x0d);
+ usb_ibmcam_Packet_Format1(dev, 0x39, 0x09);
+ usb_ibmcam_Packet_Format1(dev, 0x3b, 0x00);
+ usb_ibmcam_Packet_Format1(dev, 0x28, 0x22);
+ usb_ibmcam_Packet_Format1(dev, light_27, 0);
+ usb_ibmcam_Packet_Format1(dev, 0x2b, 0x1f);
+ usb_ibmcam_Packet_Format1(dev, 0x39, 0x08);
+
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, 0x2c, 0x00);
+
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, 0x30, 0x14);
+
+ usb_ibmcam_PacketFormat2(dev, 0x39, 0x02);
+ usb_ibmcam_PacketFormat2(dev, 0x01, 0xe1);
+ usb_ibmcam_PacketFormat2(dev, 0x02, 0xcd);
+ usb_ibmcam_PacketFormat2(dev, 0x03, 0xcd);
+ usb_ibmcam_PacketFormat2(dev, 0x04, 0xfa);
+ usb_ibmcam_PacketFormat2(dev, 0x3f, 0xff);
+ usb_ibmcam_PacketFormat2(dev, 0x39, 0x00);
+
+ usb_ibmcam_PacketFormat2(dev, 0x39, 0x02);
+ usb_ibmcam_PacketFormat2(dev, 0x0a, 0x37);
+ usb_ibmcam_PacketFormat2(dev, 0x0b, 0xb8);
+ usb_ibmcam_PacketFormat2(dev, 0x0c, 0xf3);
+ usb_ibmcam_PacketFormat2(dev, 0x0d, 0xe3);
+ usb_ibmcam_PacketFormat2(dev, 0x0e, 0x0d);
+ usb_ibmcam_PacketFormat2(dev, 0x0f, 0xf2);
+ usb_ibmcam_PacketFormat2(dev, 0x10, 0xd5);
+ usb_ibmcam_PacketFormat2(dev, 0x11, 0xba);
+ usb_ibmcam_PacketFormat2(dev, 0x12, 0x53);
+ usb_ibmcam_PacketFormat2(dev, 0x3f, 0xff);
+ usb_ibmcam_PacketFormat2(dev, 0x39, 0x00);
+
+ usb_ibmcam_PacketFormat2(dev, 0x39, 0x02);
+ usb_ibmcam_PacketFormat2(dev, 0x16, 0x00);
+ usb_ibmcam_PacketFormat2(dev, 0x17, 0x28);
+ usb_ibmcam_PacketFormat2(dev, 0x18, 0x7d);
+ usb_ibmcam_PacketFormat2(dev, 0x19, 0xbe);
+ usb_ibmcam_PacketFormat2(dev, 0x3f, 0xff);
+ usb_ibmcam_PacketFormat2(dev, 0x39, 0x00);
+
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, 0x00, 0x18);
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, 0x13, 0x18);
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, 0x14, 0x06);
+
+ /* This is default brightness */
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, 0x31, 0x37);
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, 0x32, 0x46);
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, 0x33, 0x55);
+
+ usb_ibmcam_Packet_Format1(dev, 0x2e, 0x04);
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, 0x2d, 0x04);
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, 0x29, 0x80);
+ usb_ibmcam_Packet_Format1(dev, 0x2c, 0x01);
+ usb_ibmcam_Packet_Format1(dev, 0x30, 0x17);
+ usb_ibmcam_Packet_Format1(dev, 0x39, 0x08);
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, 0x34, 0x00);
+
+ usb_ibmcam_veio(dev, 0, 0x00, 0x0101);
+ usb_ibmcam_veio(dev, 0, 0x00, 0x010a);
+
+ switch (videosize) {
+ case VIDEOSIZE_128x96:
+ usb_ibmcam_veio(dev, 0, 0x80, 0x0103);
+ usb_ibmcam_veio(dev, 0, 0x60, 0x0105);
+ usb_ibmcam_veio(dev, 0, 0x0c, 0x010b);
+ usb_ibmcam_veio(dev, 0, 0x04, 0x011b); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x0b, 0x011d);
+ usb_ibmcam_veio(dev, 0, 0x00, 0x011e); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x00, 0x0129);
+ break;
+ case VIDEOSIZE_176x144:
+ usb_ibmcam_veio(dev, 0, 0xb0, 0x0103);
+ usb_ibmcam_veio(dev, 0, 0x8f, 0x0105);
+ usb_ibmcam_veio(dev, 0, 0x06, 0x010b);
+ usb_ibmcam_veio(dev, 0, 0x04, 0x011b); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x0d, 0x011d);
+ usb_ibmcam_veio(dev, 0, 0x00, 0x011e); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x03, 0x0129);
+ break;
+ case VIDEOSIZE_352x288:
+ usb_ibmcam_veio(dev, 0, 0xb0, 0x0103);
+ usb_ibmcam_veio(dev, 0, 0x90, 0x0105);
+ usb_ibmcam_veio(dev, 0, 0x02, 0x010b);
+ usb_ibmcam_veio(dev, 0, 0x04, 0x011b); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x05, 0x011d);
+ usb_ibmcam_veio(dev, 0, 0x00, 0x011e); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x00, 0x0129);
+ break;
+ }
+
+ usb_ibmcam_veio(dev, 0, 0xff, 0x012b);
+
+ /* This is another brightness - don't know why */
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, 0x31, 0xc3);
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, 0x32, 0xd2);
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, 0x33, 0xe1);
+
+ /* Default contrast */
+ for (i=0; i < ntries; i++)
+ usb_ibmcam_Packet_Format1(dev, contrast_14, 0x0a);
+
+ /* Default sharpness */
+ for (i=0; i < 2; i++)
+ usb_ibmcam_PacketFormat2(dev, sharp_13, 0x1a); /* Level 4 FIXME */
+
+ /* Default lighting conditions */
+ usb_ibmcam_Packet_Format1(dev, light_27, lighting); /* 0=Bright 2=Low */
+
+ /* Assorted init */
+
+ switch (videosize) {
+ case VIDEOSIZE_128x96:
+ usb_ibmcam_Packet_Format1(dev, 0x2b, 0x1e);
+ usb_ibmcam_veio(dev, 0, 0xc9, 0x0119); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x80, 0x0109); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x36, 0x0102);
+ usb_ibmcam_veio(dev, 0, 0x1a, 0x0104);
+ usb_ibmcam_veio(dev, 0, 0x04, 0x011a); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x2b, 0x011c);
+ usb_ibmcam_veio(dev, 0, 0x23, 0x012a); /* Same everywhere */
+#if 0
+ usb_ibmcam_veio(dev, 0, 0x00, 0x0106);
+ usb_ibmcam_veio(dev, 0, 0x38, 0x0107);
+#else
+ usb_ibmcam_veio(dev, 0, 0x02, 0x0106);
+ usb_ibmcam_veio(dev, 0, 0x2a, 0x0107);
+#endif
+ break;
+ case VIDEOSIZE_176x144:
+ usb_ibmcam_Packet_Format1(dev, 0x2b, 0x1e);
+ usb_ibmcam_veio(dev, 0, 0xc9, 0x0119); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x80, 0x0109); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x04, 0x0102);
+ usb_ibmcam_veio(dev, 0, 0x02, 0x0104);
+ usb_ibmcam_veio(dev, 0, 0x04, 0x011a); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x2b, 0x011c);
+ usb_ibmcam_veio(dev, 0, 0x23, 0x012a); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x01, 0x0106);
+ usb_ibmcam_veio(dev, 0, 0xca, 0x0107);
+ break;
+ case VIDEOSIZE_352x288:
+ usb_ibmcam_Packet_Format1(dev, 0x2b, 0x1f);
+ usb_ibmcam_veio(dev, 0, 0xc9, 0x0119); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x80, 0x0109); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x08, 0x0102);
+ usb_ibmcam_veio(dev, 0, 0x01, 0x0104);
+ usb_ibmcam_veio(dev, 0, 0x04, 0x011a); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x2f, 0x011c);
+ usb_ibmcam_veio(dev, 0, 0x23, 0x012a); /* Same everywhere */
+ usb_ibmcam_veio(dev, 0, 0x03, 0x0106);
+ usb_ibmcam_veio(dev, 0, 0xf6, 0x0107);
+ break;
+ }
+ return 0; /* TODO: return actual completion status! */
+}
+
+/*
+ * usb_ibmcam_setup_after_video_if()
+ *
+ * This code adds finishing touches to the video data interface.
+ * Here we configure the frame rate and turn on the LED.
+ */
+static void usb_ibmcam_setup_after_video_if(struct usb_device *dev)
+{
+ unsigned short internal_frame_rate;
+
+ RESTRICT_TO_RANGE(framerate, FRAMERATE_MIN, FRAMERATE_MAX);
+ internal_frame_rate = FRAMERATE_MAX - framerate; /* 0=Fast 6=Slow */
+ usb_ibmcam_veio(dev, 0, 0x01, 0x0100); /* LED On */
+ usb_ibmcam_veio(dev, 0, internal_frame_rate, 0x0111);
+ usb_ibmcam_veio(dev, 0, 0x01, 0x0114);
+ usb_ibmcam_veio(dev, 0, 0xc0, 0x010c);
+}
+
+/*
+ * usb_ibmcam_setup_video_stop()
+ *
+ * This code tells camera to stop streaming. The interface remains
+ * configured and bandwidth - claimed.
+ */
+static void usb_ibmcam_setup_video_stop(struct usb_device *dev)
+{
+ usb_ibmcam_veio(dev, 0, 0x00, 0x010c);
+ usb_ibmcam_veio(dev, 0, 0x00, 0x010c);
+ usb_ibmcam_veio(dev, 0, 0x01, 0x0114);
+ usb_ibmcam_veio(dev, 0, 0xc0, 0x010c);
+ usb_ibmcam_veio(dev, 0, 0x00, 0x010c);
+ usb_ibmcam_send_FF_04_02(dev);
+ usb_ibmcam_veio(dev, 1, 0x00, 0x0100);
+ usb_ibmcam_veio(dev, 0, 0x81, 0x0100); /* LED Off */
+}
+
+/*
+ * usb_ibmcam_reinit_iso()
+ *
+ * This procedure sends couple of commands to the camera and then
+ * resets the video pipe. This sequence was observed to reinit the
+ * camera or, at least, to initiate ISO data stream.
+ *
+ * History:
+ * 1/2/00 Created.
+ */
+static void usb_ibmcam_reinit_iso(struct usb_ibmcam *ibmcam, int do_stop)
+{
+ if (do_stop)
+ usb_ibmcam_setup_video_stop(ibmcam->dev);
+
+ usb_ibmcam_veio(ibmcam->dev, 0, 0x0001, 0x0114);
+ usb_ibmcam_veio(ibmcam->dev, 0, 0x00c0, 0x010c);
+ usb_clear_halt(ibmcam->dev, ibmcam->video_endp);
+ usb_ibmcam_setup_after_video_if(ibmcam->dev);
+}
+
+static int ibmcam_init_isoc(struct usb_ibmcam *ibmcam)
+{
+ struct usb_device *dev = ibmcam->dev;
+ urb_t *urb;
+ int fx, err;
+
+ ibmcam->compress = 0;
+ ibmcam->curframe = -1;
+ ibmcam->cursbuf = 0;
+ ibmcam->scratchlen = 0;
+
+ /* Alternate interface 1 is is the biggest frame size */
+ if (usb_set_interface(ibmcam->dev, 2, 1) < 0) {
+ printk(KERN_ERR "usb_set_interface error\n");
+ return -EBUSY;
+ }
+ usb_ibmcam_change_lighting_conditions(ibmcam);
+ usb_ibmcam_set_sharpness(ibmcam);
+ usb_ibmcam_reinit_iso(ibmcam, 0);
+
+ /* We double buffer the Iso lists */
+ urb = usb_alloc_urb(FRAMES_PER_DESC);
+
+ if (!urb) {
+ printk(KERN_ERR "ibmcam_init_isoc: usb_init_isoc ret %d\n",
+ 0);
+ return -ENOMEM;
+ }
+ ibmcam->sbuf[0].urb = urb;
+ urb->dev = dev;
+ urb->context = ibmcam;
+ urb->pipe = usb_rcvisocpipe(dev, ibmcam->video_endp);
+ urb->transfer_flags = USB_ISO_ASAP;
+ urb->transfer_buffer = ibmcam->sbuf[0].data;
+ urb->complete = ibmcam_isoc_irq;
+ urb->number_of_packets = FRAMES_PER_DESC;
+ urb->transfer_buffer_length = ibmcam->iso_packet_len * FRAMES_PER_DESC;
+ for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
+ urb->iso_frame_desc[fx].offset = ibmcam->iso_packet_len * fx;
+ urb->iso_frame_desc[fx].length = ibmcam->iso_packet_len;
+ }
+ urb = usb_alloc_urb(FRAMES_PER_DESC);
+ if (!urb) {
+ printk(KERN_ERR "ibmcam_init_isoc: usb_init_isoc ret %d\n",
+ 0);
+ return -ENOMEM;
+ }
+ ibmcam->sbuf[1].urb = urb;
+ urb->dev = dev;
+ urb->context = ibmcam;
+ urb->pipe = usb_rcvisocpipe(dev, ibmcam->video_endp);
+ urb->transfer_flags = USB_ISO_ASAP;
+ urb->transfer_buffer = ibmcam->sbuf[1].data;
+ urb->complete = ibmcam_isoc_irq;
+ urb->number_of_packets = FRAMES_PER_DESC;
+ urb->transfer_buffer_length = ibmcam->iso_packet_len * FRAMES_PER_DESC;
+ for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
+ urb->iso_frame_desc[fx].offset = ibmcam->iso_packet_len * fx;
+ urb->iso_frame_desc[fx].length = ibmcam->iso_packet_len;
+ }
+
+ ibmcam->sbuf[1].urb->next = ibmcam->sbuf[0].urb;
+ ibmcam->sbuf[0].urb->next = ibmcam->sbuf[1].urb;
+
+ err = usb_submit_urb(ibmcam->sbuf[0].urb);
+ if (err)
+ printk(KERN_ERR "ibmcam_init_isoc: usb_run_isoc(0) ret %d\n",
+ err);
+ err = usb_submit_urb(ibmcam->sbuf[1].urb);
+ if (err)
+ printk(KERN_ERR "ibmcam_init_isoc: usb_run_isoc(1) ret %d\n",
+ err);
+
+ ibmcam->streaming = 1;
+ // printk(KERN_DEBUG "streaming=1 ibmcam->video_endp=$%02x\n", ibmcam->video_endp);
+ return 0;
+}
+
+/*
+ * ibmcam_stop_isoc()
+ *
+ * This procedure stops streaming and deallocates URBs. Then it
+ * activates zero-bandwidth alt. setting of the video interface.
+ *
+ * History:
+ * 1/22/00 Corrected order of actions to work after surprise removal.
+ */
+static void ibmcam_stop_isoc(struct usb_ibmcam *ibmcam)
+{
+ if (!ibmcam->streaming)
+ return;
+
+ /* Unschedule all of the iso td's */
+ usb_unlink_urb(ibmcam->sbuf[1].urb);
+ usb_unlink_urb(ibmcam->sbuf[0].urb);
+
+ /* printk(KERN_DEBUG "streaming=0\n"); */
+ ibmcam->streaming = 0;
+
+ /* Delete them all */
+ usb_free_urb(ibmcam->sbuf[1].urb);
+ usb_free_urb(ibmcam->sbuf[0].urb);
+
+ usb_ibmcam_setup_video_stop(ibmcam->dev);
+
+ /* Set packet size to 0 */
+ if (usb_set_interface(ibmcam->dev, 2, 0) < 0)
+ printk(KERN_ERR "usb_set_interface error\n");
+}
+
+static int ibmcam_new_frame(struct usb_ibmcam *ibmcam, int framenum)
+{
+ struct ibmcam_frame *frame;
+ int n, width, height;
+
+ /* If we're not grabbing a frame right now and the other frame is */
+ /* ready to be grabbed into, then use it instead */
+ if (ibmcam->curframe != -1)
+ return 0;
+
+ n = (framenum - 1 + IBMCAM_NUMFRAMES) % IBMCAM_NUMFRAMES;
+ if (ibmcam->frame[n].grabstate == FRAME_READY)
+ framenum = n;
+
+ frame = &ibmcam->frame[framenum];
+
+ frame->grabstate = FRAME_GRABBING;
+ frame->scanstate = STATE_SCANNING;
+ frame->scanlength = 0; /* Accumulated in ibmcam_parse_data() */
+ ibmcam->curframe = framenum;
+#if 0
+ /* This provides a "clean" frame but slows things down */
+ memset(frame->data, 0, MAX_FRAME_SIZE);
+#endif
+ switch (videosize) {
+ case VIDEOSIZE_128x96:
+ frame->frmwidth = 128;
+ frame->frmheight = 96;
+ frame->order_uv = 1; /* U Y V Y ... */
+ frame->hdr_sig = 0x06; /* 00 FF 00 06 */
+ break;
+ case VIDEOSIZE_176x144:
+ frame->frmwidth = 176;
+ frame->frmheight = 144;
+ frame->order_uv = 1; /* U Y V Y ... */
+ frame->hdr_sig = 0x0E; /* 00 FF 00 0E */
+ break;
+ case VIDEOSIZE_352x288:
+ frame->frmwidth = 352;
+ frame->frmheight = 288;
+ frame->order_uv = 0; /* V Y U Y ... */
+ frame->hdr_sig = 0x00; /* 00 FF 00 00 */
+ break;
+ }
+
+ width = frame->width;
+ RESTRICT_TO_RANGE(width, min_imgwidth, imgwidth);
+ width &= ~7; /* Multiple of 8 */
+
+ height = frame->height;
+ RESTRICT_TO_RANGE(height, min_imgheight, imgheight);
+ height &= ~3; /* Multiple of 4 */
+
+ return 0;
+}
+
+/*
+ * ibmcam_open()
+ *
+ * This is part of Video 4 Linux API. The driver can be opened by one
+ * client only (checks internal counter 'ibmcam->user'). The procedure
+ * then allocates buffers needed for video processing.
+ *
+ * History:
+ * 1/22/00 Rewrote, moved scratch buffer allocation here. Now the
+ * camera is also initialized here (once per connect), at
+ * expense of V4L client (it waits on open() call).
+ */
+static int ibmcam_open(struct video_device *dev, int flags)
+{
+ struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev;
+ const int nbuffers = 2;
+ const int sb_size = FRAMES_PER_DESC * ibmcam->iso_packet_len;
+ int i, err = 0;
+
+ down(&ibmcam->lock);
+
+ if (ibmcam->user)
+ err = -EBUSY;
+ else {
+ /* Clean pointers so we know if we allocated something */
+ for (i=0; i < nbuffers; i++)
+ ibmcam->sbuf[i].data = NULL;
+
+ /* Allocate memory for the frame buffers */
+ ibmcam->fbuf_size = nbuffers * MAX_FRAME_SIZE;
+ ibmcam->fbuf = rvmalloc(ibmcam->fbuf_size);
+ ibmcam->scratch = kmalloc(scratchbufsize, GFP_KERNEL);
+ ibmcam->scratchlen = 0;
+ if ((ibmcam->fbuf == NULL) || (ibmcam->scratch == NULL))
+ err = -ENOMEM;
+ else {
+ /* Allocate all buffers */
+ for (i=0; i < nbuffers; i++) {
+ ibmcam->frame[i].grabstate = FRAME_UNUSED;
+ ibmcam->frame[i].data = ibmcam->fbuf + i*MAX_FRAME_SIZE;
+
+ ibmcam->sbuf[i].data = kmalloc(sb_size, GFP_KERNEL);
+ if (ibmcam->sbuf[i].data == NULL) {
+ err = -ENOMEM;
+ break;
+ }
+ /*
+ * Set default sizes in case IOCTL (VIDIOCMCAPTURE)
+ * is not used (using read() instead).
+ */
+ ibmcam->frame[i].width = imgwidth;
+ ibmcam->frame[i].height = imgheight;
+ ibmcam->frame[i].bytes_read = 0;
+ }
+ }
+ if (err) {
+ /* Have to free all that memory */
+ if (ibmcam->fbuf != NULL) {
+ rvfree(ibmcam->fbuf, ibmcam->fbuf_size);
+ ibmcam->fbuf = NULL;
+ }
+ if (ibmcam->scratch != NULL) {
+ kfree(ibmcam->scratch);
+ ibmcam->scratch = NULL;
+ }
+ for (i=0; i < nbuffers; i++) {
+ if (ibmcam->sbuf[i].data != NULL) {
+ kfree (ibmcam->sbuf[i].data);
+ ibmcam->sbuf[i].data = NULL;
+ }
+ }
+ }
+ }
+
+ /* If so far no errors then we shall start the camera */
+ if (!err) {
+ err = ibmcam_init_isoc(ibmcam);
+ if (!err) {
+ /* Send init sequence only once, it's large! */
+ if (!ibmcam->initialized) {
+ err = usb_ibmcam_setup(ibmcam);
+ if (!err)
+ ibmcam->initialized = 1;
+ }
+ if (!err) {
+ ibmcam->user++;
+ MOD_INC_USE_COUNT;
+ }
+ }
+ }
+
+ up(&ibmcam->lock);
+ return err;
+}
+
+/*
+ * ibmcam_close()
+ *
+ * This is part of Video 4 Linux API. The procedure
+ * stops streaming and deallocates all buffers that were earlier
+ * allocated in ibmcam_open().
+ *
+ * History:
+ * 1/22/00 Moved scratch buffer deallocation here.
+ */
+static void ibmcam_close(struct video_device *dev)
+{
+ struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev;
+
+ down(&ibmcam->lock);
+
+ ibmcam_stop_isoc(ibmcam);
+
+ rvfree(ibmcam->fbuf, ibmcam->fbuf_size);
+ kfree(ibmcam->scratch);
+ kfree(ibmcam->sbuf[1].data);
+ kfree(ibmcam->sbuf[0].data);
+
+ ibmcam->user--;
+ MOD_DEC_USE_COUNT;
+
+ up(&ibmcam->lock);
+}
+
+static int ibmcam_init_done(struct video_device *dev)
+{
+ return 0;
+}
+
+static long ibmcam_write(struct video_device *dev, const char *buf, unsigned long count, int noblock)
+{
+ return -EINVAL;
+}
+
+/*
+ * ibmcam_ioctl()
+ *
+ * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
+ *
+ * History:
+ * 1/22/00 Corrected VIDIOCSPICT to reject unsupported settings.
+ */
+static int ibmcam_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+ struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev;
+
+ if (ibmcam->remove_pending)
+ return -EFAULT;
+
+ switch (cmd) {
+ case VIDIOCGCAP:
+ {
+ if (copy_to_user(arg, &ibmcam->vcap, sizeof(ibmcam->vcap)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCGCHAN:
+ {
+ if (copy_to_user(arg, &ibmcam->vchan, sizeof(ibmcam->vchan)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCSCHAN:
+ {
+ int v;
+
+ if (copy_from_user(&v, arg, sizeof(v)))
+ return -EFAULT;
+ if ((v < 0) || (v >= 3)) /* 3 grades of lighting conditions */
+ return -EINVAL;
+ if (v != ibmcam->vchan.channel) {
+ ibmcam->vchan.channel = v;
+ usb_ibmcam_change_lighting_conditions(ibmcam);
+ }
+ return 0;
+ }
+ case VIDIOCGPICT:
+ {
+ if (copy_to_user(arg, &ibmcam->vpic, sizeof(ibmcam->vpic)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCSPICT:
+ {
+ struct video_picture tmp;
+ /*
+ * Use temporary 'video_picture' structure to preserve our
+ * own settings (such as color depth, palette) that we
+ * aren't allowing everyone (V4L client) to change.
+ */
+ if (copy_from_user(&tmp, arg, sizeof(tmp)))
+ return -EFAULT;
+ ibmcam->vpic.brightness = tmp.brightness;
+ ibmcam->vpic.hue = tmp.hue;
+ ibmcam->vpic.colour = tmp.colour;
+ ibmcam->vpic.contrast = tmp.contrast;
+ usb_ibmcam_adjust_picture(ibmcam);
+ return 0;
+ }
+ case VIDIOCSWIN:
+ {
+ struct video_window vw;
+
+ if (copy_from_user(&vw, arg, sizeof(vw)))
+ return -EFAULT;
+ if (vw.flags)
+ return -EINVAL;
+ if (vw.clipcount)
+ return -EINVAL;
+ if (vw.height != imgheight)
+ return -EINVAL;
+ if (vw.width != imgwidth)
+ return -EINVAL;
+
+ ibmcam->compress = 0;
+
+ return 0;
+ }
+ case VIDIOCGWIN:
+ {
+ struct video_window vw;
+
+ vw.x = 0;
+ vw.y = 0;
+ vw.width = imgwidth;
+ vw.height = imgheight;
+ vw.chromakey = 0;
+ vw.flags = usb_ibmcam_calculate_fps();
+
+ if (copy_to_user(arg, &vw, sizeof(vw)))
+ return -EFAULT;
+
+ return 0;
+ }
+ case VIDIOCGMBUF:
+ {
+ struct video_mbuf vm;
+
+ memset(&vm, 0, sizeof(vm));
+ vm.size = MAX_FRAME_SIZE * 2;
+ vm.frames = 2;
+ vm.offsets[0] = 0;
+ vm.offsets[1] = MAX_FRAME_SIZE;
+
+ if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
+ return -EFAULT;
+
+ return 0;
+ }
+ case VIDIOCMCAPTURE:
+ {
+ struct video_mmap vm;
+
+ if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm)))
+ return -EFAULT;
+
+ if (debug >= 1)
+ printk(KERN_DEBUG "frame: %d, size: %dx%d, format: %d\n",
+ vm.frame, vm.width, vm.height, vm.format);
+
+ if (vm.format != VIDEO_PALETTE_RGB24)
+ return -EINVAL;
+
+ if ((vm.frame != 0) && (vm.frame != 1))
+ return -EINVAL;
+
+ if (ibmcam->frame[vm.frame].grabstate == FRAME_GRABBING)
+ return -EBUSY;
+
+ /* Don't compress if the size changed */
+ if ((ibmcam->frame[vm.frame].width != vm.width) ||
+ (ibmcam->frame[vm.frame].height != vm.height))
+ ibmcam->compress = 0;
+
+ ibmcam->frame[vm.frame].width = vm.width;
+ ibmcam->frame[vm.frame].height = vm.height;
+
+ /* Mark it as ready */
+ ibmcam->frame[vm.frame].grabstate = FRAME_READY;
+
+ return ibmcam_new_frame(ibmcam, vm.frame);
+ }
+ case VIDIOCSYNC:
+ {
+ int frame;
+
+ if (copy_from_user((void *)&frame, arg, sizeof(int)))
+ return -EFAULT;
+
+ if (debug >= 1)
+ printk(KERN_DEBUG "ibmcam: syncing to frame %d\n", frame);
+
+ switch (ibmcam->frame[frame].grabstate) {
+ case FRAME_UNUSED:
+ return -EINVAL;
+ case FRAME_READY:
+ case FRAME_GRABBING:
+ case FRAME_ERROR:
+ {
+ int ntries;
+ redo:
+ ntries = 0;
+ do {
+ interruptible_sleep_on(&ibmcam->frame[frame].wq);
+ if (signal_pending(current)) {
+ if (flags & FLAGS_RETRY_VIDIOCSYNC) {
+ /* Polling apps will destroy frames with that! */
+ ibmcam_new_frame(ibmcam, frame);
+ usb_ibmcam_testpattern(ibmcam, 1, 0);
+ ibmcam->curframe = -1;
+ ibmcam->frame_num++;
+
+ /* This will request another frame. */
+ if (waitqueue_active(&ibmcam->frame[frame].wq))
+ wake_up_interruptible(&ibmcam->frame[frame].wq);
+ return 0;
+ } else {
+ /* Standard answer: not ready yet! */
+ return -EINTR;
+ }
+ }
+ } while (ibmcam->frame[frame].grabstate == FRAME_GRABBING);
+
+ if (ibmcam->frame[frame].grabstate == FRAME_ERROR) {
+ int ret = ibmcam_new_frame(ibmcam, frame);
+ if (ret < 0)
+ return ret;
+ goto redo;
+ }
+ }
+ case FRAME_DONE:
+ ibmcam->frame[frame].grabstate = FRAME_UNUSED;
+ break;
+ }
+
+ ibmcam->frame[frame].grabstate = FRAME_UNUSED;
+
+ return 0;
+ }
+ case VIDIOCGFBUF:
+ {
+ struct video_buffer vb;
+
+ memset(&vb, 0, sizeof(vb));
+ vb.base = NULL; /* frame buffer not supported, not used */
+
+ if (copy_to_user((void *)arg, (void *)&vb, sizeof(vb)))
+ return -EFAULT;
+
+ return 0;
+ }
+ case VIDIOCKEY:
+ return 0;
+
+ case VIDIOCCAPTURE:
+ return -EINVAL;
+
+ case VIDIOCSFBUF:
+
+ case VIDIOCGTUNER:
+ case VIDIOCSTUNER:
+
+ case VIDIOCGFREQ:
+ case VIDIOCSFREQ:
+
+ case VIDIOCGAUDIO:
+ case VIDIOCSAUDIO:
+ return -EINVAL;
+
+ default:
+ return -ENOIOCTLCMD;
+ }
+ return 0;
+}
+
+static long ibmcam_read(struct video_device *dev, char *buf, unsigned long count, int noblock)
+{
+ struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev;
+ int frmx = -1;
+ volatile struct ibmcam_frame *frame;
+
+ if (debug >= 1)
+ printk(KERN_DEBUG "ibmcam_read: %ld bytes, noblock=%d\n", count, noblock);
+
+ if (ibmcam->remove_pending)
+ return -EFAULT;
+
+ if (!dev || !buf)
+ return -EFAULT;
+
+ /* See if a frame is completed, then use it. */
+ if (ibmcam->frame[0].grabstate >= FRAME_DONE) /* _DONE or _ERROR */
+ frmx = 0;
+ else if (ibmcam->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */
+ frmx = 1;
+
+ if (noblock && (frmx == -1))
+ return -EAGAIN;
+
+ /* If no FRAME_DONE, look for a FRAME_GRABBING state. */
+ /* See if a frame is in process (grabbing), then use it. */
+ if (frmx == -1) {
+ if (ibmcam->frame[0].grabstate == FRAME_GRABBING)
+ frmx = 0;
+ else if (ibmcam->frame[1].grabstate == FRAME_GRABBING)
+ frmx = 1;
+ }
+
+ /* If no frame is active, start one. */
+ if (frmx == -1)
+ ibmcam_new_frame(ibmcam, frmx = 0);
+
+ frame = &ibmcam->frame[frmx];
+
+restart:
+ while (frame->grabstate == FRAME_GRABBING) {
+ interruptible_sleep_on((void *)&frame->wq);
+ if (signal_pending(current))
+ return -EINTR;
+ }
+
+ if (frame->grabstate == FRAME_ERROR) {
+ frame->bytes_read = 0;
+ if (ibmcam_new_frame(ibmcam, frmx))
+ printk(KERN_ERR "ibmcam_read: ibmcam_new_frame error\n");
+ goto restart;
+ }
+
+ if (debug >= 1)
+ printk(KERN_DEBUG "ibmcam_read: frmx=%d, bytes_read=%ld, scanlength=%ld\n",
+ frmx, frame->bytes_read, frame->scanlength);
+
+ /* copy bytes to user space; we allow for partials reads */
+ if ((count + frame->bytes_read) > frame->scanlength)
+ count = frame->scanlength - frame->bytes_read;
+
+ if (copy_to_user(buf, frame->data + frame->bytes_read, count))
+ return -EFAULT;
+
+ frame->bytes_read += count;
+ if (debug >= 1)
+ printk(KERN_DEBUG "ibmcam_read: {copy} count used=%ld, new bytes_read=%ld\n",
+ count, frame->bytes_read);
+
+ if (frame->bytes_read >= frame->scanlength) { /* All data has been read */
+ frame->bytes_read = 0;
+
+ /* Mark it as available to be used again. */
+ ibmcam->frame[frmx].grabstate = FRAME_UNUSED;
+ if (ibmcam_new_frame(ibmcam, frmx ? 0 : 1))
+ printk(KERN_ERR "ibmcam_read: ibmcam_new_frame returned error\n");
+ }
+
+ return count;
+}
+
+static int ibmcam_mmap(struct video_device *dev, const char *adr, unsigned long size)
+{
+ struct usb_ibmcam *ibmcam = (struct usb_ibmcam *)dev;
+ unsigned long start = (unsigned long)adr;
+ unsigned long page, pos;
+
+ if (ibmcam->remove_pending)
+ return -EFAULT;
+
+ if (size > (((2 * MAX_FRAME_SIZE) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
+ return -EINVAL;
+
+ pos = (unsigned long)ibmcam->fbuf;
+ while (size > 0) {
+ page = kvirt_to_pa(pos);
+ if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
+ return -EAGAIN;
+
+ start += PAGE_SIZE;
+ pos += PAGE_SIZE;
+ if (size > PAGE_SIZE)
+ size -= PAGE_SIZE;
+ else
+ size = 0;
+ }
+
+ return 0;
+}
+
+static struct video_device ibmcam_template = {
+ "CPiA USB Camera",
+ VID_TYPE_CAPTURE,
+ VID_HARDWARE_CPIA,
+ ibmcam_open,
+ ibmcam_close,
+ ibmcam_read,
+ ibmcam_write,
+ NULL,
+ ibmcam_ioctl,
+ ibmcam_mmap,
+ ibmcam_init_done,
+ NULL,
+ 0,
+ 0
+};
+
+static void usb_ibmcam_configure_video(struct usb_ibmcam *ibmcam)
+{
+ if (ibmcam == NULL)
+ return;
+
+ RESTRICT_TO_RANGE(init_brightness, 0, 255);
+ RESTRICT_TO_RANGE(init_contrast, 0, 255);
+ RESTRICT_TO_RANGE(init_color, 0, 255);
+ RESTRICT_TO_RANGE(init_hue, 0, 255);
+
+ memset(&ibmcam->vpic, 0, sizeof(ibmcam->vpic));
+ memset(&ibmcam->vpic_old, 0x55, sizeof(ibmcam->vpic_old));
+
+ ibmcam->vpic.colour = init_color << 8;
+ ibmcam->vpic.hue = init_hue << 8;
+ ibmcam->vpic.brightness = init_brightness << 8;
+ ibmcam->vpic.contrast = init_contrast << 8;
+ ibmcam->vpic.whiteness = 105 << 8; /* This one isn't used */
+ ibmcam->vpic.depth = 24;
+ ibmcam->vpic.palette = VIDEO_PALETTE_RGB24;
+
+ memset(&ibmcam->vcap, 0, sizeof(ibmcam->vcap));
+ strcpy(ibmcam->vcap.name, "IBM USB Camera");
+ ibmcam->vcap.type = VID_TYPE_CAPTURE /*| VID_TYPE_SUBCAPTURE*/;
+ ibmcam->vcap.channels = 1;
+ ibmcam->vcap.audios = 0;
+ ibmcam->vcap.maxwidth = imgwidth;
+ ibmcam->vcap.maxheight = imgheight;
+ ibmcam->vcap.minwidth = min_imgwidth;
+ ibmcam->vcap.minheight = min_imgheight;
+
+ memset(&ibmcam->vchan, 0, sizeof(ibmcam->vchan));
+ ibmcam->vchan.flags = 0;
+ ibmcam->vchan.tuners = 0;
+ ibmcam->vchan.channel = 0;
+ ibmcam->vchan.type = VIDEO_TYPE_CAMERA;
+ strcpy(ibmcam->vchan.name, "Camera");
+}
+
+/*
+ * usb_ibmcam_probe()
+ *
+ * This procedure queries device descriptor and accepts the interface
+ * if it looks like IBM C-it camera.
+ *
+ * History:
+ * 1/22/00 Moved camera init code to ibmcam_open()
+ */
+static void *usb_ibmcam_probe(struct usb_device *dev, unsigned int ifnum)
+{
+ struct usb_ibmcam *ibmcam = NULL;
+ struct usb_interface_descriptor *interface;
+
+ if (debug >= 1)
+ printk(KERN_DEBUG "ibmcam_probe(%p,%u.)\n", dev, ifnum);
+
+ /* We don't handle multi-config cameras */
+ if (dev->descriptor.bNumConfigurations != 1)
+ return NULL;
+
+ /* Is it an IBM camera? */
+ if ((dev->descriptor.idVendor != 0x0545) ||
+ (dev->descriptor.idProduct != 0x8080))
+ return NULL;
+
+ /* Camera confirmed. We claim only interface 2 (video data) */
+ if (ifnum != 2)
+ return NULL;
+
+ /* We found an IBM camera */
+ printk(KERN_INFO "IBM USB camera found (interface %u.)\n", ifnum);
+
+ if (debug >= 1)
+ printk(KERN_DEBUG "ibmcam_probe: new ibmcam alloc\n");
+ ibmcam = kmalloc(sizeof(*ibmcam), GFP_KERNEL);
+ if (ibmcam == NULL) {
+ printk(KERN_ERR "couldn't kmalloc ibmcam struct\n");
+ return NULL;
+ }
+ memset(ibmcam, 0, sizeof(struct usb_ibmcam));
+ ibmcam->dev = dev;
+ interface = &dev->actconfig->interface[ifnum].altsetting[0];
+ ibmcam->iface = interface->bInterfaceNumber;
+ ibmcam->video_endp = 0x82;
+ init_waitqueue_head (&ibmcam->remove_ok);
+ ibmcam->iso_packet_len = 1014;
+
+ memcpy(&ibmcam->vdev, &ibmcam_template, sizeof(ibmcam_template));
+ usb_ibmcam_configure_video(ibmcam);
+
+ init_waitqueue_head(&ibmcam->frame[0].wq);
+ init_waitqueue_head(&ibmcam->frame[1].wq);
+
+ if (video_register_device(&ibmcam->vdev, VFL_TYPE_GRABBER) == -1) {
+ printk(KERN_ERR "video_register_device failed\n");
+ return NULL;
+ }
+ if (debug > 1)
+ printk(KERN_DEBUG "video_register_device() successful\n");
+
+ ibmcam->compress = 0;
+ ibmcam->user=0;
+ init_MUTEX(&ibmcam->lock); /* to 1 == available */
+
+ return ibmcam;
+}
+
+/*
+ * usb_ibmcam_disconnect()
+ *
+ * This procedure stops all driver activity, deallocates interface-private
+ * structure (pointed by 'ptr') and after that driver should be removable
+ * with no ill consequences.
+ *
+ * TODO: This code behaves badly on surprise removal!
+ *
+ * History:
+ * 1/22/00 Added polling of MOD_IN_USE to delay removal until all users gone.
+ */
+static void usb_ibmcam_disconnect(struct usb_device *dev, void *ptr)
+{
+ static const char proc[] = "usb_ibmcam_disconnect";
+ struct usb_ibmcam *ibmcam = (struct usb_ibmcam *) ptr;
+ wait_queue_head_t wq; /* Wait here until removal is safe */
+
+ if (debug > 0)
+ printk(KERN_DEBUG "%s(%p,%p.)\n", proc, dev, ptr);
+
+ init_waitqueue_head(&wq);
+ ibmcam->remove_pending = 1; /* Now all ISO data will be ignored */
+
+ /* At this time we ask to cancel outstanding URBs */
+ ibmcam_stop_isoc(ibmcam);
+
+ if (MOD_IN_USE) {
+ printk(KERN_INFO "%s: In use, disconnect pending.\n", proc);
+ while (MOD_IN_USE)
+ interruptible_sleep_on_timeout (&wq, HZ);
+ printk(KERN_INFO "%s: Released, wait.\n", proc);
+// interruptible_sleep_on_timeout (&wq, HZ*10);
+ }
+ video_unregister_device(&ibmcam->vdev);
+ printk(KERN_INFO "%s: Video dereg'd, wait.\n", proc);
+// interruptible_sleep_on_timeout (&wq, HZ*10);
+
+ /* Free the memory */
+ if (debug > 0)
+ printk(KERN_DEBUG "%s: freeing ibmcam=%p\n", proc, ibmcam);
+ kfree(ibmcam);
+
+ printk(KERN_INFO "%s: Memory freed, wait.\n", proc);
+// interruptible_sleep_on_timeout (&wq, HZ*10);
+
+ printk(KERN_INFO "IBM USB camera disconnected.\n");
+}
+
+static struct usb_driver ibmcam_driver = {
+ "ibmcam",
+ usb_ibmcam_probe,
+ usb_ibmcam_disconnect,
+ { NULL, NULL }
+};
+
+int usb_ibmcam_init(void)
+{
+ return usb_register(&ibmcam_driver);
+}
+
+void usb_ibmcam_cleanup(void)
+{
+ usb_deregister(&ibmcam_driver);
+}
+
+#ifdef MODULE
+int init_module(void)
+{
+ return usb_ibmcam_init();
+}
+
+void cleanup_module(void)
+{
+ usb_ibmcam_cleanup();
+}
+#endif
diff --git a/drivers/usb/ibmcam.h b/drivers/usb/ibmcam.h
new file mode 100644
index 000000000..6eb1d99ba
--- /dev/null
+++ b/drivers/usb/ibmcam.h
@@ -0,0 +1,222 @@
+/*
+ * Header file for USB IBM C-It Video Camera driver.
+ *
+ * Supports IBM C-It Video Camera.
+ *
+ * This driver is based on earlier work of:
+ *
+ * (C) Copyright 1999 Johannes Erdfelt
+ * (C) Copyright 1999 Randy Dunlap
+ */
+
+#ifndef __LINUX_IBMCAM_H
+#define __LINUX_IBMCAM_H
+
+#include <linux/list.h>
+
+#define USES_IBMCAM_PUTPIXEL 0 /* 0=Fast/oops 1=Slow/secure */
+
+/* Video Size 384 x 288 x 3 bytes for RGB */
+/* 384 because xawtv tries to grab 384 even though we tell it 352 is our max */
+#define V4L_FRAME_WIDTH 384
+#define V4L_FRAME_WIDTH_USED 352
+#define V4L_FRAME_HEIGHT 288
+#define V4L_BYTES_PER_PIXEL 3
+#define MAX_FRAME_SIZE (V4L_FRAME_WIDTH * V4L_FRAME_HEIGHT * V4L_BYTES_PER_PIXEL)
+
+/* Camera capabilities (maximum) */
+#define CAMERA_IMAGE_WIDTH 352
+#define CAMERA_IMAGE_HEIGHT 288
+#define CAMERA_IMAGE_LINE_SZ ((CAMERA_IMAGE_WIDTH * 3) / 2) /* Bytes */
+#define CAMERA_URB_FRAMES 32
+#define CAMERA_MAX_ISO_PACKET 1023 /* 1022 actually sent by camera */
+
+#define IBMCAM_NUMFRAMES 2
+#define IBMCAM_NUMSBUF 2
+
+#define FRAMES_PER_DESC (CAMERA_URB_FRAMES)
+#define FRAME_SIZE_PER_DESC (CAMERA_MAX_ISO_PACKET)
+
+/* This macro restricts an int variable to an inclusive range */
+#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
+
+/*
+ * This macro performs bounds checking - use it when working with
+ * new formats, or else you may get oopses all over the place.
+ * If pixel falls out of bounds then it gets shoved back (as close
+ * to place of offence as possible) and is painted bright red.
+ */
+#define IBMCAM_PUTPIXEL(fr, ix, iy, vr, vg, vb) { \
+ register unsigned char *pf; \
+ int limiter = 0, mx, my; \
+ mx = ix; \
+ my = iy; \
+ if (mx < 0) { \
+ mx=0; \
+ limiter++; \
+ } else if (mx >= 352) { \
+ mx=351; \
+ limiter++; \
+ } \
+ if (my < 0) { \
+ my = 0; \
+ limiter++; \
+ } else if (my >= V4L_FRAME_HEIGHT) { \
+ my = V4L_FRAME_HEIGHT - 1; \
+ limiter++; \
+ } \
+ pf = (fr)->data + V4L_BYTES_PER_PIXEL*((iy)*352 + (ix)); \
+ if (limiter) { \
+ *pf++ = 0; \
+ *pf++ = 0; \
+ *pf++ = 0xFF; \
+ } else { \
+ *pf++ = (vb); \
+ *pf++ = (vg); \
+ *pf++ = (vr); \
+ } \
+}
+
+/*
+ * We use macros to do YUV -> RGB conversion because this is
+ * very important for speed and totally unimportant for size.
+ *
+ * YUV -> RGB Conversion
+ * ---------------------
+ *
+ * B = 1.164*(Y-16) + 2.018*(V-128)
+ * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128)
+ * R = 1.164*(Y-16) + 1.596*(U-128)
+ *
+ * If you fancy integer arithmetics (as you should), hear this:
+ *
+ * 65536*B = 76284*(Y-16) + 132252*(V-128)
+ * 65536*G = 76284*(Y-16) - 53281*(U-128) - 25625*(V-128)
+ * 65536*R = 76284*(Y-16) + 104595*(U-128)
+ *
+ * Make sure the output values are within [0..255] range.
+ */
+#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
+#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \
+ int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \
+ mm_y = (my) - 16; \
+ mm_u = (mu) - 128; \
+ mm_v = (mv) - 128; \
+ mm_yc= mm_y * 76284; \
+ mm_b = (mm_yc + 132252*mm_v ) >> 16; \
+ mm_g = (mm_yc - 53281*mm_u - 25625*mm_v ) >> 16; \
+ mm_r = (mm_yc + 104595*mm_u ) >> 16; \
+ mb = LIMIT_RGB(mm_b); \
+ mg = LIMIT_RGB(mm_g); \
+ mr = LIMIT_RGB(mm_r); \
+}
+
+/* Debugging aid */
+#define IBMCAM_SAY_AND_WAIT(what) { \
+ wait_queue_head_t wq; \
+ init_waitqueue_head(&wq); \
+ printk(KERN_INFO "Say: %s\n", what); \
+ interruptible_sleep_on_timeout (&wq, HZ*3); \
+}
+
+enum {
+ STATE_SCANNING, /* Scanning for header */
+ STATE_LINES, /* Parsing lines */
+};
+
+enum {
+ FRAME_UNUSED, /* Unused (no MCAPTURE) */
+ FRAME_READY, /* Ready to start grabbing */
+ FRAME_GRABBING, /* In the process of being grabbed into */
+ FRAME_DONE, /* Finished grabbing, but not been synced yet */
+ FRAME_ERROR, /* Something bad happened while processing */
+};
+
+struct usb_device;
+
+struct ibmcam_sbuf {
+ char *data;
+ urb_t *urb;
+};
+
+struct ibmcam_frame {
+ char *data; /* Frame buffer */
+ int order_uv; /* True=UV False=VU */
+ unsigned char hdr_sig; /* "00 FF 00 ??" where 'hdr_sig' is '??' */
+
+ int width; /* Width application is expecting */
+ int height; /* Height */
+
+ int frmwidth; /* Width the frame actually is */
+ int frmheight; /* Height */
+
+ volatile int grabstate; /* State of grabbing */
+ int scanstate; /* State of scanning */
+
+ int curline; /* Line of frame we're working on */
+
+ long scanlength; /* uncompressed, raw data length of frame */
+ long bytes_read; /* amount of scanlength that has been read from *data */
+
+ wait_queue_head_t wq; /* Processes waiting */
+};
+
+struct usb_ibmcam {
+ struct video_device vdev;
+
+ /* Device structure */
+ struct usb_device *dev;
+
+ unsigned char iface;
+
+ struct semaphore lock;
+ int user; /* user count for exclusive use */
+
+ int initialized; /* Had we already sent init sequence? */
+ int streaming; /* Are we streaming Isochronous? */
+ int grabbing; /* Are we grabbing? */
+
+ int compress; /* Should the next frame be compressed? */
+
+ char *fbuf; /* Videodev buffer area */
+ int fbuf_size; /* Videodev buffer size */
+
+ int curframe;
+ struct ibmcam_frame frame[IBMCAM_NUMFRAMES]; /* Double buffering */
+
+ int cursbuf; /* Current receiving sbuf */
+ struct ibmcam_sbuf sbuf[IBMCAM_NUMSBUF]; /* Double buffering */
+ volatile int remove_pending; /* If set then about to exit */
+ wait_queue_head_t remove_ok; /* Wait here until removal is safe */
+
+ /*
+ * Scratch space from the Isochronous pipe.
+ * Scratch buffer should contain at least one pair of lines
+ * (CAMERA_IMAGE_LINE_SZ). We set it to two pairs here.
+ * This will be approximately 2 KB. HOWEVER in reality this
+ * buffer must be as large as hundred of KB because otherwise
+ * you'll get lots of overflows because V4L client may request
+ * frames not as uniformly as USB sources them.
+ */
+ unsigned char *scratch;
+ int scratchlen;
+
+ struct video_picture vpic, vpic_old; /* Picture settings */
+ struct video_capability vcap; /* Video capabilities */
+ struct video_channel vchan; /* May be used for tuner support */
+ unsigned char video_endp; /* 0x82 for IBM camera */
+ int has_hdr;
+ int frame_num;
+ int iso_packet_len; /* Videomode-dependent, saves bus bandwidth */
+
+ /* Statistics that can be overlayed on screen */
+ unsigned long urb_count; /* How many URBs we received so far */
+ unsigned long urb_length; /* Length of last URB */
+ unsigned long data_count; /* How many bytes we received */
+ unsigned long header_count; /* How many frame headers we found */
+ unsigned long scratch_ovf_count;/* How many times we overflowed scratch */
+ unsigned long iso_skip_count; /* How many empty ISO packets received */
+ unsigned long iso_err_count; /* How many bad ISO packets received */
+};
+
+#endif /* __LINUX_IBMCAM_H */
diff --git a/drivers/usb/keybdev.c b/drivers/usb/keybdev.c
index 34da92941..f45f7032f 100644
--- a/drivers/usb/keybdev.c
+++ b/drivers/usb/keybdev.c
@@ -50,11 +50,11 @@ static unsigned char keybdev_mac_codes[256] =
{ 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54,128, 1,
2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9,
- 11, 45, 46, 43, 47, 44,123, 67, 55, 49, 57,122,120, 99,118, 96,
+ 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
- 84, 85, 82, 65, 42, 0, 10,103,111, 0, 0, 0, 0, 0, 0, 0,
+ 84, 85, 82, 65, 42,105, 10,103,111, 0, 0, 0, 0, 0, 0, 0,
76,125, 75, 0,124, 0,115, 62,116, 59, 60,119, 61,121,114,117,
- 0, 0, 0, 0,127, 81, 0,113 };
+ 0, 0, 0, 0,127, 24, 0,113, 0, 0, 0, 0, 0, 55, 55, 0 };
#endif
diff --git a/drivers/usb/mousedev.c b/drivers/usb/mousedev.c
index c10b76557..95623c986 100644
--- a/drivers/usb/mousedev.c
+++ b/drivers/usb/mousedev.c
@@ -38,6 +38,13 @@
#include <linux/input.h>
#include <linux/config.h>
+#ifndef CONFIG_MOUSEDEV_SCREEN_X
+#define CONFIG_MOUSEDEV_SCREEN_X 1024
+#endif
+#ifndef CONFIG_MOUSEDEV_SCREEN_Y
+#define CONFIG_MOUSEDEV_SCREEN_Y 768
+#endif
+
struct mousedev {
char name[32];
int used;
@@ -51,8 +58,8 @@ struct mousedev_list {
struct fasync_struct *fasync;
struct mousedev *mousedev;
struct mousedev_list *next;
- int dx, dy, dz;
- unsigned char ps2[6];
+ int dx, dy, dz, oldx, oldy;
+ char ps2[6];
unsigned long buttons;
unsigned char ready, buffer, bufsiz;
unsigned char mode, genseq, impseq;
@@ -75,10 +82,26 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig
{
struct mousedev *mousedev = handle->private;
struct mousedev_list *list = mousedev->list;
- int index;
+ int index, size;
while (list) {
switch (type) {
+ case EV_ABS:
+ if (test_bit(EV_REL, handle->dev->evbit) && test_bit(REL_X, handle->dev->relbit))
+ return;
+ switch (code) {
+ case ABS_X:
+ size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
+ list->dx += (value * CONFIG_MOUSEDEV_SCREEN_X - list->oldx) / size;
+ list->oldx += list->dx * size;
+ break;
+ case ABS_Y:
+ size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
+ list->dy += (value * CONFIG_MOUSEDEV_SCREEN_Y - list->oldy) / size;
+ list->oldy += list->dy * size;
+ break;
+ }
+ break;
case EV_REL:
switch (code) {
case REL_X: list->dx += value; break;
@@ -89,12 +112,20 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig
case EV_KEY:
switch (code) {
+ case BTN_0:
+ case BTN_TOUCH:
case BTN_LEFT: index = 0; break;
+ case BTN_4:
case BTN_EXTRA: if (list->mode > 1) { index = 4; break; }
+ case BTN_STYLUS:
+ case BTN_1:
case BTN_RIGHT: index = 1; break;
+ case BTN_3:
case BTN_SIDE: if (list->mode > 1) { index = 3; break; }
+ case BTN_2:
+ case BTN_STYLUS2:
case BTN_MIDDLE: index = 2; break;
- default: index = 0;
+ default: return;
}
switch (value) {
case 0: clear_bit(index, &list->buttons); break;
@@ -186,7 +217,8 @@ static void mousedev_packet(struct mousedev_list *list, unsigned char off)
list->ps2[off] = 0x08 | ((list->dx < 0) << 4) | ((list->dy < 0) << 5) | (list->buttons & 0x07);
list->ps2[off + 1] = (list->dx > 127 ? 127 : (list->dx < -127 ? -127 : list->dx));
list->ps2[off + 2] = (list->dy > 127 ? 127 : (list->dy < -127 ? -127 : list->dy));
- list->dx = list->dy = 0;
+ list->dx -= list->ps2[off + 1];
+ list->dy -= list->ps2[off + 2];
list->bufsiz = off + 3;
if (list->mode > 1)
@@ -195,9 +227,9 @@ static void mousedev_packet(struct mousedev_list *list, unsigned char off)
if (list->mode) {
list->ps2[off + 3] = (list->dz > 127 ? 127 : (list->dz < -127 ? -127 : list->dz));
list->bufsiz++;
- list->dz = 0;
+ list->dz -= list->ps2[off + 3];
}
- list->ready = 0;
+ if (!list->dx && !list->dy && (!list->mode || !list->dz)) list->ready = 0;
list->buffer = list->bufsiz;
}
@@ -330,15 +362,14 @@ struct file_operations mousedev_fops = {
static int mousedev_connect(struct input_handler *handler, struct input_dev *dev)
{
- if (!(test_bit(EV_KEY, dev->evbit) && test_bit(EV_REL, dev->evbit))) /* The device must have both rels and keys */
+ if (!test_bit(EV_KEY, dev->evbit) ||
+ (!test_bit(BTN_LEFT, dev->keybit) && !test_bit(BTN_TOUCH, dev->keybit)))
return -1;
- if (!(test_bit(REL_X, dev->relbit) && test_bit(REL_Y, dev->relbit))) /* It must be a pointer device */
+ if ((!test_bit(EV_REL, dev->evbit) || !test_bit(REL_X, dev->relbit)) &&
+ (!test_bit(EV_ABS, dev->evbit) || !test_bit(ABS_X, dev->absbit)))
return -1;
- if (!test_bit(BTN_LEFT, dev->keybit)) /* And have at least one mousebutton */
- return -1;
-
#ifdef CONFIG_INPUT_MOUSEDEV_MIX
{
struct input_handle *handle;
diff --git a/drivers/usb/ov511.c b/drivers/usb/ov511.c
index c26f96132..6ec72d502 100644
--- a/drivers/usb/ov511.c
+++ b/drivers/usb/ov511.c
@@ -1,6 +1,6 @@
/*
* OmniVision OV511 Camera-to-USB Bridge Driver
- * Copyright 1999 Mark W. McClelland
+ * Copyright 1999/2000 Mark W. McClelland
*
* Based on the Linux CPiA driver.
*
@@ -11,7 +11,7 @@
* DEBUG - Debugging code.
* FIXME - Something that is broken or needs improvement.
*
- * Version: 1.05
+ * Version: 1.06
*
* Please see the file: linux/Documentation/usb/ov511.txt
* and the website at: http://people.delphi.com/mmcclelland/linux/
@@ -533,7 +533,7 @@ static int ov511_mode_init_regs(struct usb_ov511 *ov511,
ov511_i2c_write(dev, 0x20, 0x1c);
ov511_i2c_write(dev, 0x24, 0x2e); /* 10 */
ov511_i2c_write(dev, 0x25, 0x7c); /* 8a */
- ov511_i2c_write(dev, 0x26, 0x70);
+ ov511_i2c_write(dev, 0x26, 0x00); /* was 0x70 */
ov511_i2c_write(dev, 0x28, 0x24); /* 24 */
ov511_i2c_write(dev, 0x2b, 0xac);
ov511_i2c_write(dev, 0x2c, 0xfe);
@@ -737,20 +737,16 @@ static int ov511_move_data(struct usb_ov511 *ov511, urb_t *urb)
int aPackNum[10];
struct ov511_frame *frame;
- if (ov511->curframe == -1) {
- return 0;
- }
-
for (i = 0; i < urb->number_of_packets; i++) {
int n = urb->iso_frame_desc[i].actual_length;
int st = urb->iso_frame_desc[i].status;
-
+ urb->iso_frame_desc[i].actual_length = 0;
+ urb->iso_frame_desc[i].status = 0;
cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
- if (!n) continue;
-
aPackNum[i] = n ? cdata[992] : -1;
+ if (!n || ov511->curframe == -1) continue;
if (st)
PDEBUG("data error: [%d] len=%d, status=%d", i, n, st);
@@ -767,14 +763,27 @@ static int ov511_move_data(struct usb_ov511 *ov511, urb_t *urb)
#endif
if (frame->scanstate == STATE_LINES) {
+ int iFrameNext;
if (waitqueue_active(&frame->wq)) {
#if 0
PDEBUG("About to wake up waiting processes");
#endif
frame->grabstate = FRAME_DONE;
- ov511->curframe = -1;
wake_up_interruptible(&frame->wq);
}
+ /* If next frame is ready or grabbing, point to it */
+ iFrameNext = (ov511->curframe + 1) % OV511_NUMFRAMES;
+ if (ov511->frame[iFrameNext].grabstate== FRAME_READY ||
+ ov511->frame[iFrameNext].grabstate== FRAME_GRABBING) {
+ ov511->curframe = iFrameNext;
+ frame->scanstate = STATE_SCANNING;
+ } else {
+#if 0
+ PDEBUG("Frame not ready? state = %d",
+ ov511->frame[iFrameNext].grabstate);
+#endif
+ ov511->curframe = -1;
+ }
}
}
@@ -1624,6 +1633,9 @@ static void* ov511_probe(struct usb_device *dev, unsigned int ifnum)
case 102:
printk("ov511: Camera is a AverMedia InterCam Elite\n");
break;
+ case 112:
+ printk("ov511: Camera is a MediaForte MV300\n");
+ break;
default:
err("Specific camera type (%d) not recognized", rc);
err("Please contact mmcclelland@delphi.com to request");
diff --git a/drivers/usb/scanner.c b/drivers/usb/scanner.c
index 97399bc2d..ec45a6fb9 100644
--- a/drivers/usb/scanner.c
+++ b/drivers/usb/scanner.c
@@ -1,7 +1,11 @@
/* -*- linux-c -*- */
/*
- * Driver for USB Scanners (linux-2.3.33)
+ * Driver for USB Scanners (linux-2.3.41)
+ *
+ * Copyright (C) 1999, 2000 David E. Nelson
+ *
+ * Portions may be copyright Brad Keryan and Michael Gee.
*
* David E. Nelson (dnelson@jump.net)
*
@@ -19,9 +23,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * Based upon mouse.c (Brad Keryan) and printer.c (Michael Gee).
+ * Originally based upon mouse.c (Brad Keryan) and printer.c (Michael Gee).
*
* History
+ *
* 0.1 8/31/1999
*
* Developed/tested using linux-2.3.15 with minor ohci.c changes to
@@ -30,18 +35,18 @@
* testing was performed with uhci but I was unable to get it to
* work. Initial relase to the linux-usb development effort.
*
+ *
* 0.2 10/16/1999
*
- * FIXED:
* - Device can't be opened unless a scanner is plugged into the USB.
* - Finally settled on a reasonable value for the I/O buffer's.
* - Cleaned up write_scanner()
* - Disabled read/write stats
* - A little more code cleanup
*
+ *
* 0.3 10/18/1999
*
- * FIXED:
* - Device registration changed to reflect new device
* allocation/registration for linux-2.3.22+.
* - Adopted David Brownell's <david-b@pacbell.net> technique for
@@ -52,19 +57,21 @@
* - Added user specified verdor:product USB ID's which can be passed
* as module parameters.
*
+ *
* 0.3.1
- * FIXED:
+ *
* - Applied patches for linux-2.3.25.
* - Error number reporting changed to reflect negative return codes.
*
+ *
* 0.3.2
- * FIXED:
+ *
* - Applied patches for linux-2.3.26 to scanner_init().
* - Debug read/write stats now report values as signed decimal.
*
*
* 0.3.3
- * FIXED:
+ *
* - Updated the bulk_msg() calls to usb usb_bulk_msg().
* - Added a small delay in the write_scanner() method to aid in
* avoiding NULL data reads on HP scanners. We'll see how this works.
@@ -75,13 +82,42 @@
* - kfree()'d the pointer after using usb_string() as documented in
* linux-usb-api.txt.
* - Added usb_set_configuration(). It got lost in version 0.3 -- ack!
- * - Added the HP 5200C USB Vendor/Product ID's
+ * - Added the HP 5200C USB Vendor/Product ID's.
+ *
+ *
+ * 0.3.4
+ *
+ * - Added Greg K-H's <greg@kroah.com> patch for better handling of
+ * Product/Vendor detection.
+ * - The driver now autoconfigures its endpoints including interrupt
+ * endpoints if one is detected. The concept was originally based
+ * upon David Brownell's method.
+ * - Added some Seiko/Epson ID's. Thanks to Karl Heinz
+ * Kremer <khk@khk.net>.
+ * - Added some preliminary ioctl() calls for the PV8630 which is used
+ * by the HP4200. The ioctl()'s still have to be registered. Thanks
+ * to Adrian Perez Jorge <adrianpj@easynews.com>.
+ * - Moved/migrated stuff to scanner.h
+ * - Removed the usb_set_configuration() since this is handled by
+ * the usb_new_device() routine in usb.c.
+ * - Added the HP 3300C. Thanks to Bruce Tenison.
+ * - Changed user specified vendor/product id so that root hub doesn't
+ * get falsely attached to. Thanks to Greg K-H.
+ * - Added some Mustek ID's. Thanks to Gernot Hoyler
+ * <Dr.Hoyler@t-online.de>.
+ * - Modified the usb_string() reporting. See kfree() comment above.
+ * - Added Umax Astra 2000U. Thanks to Doug Alcorn.
+ * - Updated the printk()'s to use the info/warn/dbg macros.
+ * - Updated usb_bulk_msg() argument types to correct gcc warnings.
+ *
*
* TODO
+ *
* - Simultaneous multiple device attachment
- * - ioctl()'s ?
+ *
*
* Thanks to:
+ *
* - All the folks on the linux-usb list who put up with me. :) This
* has been a great learning experience for me.
* - To Linus Torvalds for this great OS.
@@ -90,58 +126,28 @@
* - And anybody else who chimed in with reports and suggestions.
*
* Performance:
+ *
* System: Pentium 120, 80 MB RAM, OHCI, Linux 2.3.23, HP 4100C USB Scanner
* 300 dpi scan of the entire bed
* 24 Bit Color ~ 70 secs - 3.6 Mbit/sec
* 8 Bit Gray ~ 17 secs - 4.2 Mbit/sec
* */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <asm/uaccess.h>
-#include <linux/malloc.h>
-#include <linux/delay.h>
-
-#undef DEBUG /* Enable to print results of read/write_scanner() calls */
-#undef RD_DATA_DUMP /* Enable to dump data - limited to 24 bytes */
-#undef WR_DATA_DUMP
-
-#include "usb.h"
-
-#define IBUF_SIZE 32768
-#define OBUF_SIZE 4096
-
-struct hpscan_usb_data {
- struct usb_device *hpscan_dev;
- int isopen; /* Not zero if the device is open */
- int present; /* Device is present on the bus */
- char *obuf, *ibuf; /* transfer buffers */
- char iep, oep; /* I/O Endpoints */
-};
-
-static struct hpscan_usb_data hpscan;
-
-MODULE_AUTHOR("David E. Nelson, dnelson@jump.net, http://www.jump.net/~dnelson");
-MODULE_DESCRIPTION("USB Scanner Driver");
-
-static __u16 vendor=0x05f9, product=0xffff;
-MODULE_PARM(vendor, "i");
-MODULE_PARM_DESC(vendor, "User specified USB idVendor");
-
-MODULE_PARM(product, "i");
-MODULE_PARM_DESC(product, "User specified USB idProduct");
+#include "scanner.h"
static int
open_scanner(struct inode * inode, struct file * file)
{
struct hpscan_usb_data *hps = &hpscan;
+ struct usb_device *dev;
- if (!hps->present) {
+ dev = hps->hpscan_dev;
+
+ if (!dev) {
return -ENODEV;
}
- if (!hps->hpscan_dev) {
+ if (!hps->present) {
return -ENODEV;
}
@@ -173,18 +179,18 @@ write_scanner(struct file * file, const char * buffer,
size_t count, loff_t *ppos)
{
struct hpscan_usb_data *hps = &hpscan;
-
- unsigned long copy_size;
- unsigned long bytes_written = 0;
- unsigned long partial;
-
+ struct usb_device *dev;
+
+ ssize_t bytes_written = 0;
ssize_t ret = 0;
+ int copy_size;
+ int partial;
int result = 0;
char *obuf = hps->obuf;
- set_current_state(TASK_INTERRUPTIBLE);
+ dev = hps->hpscan_dev;
while (count > 0) {
@@ -200,8 +206,8 @@ write_scanner(struct file * file, const char * buffer,
break;
}
- result = usb_bulk_msg(hps->hpscan_dev,usb_sndbulkpipe(hps->hpscan_dev, hps->oep), obuf, copy_size, &partial, 30*HZ);
- dbg("write stats: result:%d copy_size:%lu partial:%lu", (int)result, copy_size, partial);
+ result = usb_bulk_msg(dev,usb_sndbulkpipe(dev, hps->bulk_out_ep), obuf, copy_size, &partial, 60*HZ);
+ dbg("write stats: result:%d copy_size:%d partial:%d", result, copy_size, partial);
if (result == USB_ST_TIMEOUT) { /* NAK -- shouldn't happen */
warn("write_scanner: NAK recieved.");
@@ -217,7 +223,7 @@ write_scanner(struct file * file, const char * buffer,
if (partial) {
unsigned char cnt, cnt_max;
cnt_max = (partial > 24) ? 24 : partial;
- printk(KERN_DEBUG __FILE__ ": dump: ");
+ printk(KERN_DEBUG "dump: ");
for (cnt=0; cnt < cnt_max; cnt++) {
printk("%X ", obuf[cnt]);
}
@@ -239,8 +245,7 @@ write_scanner(struct file * file, const char * buffer,
break;
}
}
-// mdelay(5);
- set_current_state(TASK_RUNNING);
+ mdelay(5);
return ret ? ret : bytes_written;
}
@@ -249,18 +254,19 @@ read_scanner(struct file * file, char * buffer,
size_t count, loff_t *ppos)
{
struct hpscan_usb_data *hps = &hpscan;
+ struct usb_device *dev;
ssize_t read_count, ret = 0;
- unsigned long partial;
-
+ int partial;
int this_read;
int result;
char *ibuf = hps->ibuf;
+ dev = hps->hpscan_dev;
+
read_count = 0;
- set_current_state(TASK_INTERRUPTIBLE);
while (count) {
if (signal_pending(current)) {
@@ -270,8 +276,8 @@ read_scanner(struct file * file, char * buffer,
this_read = (count > IBUF_SIZE) ? IBUF_SIZE : count;
- result = usb_bulk_msg(hps->hpscan_dev, usb_rcvbulkpipe(hps->hpscan_dev, hps->iep), ibuf, this_read, &partial, 60*HZ);
- dbg("read stats: result:%d this_read:%u partial:%lu", (int)result, this_read, partial);
+ result = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, hps->bulk_in_ep), ibuf, this_read, &partial, 60*HZ);
+ dbg("read stats: result:%d this_read:%d partial:%d", result, this_read, partial);
if (result == USB_ST_TIMEOUT) { /* NAK -- shouldn't happen */
warn("read_scanner: NAK received");
@@ -287,7 +293,7 @@ read_scanner(struct file * file, char * buffer,
if (partial) {
unsigned char cnt, cnt_max;
cnt_max = (partial > 24) ? 24 : partial;
- printk(KERN_DEBUG __FILE__ ": dump: ");
+ printk(KERN_DEBUG "dump: ");
for (cnt=0; cnt < cnt_max; cnt++) {
printk("%X ", ibuf[cnt]);
}
@@ -313,7 +319,6 @@ read_scanner(struct file * file, char * buffer,
buffer += this_read;
}
}
- set_current_state(TASK_RUNNING);
return ret ? ret : read_count;
}
@@ -321,103 +326,174 @@ static void *
probe_scanner(struct usb_device *dev, unsigned int ifnum)
{
struct hpscan_usb_data *hps = &hpscan;
+ struct usb_interface_descriptor *interface;
struct usb_endpoint_descriptor *endpoint;
+
+ int ep_cnt;
char *ident;
+ char valid_device = 0;
+ char have_bulk_in, have_bulk_out, have_intr;
hps->present = 0;
- if (vendor != 0 || product != 0)
- info("USB Scanner Vendor:Product - %x:%x\n", vendor, product);
+ if (vendor != -1 && product != -1) {
+ info("probe_scanner: User specified USB scanner -- Vendor:Product - %x:%x", vendor, product);
+ }
+
+/*
+ * 1. Check Vendor/Product
+ * 2. Determine/Assign Bulk Endpoints
+ * 3. Determine/Assign Intr Endpoint
+ */
-/* There doesn't seem to be an imaging class defined in the USB
+/*
+ * There doesn't seem to be an imaging class defined in the USB
* Spec. (yet). If there is, HP isn't following it and it doesn't
* look like anybody else is either. Therefore, we have to test the
- * Vendor and Product ID's to see what we have. This makes this
- * driver a high maintenance driver since it has to be updated with
- * each release of a product. Also, other scanners may be able to use
- * this driver but again, their Vendor and Product ID's must be added.
+ * Vendor and Product ID's to see what we have. Also, other scanners
+ * may be able to use this driver by specifying both vendor and
+ * product ID's as options to the scanner module in conf.modules.
*
* NOTE: Just because a product is supported here does not mean that
* applications exist that support the product. It's in the hopes
* that this will allow developers a means to produce applications
* that will support USB products.
*
- * Until we detect a device which is pleasing, we silently punt.
- * */
+ * Until we detect a device which is pleasing, we silently punt. */
+
+ do {
+ if (dev->descriptor.idVendor == 0x03f0) { /* Hewlett Packard */
+ if (dev->descriptor.idProduct == 0x0205 || /* 3300C */
+ dev->descriptor.idProduct == 0x0101 || /* 4100C */
+ dev->descriptor.idProduct == 0x0105 || /* 4200C */
+ dev->descriptor.idProduct == 0x0202 || /* PhotoSmart S20 */
+ dev->descriptor.idProduct == 0x0401 || /* 5200C */
+ dev->descriptor.idProduct == 0x0201 || /* 6200C */
+ dev->descriptor.idProduct == 0x0601) { /* 6300C */
+ valid_device = 1;
+ break;
+ }
+ }
+
+ if (dev->descriptor.idVendor == 0x06bd && /* AGFA */
+ dev->descriptor.idProduct == 0x0001) { /* SnapScan 1212U */
+ valid_device = 1;
+ break;
+ }
+
+ if (dev->descriptor.idVendor == 0x1606 && /* Umax */
+ dev->descriptor.idProduct == 0x0030) { /* Astra 2000U */
+ valid_device = 1;
+ break;
+ }
+
+ if (dev->descriptor.idVendor == 0x04b8) { /* Seiko/Epson Corp. */
+ if (dev->descriptor.idProduct == 0x0101 || /* Perfection 636 */
+ dev->descriptor.idProduct == 0x0104) { /* Perfection 1200U */
+ valid_device = 1;
+ break;
+ }
+ }
- if (dev->descriptor.idVendor != 0x03f0 && /* Hewlett Packard */
- dev->descriptor.idVendor != 0x06bd && /* AGFA */
- dev->descriptor.idVendor != 0x1606 && /* UMAX */
- dev->descriptor.idVendor != vendor ) { /* User specified */
- return NULL;
- }
+ if (dev->descriptor.idVendor == 0x055f) { /* Mustek */
+ if (dev->descriptor.idProduct == 0x0001) { /* 1200 CU */
+ valid_device = 1;
+ break;
+ }
+ }
- if (dev->descriptor.idProduct != 0x0101 && /* HP 4100C */
- dev->descriptor.idProduct != 0x0102 && /* HP 4200C & PhotoSmart S20? */
- dev->descriptor.idProduct != 0x0202 && /* HP 5100C */
- dev->descriptor.idProduct != 0x0401 && /* HP 5200C */
- dev->descriptor.idProduct != 0x0201 && /* HP 6200C */
- dev->descriptor.idProduct != 0x0601 && /* HP 6300C */
- dev->descriptor.idProduct != 0x0001 && /* AGFA SnapScan 1212U */
- dev->descriptor.idProduct != 0x0030 && /* Umax 2000U */
- dev->descriptor.idProduct != product) { /* User specified */
+ if (dev->descriptor.idVendor == vendor && /* User specified */
+ dev->descriptor.idProduct == product) { /* User specified */
+ valid_device = 1;
+ break;
+ }
+ } while (0);
+
+ if (!valid_device)
return NULL;
- }
-/* After this point we can be a little noisy about what we are trying to
- * configure. */
- if (dev->descriptor.bNumConfigurations != 1 ||
- dev->config[0].bNumInterfaces != 1) {
- dbg("probe_scanner: only simple configurations supported");
+/*
+ * After this point we can be a little noisy about what we are trying to
+ * configure.
+ */
+
+ if (dev->descriptor.bNumConfigurations != 1) {
+ info("probe_scanner: Only one configuration is supported.");
return NULL;
}
- endpoint = dev->config[0].interface[0].altsetting[0].endpoint;
-
- if (endpoint[0].bmAttributes != USB_ENDPOINT_XFER_BULK
- || endpoint [1].bmAttributes != USB_ENDPOINT_XFER_BULK) {
- dbg("probe_scanner: invalid bulk endpoints");
+ if (dev->config[0].bNumInterfaces != 1) {
+ info("probe_scanner: Only one interface is supported.");
return NULL;
}
- if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) {
- dbg("probe_scanner: failed usb_set_configuration");
- hps->hpscan_dev = NULL;
- return NULL;
- }
+ interface = dev->config[0].interface[0].altsetting;
+ endpoint = interface[0].endpoint;
-/* By the time we get here, we should be dealing with a fairly simple
- * device that supports at least two bulk endpoints on endpoints 1 and
- * 2.
- *
- * We determine the bulk endpoints so that the read_*() and write_*()
- * procedures can recv/send data to the correct endpoint.
- * */
+/*
+ * Start checking for two bulk endpoints OR two bulk endpoints *and* one
+ * interrupt endpoint. If we have an interrupt endpoint go ahead and
+ * setup the handler. FIXME: This is a future enhancement...
+ */
- hps->iep = hps->oep = 0;
- if ((endpoint[0].bEndpointAddress & 0x80) == 0x80) {
- hps->iep = endpoint[0].bEndpointAddress & 0x7f;
- } else {
- hps->oep = endpoint[0].bEndpointAddress;
- }
+ dbg("probe_scanner: Number of Endpoints: %d", (int) interface->bNumEndpoints);
- if ((endpoint[1].bEndpointAddress & 0x80) == 0x80) {
- hps->iep = endpoint[1].bEndpointAddress & 0x7f;
- } else {
- hps->oep = endpoint[1].bEndpointAddress;
+ if ((interface->bNumEndpoints != 2) && (interface->bNumEndpoints != 3)) {
+ info("probe_scanner: Only two or three endpoints supported.");
+ return NULL;
}
- ident = kmalloc(256, GFP_KERNEL);
- if (ident) {
- usb_string(dev, dev->descriptor.iProduct, ident, 256);
- info("USB Scanner (%s) found at address %d", ident, dev->devnum);
- kfree(ident);
+ ep_cnt = have_bulk_in = have_bulk_out = have_intr = 0;
+
+ while (ep_cnt < interface->bNumEndpoints) {
+
+ if (!have_bulk_in && IS_EP_BULK_IN(endpoint[ep_cnt])) {
+ have_bulk_in = 1;
+ hps->bulk_in_ep = ep_cnt + 1;
+ ep_cnt++;
+ dbg("probe_scanner: bulk_in_ep: %d", (int)hps->bulk_in_ep);
+ continue;
+ }
+
+ if (!have_bulk_out && IS_EP_BULK_OUT(endpoint[ep_cnt])) {
+ have_bulk_out = 1;
+ hps->bulk_out_ep = ep_cnt + 1;
+ ep_cnt++;
+ dbg("probe_scanner: bulk_out_ep: %d", (int)hps->bulk_out_ep);
+ continue;
+ }
+
+ if (!have_intr && IS_EP_INTR(endpoint[ep_cnt])) {
+ have_intr = 1;
+ hps->intr_ep = ep_cnt + 1;
+ ep_cnt++;
+ dbg("probe_scanner: intr_ep: %d", (int)hps->intr_ep);
+ continue;
+ }
+ info("probe_scanner: Undetected endpoint. Notify the maintainer.");
+ return NULL; /* Shouldn't ever get here unless we have something weird */
}
- dbg("probe_scanner: using bulk endpoints - In: %x Out: %x", hps->iep, hps->oep);
+ switch(interface->bNumEndpoints) {
+ case 2:
+ if (!have_bulk_in || !have_bulk_out) {
+ info("probe_scanner: Two bulk endpoints required.");
+ return NULL;
+ }
+ break;
+ case 3:
+ if (!have_bulk_in || !have_bulk_out || !have_intr) {
+ info("probe_scanner: Two bulk endpoints and one interrupt endpoint required.");
+ return NULL;
+ }
+ break;
+ default:
+ info("probe_scanner: Endpoint determination failed. Notify the maintainer.");
+ return NULL;
+ }
hps->present = 1;
hps->hpscan_dev = dev;
@@ -449,6 +525,71 @@ disconnect_scanner(struct usb_device *dev, void *ptr)
hps->present = 0;
}
+static int
+ioctl_scanner(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct hpscan_usb_data *hps = &hpscan;
+ struct usb_device *dev;
+
+ int result;
+
+ dev = hps->hpscan_dev;
+
+ switch (cmd)
+ {
+ case PV8630_RECEIVE :
+ {
+ struct {
+ unsigned char data;
+ __u16 value;
+ __u16 index;
+ } args;
+
+ if (copy_from_user(&args, (void *)arg, sizeof(args)))
+ return -EFAULT;
+
+ result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x0,
+ USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,
+ args.value, args.index, &args.data, 1, HZ);
+
+ dbg("ioctl_scanner recv: args.data:%x args.value:%x args.index:%x",
+ args.data, args.value, args.index);
+
+ if (copy_to_user((void *)arg, &args, sizeof(args)))
+ return -EFAULT;
+
+ dbg("ioctl_scanner recv: result:%d", result);
+
+ return result;
+ }
+ case PV8630_SEND :
+ {
+ struct {
+ __u16 value;
+ __u16 index;
+ } args;
+
+ if (copy_from_user(&args, (void *)arg, sizeof(args)))
+ return -EFAULT;
+
+ dbg("ioctl_scanner send: args.value:%x args.index:%x", args.value, args.index);
+
+ result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x1 /* Vendor Specific bRequest */,
+ USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_OUT /* 0x40 */,
+ args.value, args.index, NULL, 0, HZ);
+
+ dbg("ioctl_scanner send: result:%d", result);
+
+
+ return result;
+ }
+ default:
+ return -ENOIOCTLCMD;
+ }
+ return 0;
+}
+
static struct
file_operations usb_scanner_fops = {
NULL, /* seek */
@@ -456,7 +597,7 @@ file_operations usb_scanner_fops = {
write_scanner,
NULL, /* readdir */
NULL, /* poll */
- NULL, /* ioctl */
+ ioctl_scanner, /* ioctl */
NULL, /* mmap */
open_scanner,
NULL, /* flush */
diff --git a/drivers/usb/scanner.h b/drivers/usb/scanner.h
new file mode 100644
index 000000000..996eb7f59
--- /dev/null
+++ b/drivers/usb/scanner.h
@@ -0,0 +1,55 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/ioctl.h>
+
+// #define DEBUG
+
+#include "usb.h"
+
+// #define RD_DATA_DUMP /* Enable to dump data - limited to 24 bytes */
+// #define WR_DATA_DUMP /* DEBUG does not have to be defined. */
+
+#define IS_EP_BULK(ep) ((ep).bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0)
+#define IS_EP_BULK_IN(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
+#define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
+#define IS_EP_INTR(ep) ((ep).bmAttributes == USB_ENDPOINT_XFER_INT ? 1 : 0)
+
+#ifdef DEBUG
+#define SCN_DEBUG(X) X
+#else
+#define SCN_DEBUG(X)
+#endif
+
+#define IBUF_SIZE 32768
+#define OBUF_SIZE 4096
+
+
+/* FIXME: These are NOT registered ioctls()'s */
+
+#define PV8630_RECEIVE 69
+#define PV8630_SEND 70
+
+struct hpscan_usb_data {
+ struct usb_device *hpscan_dev;
+ int isopen; /* Not zero if the device is open */
+ int present; /* Device is present on the bus */
+ char *obuf, *ibuf; /* transfer buffers */
+ char bulk_in_ep, bulk_out_ep, intr_ep; /* Endpoint assignments */
+ char *button; /* Front panel button buffer */
+};
+
+static struct hpscan_usb_data hpscan;
+
+MODULE_AUTHOR("David E. Nelson, dnelson@jump.net, http://www.jump.net/~dnelson");
+MODULE_DESCRIPTION("USB Scanner Driver");
+
+static __s32 vendor=-1, product=-1;
+MODULE_PARM(vendor, "i");
+MODULE_PARM_DESC(vendor, "User specified USB idVendor");
+
+MODULE_PARM(product, "i");
+MODULE_PARM_DESC(product, "User specified USB idProduct");
diff --git a/drivers/usb/uhci-debug.c b/drivers/usb/uhci-debug.c
deleted file mode 100644
index 2ecd611e6..000000000
--- a/drivers/usb/uhci-debug.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * $Id: uhci-debug.c,v 1.12 1999/12/13 15:24:42 fliegl Exp $
- */
-
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <asm/io.h>
-
-#define DEBUG
-
-#include "usb.h"
-#include "uhci.h"
-
-void dump_urb (purb_t purb)
-{
- dbg("urb :%p", purb);
- dbg("next :%p", purb->next);
- dbg("dev :%p", purb->dev);
- dbg("pipe :%08X", purb->pipe);
- dbg("status :%d", purb->status);
- dbg("transfer_flags :%08X", purb->transfer_flags);
- dbg("transfer_buffer :%p", purb->transfer_buffer);
- dbg("transfer_buffer_length:%d", purb->transfer_buffer_length);
- dbg("actual_length :%d", purb->actual_length);
- dbg("setup_packet :%p", purb->setup_packet);
- dbg("start_frame :%d", purb->start_frame);
- dbg("number_of_packets :%d", purb->number_of_packets);
- dbg("interval :%d", purb->interval);
- dbg("error_count :%d", purb->error_count);
- dbg("context :%p", purb->context);
- dbg("complete :%p", purb->complete);
-}
-
-void beep (long freq)
-{
- long v;
- char low, high;
-
- if (!freq)
- outb (inb (0x61) & 252, 0x61);
- else {
- outb (inb (0x61) | 0x3, 0x61);
-
- v = 1193180L / freq;
-
- low = (char) (v & 255);
- high = (char) ((v >> 8) & 255);
-
- outb (182, 0x43);
- outb (low, 0x42);
- outb (high, 0x42);
- }
-}
-
-void uhci_show_qh (puhci_desc_t qh)
-{
- if (qh->type != QH_TYPE) {
- dbg("qh has not QH_TYPE");
- return;
- }
- dbg("uhci_show_qh %p (%08lX):", qh, virt_to_bus (qh));
-
- if (qh->hw.qh.head & UHCI_PTR_TERM)
- dbg("Head Terminate");
- else {
- if (qh->hw.qh.head & UHCI_PTR_QH)
- dbg("Head points to QH");
- else
- dbg("Head points to TD");
-
- dbg("head: %08X", qh->hw.qh.head & ~UHCI_PTR_BITS);
- }
- if (qh->hw.qh.element & UHCI_PTR_TERM)
- dbg("Element Terminate");
- else {
-
- if (qh->hw.qh.element & UHCI_PTR_QH)
- dbg("Element points to QH");
- else
- dbg("Element points to TD");
- dbg("element: %08X", qh->hw.qh.element & ~UHCI_PTR_BITS);
- }
-}
-
-void uhci_show_td (puhci_desc_t td)
-{
- char *spid;
-
- switch (td->hw.td.info & 0xff) {
- case USB_PID_SETUP:
- spid = "SETUP";
- break;
- case USB_PID_OUT:
- spid = " OUT ";
- break;
- case USB_PID_IN:
- spid = " IN ";
- break;
- default:
- spid = " ? ";
- break;
- }
-
- dbg("uhci_show_td %p (%08lX) MaxLen=%02x DT%d EndPt=%x Dev=%x, PID=%x(%s) (buf=%08x)",
- td,
- virt_to_bus(td),
- td->hw.td.info >> 21,
- ((td->hw.td.info >> 19) & 1),
- (td->hw.td.info >> 15) & 15,
- (td->hw.td.info >> 8) & 127,
- (td->hw.td.info & 0xff),
- spid,
- td->hw.td.buffer);
-
- dbg("Len=%02x e%d %s%s%s%s%s%s%s%s%s%s",
- td->hw.td.status & 0x7ff,
- ((td->hw.td.status >> 27) & 3),
- (td->hw.td.status & TD_CTRL_SPD) ? "SPD " : "",
- (td->hw.td.status & TD_CTRL_LS) ? "LS " : "",
- (td->hw.td.status & TD_CTRL_IOC) ? "IOC " : "",
- (td->hw.td.status & TD_CTRL_ACTIVE) ? "Active " : "",
- (td->hw.td.status & TD_CTRL_STALLED) ? "Stalled " : "",
- (td->hw.td.status & TD_CTRL_DBUFERR) ? "DataBufErr " : "",
- (td->hw.td.status & TD_CTRL_BABBLE) ? "Babble " : "",
- (td->hw.td.status & TD_CTRL_NAK) ? "NAK " : "",
- (td->hw.td.status & TD_CTRL_CRCTIMEO) ? "CRC/Timeo " : "",
- (td->hw.td.status & TD_CTRL_BITSTUFF) ? "BitStuff " : ""
- );
-
- if (td->hw.td.link & UHCI_PTR_TERM)
- dbg("Link Terminate");
- else {
- if (td->hw.td.link & UHCI_PTR_QH)
- dbg("%s, link points to QH @ %08x",
- (td->hw.td.link & UHCI_PTR_DEPTH ? "Depth first" : " Breadth first"),
- td->hw.td.link & ~UHCI_PTR_BITS);
- else
- dbg("%s, link points to TD @ %08x",
- (td->hw.td.link & UHCI_PTR_DEPTH ? "Depth first" : " Breadth first"),
- td->hw.td.link & ~UHCI_PTR_BITS);
- }
-}
-
-void uhci_show_td_queue (puhci_desc_t td)
-{
- dbg("uhci_show_td_queue %p (%08lX):", td, virt_to_bus (td));
- while (1) {
- uhci_show_td (td);
- if (td->hw.td.link & UHCI_PTR_TERM)
- break;
- //if(!(td->hw.td.link&UHCI_PTR_DEPTH))
- // break;
- if (td != bus_to_virt (td->hw.td.link & ~UHCI_PTR_BITS))
- td = bus_to_virt (td->hw.td.link & ~UHCI_PTR_BITS);
- else {
- dbg("td points to itself!");
- break;
- }
-// schedule();
- }
-}
-
-void uhci_show_queue (puhci_desc_t qh)
-{
- dbg("uhci_show_queue %p:", qh);
- while (1) {
- uhci_show_qh (qh);
-
- if (qh->hw.qh.element & UHCI_PTR_QH)
- dbg("Warning: qh->element points to qh!");
- else if (!(qh->hw.qh.element & UHCI_PTR_TERM))
- uhci_show_td_queue (bus_to_virt (qh->hw.qh.element & ~UHCI_PTR_BITS));
-
- if (qh->hw.qh.head & UHCI_PTR_TERM)
- break;
-
- if (qh != bus_to_virt (qh->hw.qh.head & ~UHCI_PTR_BITS))
- qh = bus_to_virt (qh->hw.qh.head & ~UHCI_PTR_BITS);
- else {
- dbg("qh points to itself!");
- break;
- }
- }
-}
-
-static void uhci_show_sc (int port, unsigned short status)
-{
- dbg(" stat%d = %04x %s%s%s%s%s%s%s%s",
- port,
- status,
- (status & USBPORTSC_SUSP) ? "PortSuspend " : "",
- (status & USBPORTSC_PR) ? "PortReset " : "",
- (status & USBPORTSC_LSDA) ? "LowSpeed " : "",
- (status & USBPORTSC_RD) ? "ResumeDetect " : "",
- (status & USBPORTSC_PEC) ? "EnableChange " : "",
- (status & USBPORTSC_PE) ? "PortEnabled " : "",
- (status & USBPORTSC_CSC) ? "ConnectChange " : "",
- (status & USBPORTSC_CCS) ? "PortConnected " : "");
-}
-
-void uhci_show_status (puhci_t s)
-{
- unsigned int io_addr = s->io_addr;
- unsigned short usbcmd, usbstat, usbint, usbfrnum;
- unsigned int flbaseadd;
- unsigned char sof;
- unsigned short portsc1, portsc2;
-
- usbcmd = inw (io_addr + 0);
- usbstat = inw (io_addr + 2);
- usbint = inw (io_addr + 4);
- usbfrnum = inw (io_addr + 6);
- flbaseadd = inl (io_addr + 8);
- sof = inb (io_addr + 12);
- portsc1 = inw (io_addr + 16);
- portsc2 = inw (io_addr + 18);
-
- dbg(" usbcmd = %04x %s%s%s%s%s%s%s%s",
- usbcmd,
- (usbcmd & USBCMD_MAXP) ? "Maxp64 " : "Maxp32 ",
- (usbcmd & USBCMD_CF) ? "CF " : "",
- (usbcmd & USBCMD_SWDBG) ? "SWDBG " : "",
- (usbcmd & USBCMD_FGR) ? "FGR " : "",
- (usbcmd & USBCMD_EGSM) ? "EGSM " : "",
- (usbcmd & USBCMD_GRESET) ? "GRESET " : "",
- (usbcmd & USBCMD_HCRESET) ? "HCRESET " : "",
- (usbcmd & USBCMD_RS) ? "RS " : "");
-
- dbg(" usbstat = %04x %s%s%s%s%s%s",
- usbstat,
- (usbstat & USBSTS_HCH) ? "HCHalted " : "",
- (usbstat & USBSTS_HCPE) ? "HostControllerProcessError " : "",
- (usbstat & USBSTS_HSE) ? "HostSystemError " : "",
- (usbstat & USBSTS_RD) ? "ResumeDetect " : "",
- (usbstat & USBSTS_ERROR) ? "USBError " : "",
- (usbstat & USBSTS_USBINT) ? "USBINT " : "");
-
- dbg(" usbint = %04x", usbint);
- dbg(" usbfrnum = (%d)%03x", (usbfrnum >> 10) & 1,
- 0xfff & (4 * (unsigned int) usbfrnum));
- dbg(" flbaseadd = %08x", flbaseadd);
- dbg(" sof = %02x", sof);
- uhci_show_sc (1, portsc1);
- uhci_show_sc (2, portsc2);
-}
diff --git a/drivers/usb/uhci-debug.h b/drivers/usb/uhci-debug.h
index aebc836aa..73d16937a 100644
--- a/drivers/usb/uhci-debug.h
+++ b/drivers/usb/uhci-debug.h
@@ -1,7 +1,195 @@
-void uhci_show_qh(puhci_desc_t qh);
-void uhci_show_td(puhci_desc_t td);
-void uhci_show_td_queue(puhci_desc_t td);
-void uhci_show_queue(puhci_desc_t qh);
-void uhci_show_status(puhci_t s);
-void beep(long freq);
-void dump_urb (purb_t purb); \ No newline at end of file
+#ifdef DEBUG
+
+static void uhci_show_qh (puhci_desc_t qh)
+{
+ if (qh->type != QH_TYPE) {
+ dbg("qh has not QH_TYPE");
+ return;
+ }
+ dbg("uhci_show_qh %p (%08lX):", qh, virt_to_bus (qh));
+
+ if (qh->hw.qh.head & UHCI_PTR_TERM)
+ dbg("Head Terminate");
+ else {
+ if (qh->hw.qh.head & UHCI_PTR_QH)
+ dbg("Head points to QH");
+ else
+ dbg("Head points to TD");
+
+ dbg("head: %08X", qh->hw.qh.head & ~UHCI_PTR_BITS);
+ }
+ if (qh->hw.qh.element & UHCI_PTR_TERM)
+ dbg("Element Terminate");
+ else {
+
+ if (qh->hw.qh.element & UHCI_PTR_QH)
+ dbg("Element points to QH");
+ else
+ dbg("Element points to TD");
+ dbg("element: %08X", qh->hw.qh.element & ~UHCI_PTR_BITS);
+ }
+}
+#endif
+
+static void uhci_show_td (puhci_desc_t td)
+{
+ char *spid;
+ warn("uhci_show_td %p (%08lX) ", td, virt_to_bus (td));
+
+ switch (td->hw.td.info & 0xff) {
+ case USB_PID_SETUP:
+ spid = "SETUP";
+ break;
+ case USB_PID_OUT:
+ spid = " OUT ";
+ break;
+ case USB_PID_IN:
+ spid = " IN ";
+ break;
+ default:
+ spid = " ? ";
+ break;
+ }
+
+ warn("MaxLen=%02x DT%d EndPt=%x Dev=%x, PID=%x(%s) (buf=%08x)",
+ td->hw.td.info >> 21,
+ ((td->hw.td.info >> 19) & 1),
+ (td->hw.td.info >> 15) & 15,
+ (td->hw.td.info >> 8) & 127,
+ (td->hw.td.info & 0xff),
+ spid,
+ td->hw.td.buffer);
+
+ warn("Len=%02x e%d %s%s%s%s%s%s%s%s%s%s",
+ td->hw.td.status & 0x7ff,
+ ((td->hw.td.status >> 27) & 3),
+ (td->hw.td.status & TD_CTRL_SPD) ? "SPD " : "",
+ (td->hw.td.status & TD_CTRL_LS) ? "LS " : "",
+ (td->hw.td.status & TD_CTRL_IOC) ? "IOC " : "",
+ (td->hw.td.status & TD_CTRL_ACTIVE) ? "Active " : "",
+ (td->hw.td.status & TD_CTRL_STALLED) ? "Stalled " : "",
+ (td->hw.td.status & TD_CTRL_DBUFERR) ? "DataBufErr " : "",
+ (td->hw.td.status & TD_CTRL_BABBLE) ? "Babble " : "",
+ (td->hw.td.status & TD_CTRL_NAK) ? "NAK " : "",
+ (td->hw.td.status & TD_CTRL_CRCTIMEO) ? "CRC/Timeo " : "",
+ (td->hw.td.status & TD_CTRL_BITSTUFF) ? "BitStuff " : ""
+ );
+#if 1
+ if (td->hw.td.link & UHCI_PTR_TERM)
+ warn("Link Terminate");
+ else {
+ if (td->hw.td.link & UHCI_PTR_QH)
+ warn("%s, link points to QH @ %08x",
+ (td->hw.td.link & UHCI_PTR_DEPTH ? "Depth first" : " Breadth first"),
+ td->hw.td.link & ~UHCI_PTR_BITS);
+ else
+ warn("%s, link points to TD @ %08x",
+ (td->hw.td.link & UHCI_PTR_DEPTH ? "Depth first" : " Breadth first"),
+ td->hw.td.link & ~UHCI_PTR_BITS);
+ }
+#endif
+}
+#ifdef DEBUG
+static void uhci_show_td_queue (puhci_desc_t td)
+{
+ dbg("uhci_show_td_queue %p (%08lX):", td, virt_to_bus (td));
+ while (1) {
+ uhci_show_td (td);
+ if (td->hw.td.link & UHCI_PTR_TERM)
+ break;
+ //if(!(td->hw.td.link&UHCI_PTR_DEPTH))
+ // break;
+ if (td != bus_to_virt (td->hw.td.link & ~UHCI_PTR_BITS))
+ td = bus_to_virt (td->hw.td.link & ~UHCI_PTR_BITS);
+ else {
+ dbg("td points to itself!");
+ break;
+ }
+// schedule();
+ }
+}
+
+static void uhci_show_queue (puhci_desc_t qh)
+{
+ dbg("uhci_show_queue %p:", qh);
+ while (1) {
+ uhci_show_qh (qh);
+
+ if (qh->hw.qh.element & UHCI_PTR_QH)
+ dbg("Warning: qh->element points to qh!");
+ else if (!(qh->hw.qh.element & UHCI_PTR_TERM))
+ uhci_show_td_queue (bus_to_virt (qh->hw.qh.element & ~UHCI_PTR_BITS));
+
+ if (qh->hw.qh.head & UHCI_PTR_TERM)
+ break;
+
+ if (qh != bus_to_virt (qh->hw.qh.head & ~UHCI_PTR_BITS))
+ qh = bus_to_virt (qh->hw.qh.head & ~UHCI_PTR_BITS);
+ else {
+ dbg("qh points to itself!");
+ break;
+ }
+ }
+}
+
+static void uhci_show_sc (int port, unsigned short status)
+{
+ dbg(" stat%d = %04x %s%s%s%s%s%s%s%s",
+ port,
+ status,
+ (status & USBPORTSC_SUSP) ? "PortSuspend " : "",
+ (status & USBPORTSC_PR) ? "PortReset " : "",
+ (status & USBPORTSC_LSDA) ? "LowSpeed " : "",
+ (status & USBPORTSC_RD) ? "ResumeDetect " : "",
+ (status & USBPORTSC_PEC) ? "EnableChange " : "",
+ (status & USBPORTSC_PE) ? "PortEnabled " : "",
+ (status & USBPORTSC_CSC) ? "ConnectChange " : "",
+ (status & USBPORTSC_CCS) ? "PortConnected " : "");
+}
+
+void uhci_show_status (puhci_t s)
+{
+ unsigned int io_addr = s->io_addr;
+ unsigned short usbcmd, usbstat, usbint, usbfrnum;
+ unsigned int flbaseadd;
+ unsigned char sof;
+ unsigned short portsc1, portsc2;
+
+ usbcmd = inw (io_addr + 0);
+ usbstat = inw (io_addr + 2);
+ usbint = inw (io_addr + 4);
+ usbfrnum = inw (io_addr + 6);
+ flbaseadd = inl (io_addr + 8);
+ sof = inb (io_addr + 12);
+ portsc1 = inw (io_addr + 16);
+ portsc2 = inw (io_addr + 18);
+
+ dbg(" usbcmd = %04x %s%s%s%s%s%s%s%s",
+ usbcmd,
+ (usbcmd & USBCMD_MAXP) ? "Maxp64 " : "Maxp32 ",
+ (usbcmd & USBCMD_CF) ? "CF " : "",
+ (usbcmd & USBCMD_SWDBG) ? "SWDBG " : "",
+ (usbcmd & USBCMD_FGR) ? "FGR " : "",
+ (usbcmd & USBCMD_EGSM) ? "EGSM " : "",
+ (usbcmd & USBCMD_GRESET) ? "GRESET " : "",
+ (usbcmd & USBCMD_HCRESET) ? "HCRESET " : "",
+ (usbcmd & USBCMD_RS) ? "RS " : "");
+
+ dbg(" usbstat = %04x %s%s%s%s%s%s",
+ usbstat,
+ (usbstat & USBSTS_HCH) ? "HCHalted " : "",
+ (usbstat & USBSTS_HCPE) ? "HostControllerProcessError " : "",
+ (usbstat & USBSTS_HSE) ? "HostSystemError " : "",
+ (usbstat & USBSTS_RD) ? "ResumeDetect " : "",
+ (usbstat & USBSTS_ERROR) ? "USBError " : "",
+ (usbstat & USBSTS_USBINT) ? "USBINT " : "");
+
+ dbg(" usbint = %04x", usbint);
+ dbg(" usbfrnum = (%d)%03x", (usbfrnum >> 10) & 1,
+ 0xfff & (4 * (unsigned int) usbfrnum));
+ dbg(" flbaseadd = %08x", flbaseadd);
+ dbg(" sof = %02x", sof);
+ uhci_show_sc (1, portsc1);
+ uhci_show_sc (2, portsc2);
+}
+#endif
diff --git a/drivers/usb/usb-core.c b/drivers/usb/usb-core.c
index f0b30bf93..68927a086 100644
--- a/drivers/usb/usb-core.c
+++ b/drivers/usb/usb-core.c
@@ -32,6 +32,7 @@ void usb_major_cleanup(void);
int usb_acm_init(void);
int usb_audio_init(void);
int usb_cpia_init(void);
+int usb_ibmcam_init(void);
int usb_ov511_init(void);
int usb_dc2xx_init(void);
int usb_scanner_init(void);
@@ -98,13 +99,16 @@ int usb_init(void)
#ifdef CONFIG_USB_CPIA
usb_cpia_init();
#endif
+#ifdef CONFIG_USB_IBMCAM
+ usb_ibmcam_init();
+#endif
#ifdef CONFIG_USB_OV511
usb_ov511_init();
#endif
#ifdef CONFIG_USB_DC2XX
usb_dc2xx_init();
#endif
-#ifdef CONFIG_USB_SCSI
+#ifdef CONFIG_USB_STORAGE
usb_stor_init();
#endif
#ifdef CONFIG_USB_DABUSB
@@ -128,7 +132,7 @@ int usb_init(void)
#ifdef CONFIG_USB_UHCI
uhci_init();
#endif
-#ifdef CONFIG_USB_OHCI_HCD
+#ifdef CONFIG_USB_OHCI
ohci_hcd_init();
#endif
#endif
diff --git a/drivers/usb/usb-debug.c b/drivers/usb/usb-debug.c
index 2cca35151..356a4373b 100644
--- a/drivers/usb/usb-debug.c
+++ b/drivers/usb/usb-debug.c
@@ -6,8 +6,8 @@
*/
#include <linux/version.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
-
+#include <linux/mm.h>
+#include <linux/malloc.h>
#define DEBUG
#include "usb.h"
@@ -59,6 +59,11 @@ void usb_show_device(struct usb_device *dev)
*/
void usb_show_device_descriptor(struct usb_device_descriptor *desc)
{
+ if (!desc)
+ {
+ printk("Invalid USB device descriptor (NULL POINTER)\n");
+ return;
+ }
printk(" Length = %2d%s\n", desc->bLength,
desc->bLength == USB_DT_DEVICE_SIZE ? "" : " (!!!)");
printk(" DescriptorType = %02x\n", desc->bDescriptorType);
@@ -160,6 +165,8 @@ void usb_show_string(struct usb_device *dev, char *id, int index)
{
char *buf;
+ if (!index)
+ return;
if (!(buf = kmalloc(256, GFP_KERNEL)))
return;
if (usb_string(dev, index, buf, 256) > 0)
@@ -167,3 +174,23 @@ void usb_show_string(struct usb_device *dev, char *id, int index)
kfree(buf);
}
+void usb_dump_urb (purb_t purb)
+{
+ printk ("urb :%p\n", purb);
+ printk ("next :%p\n", purb->next);
+ printk ("dev :%p\n", purb->dev);
+ printk ("pipe :%08X\n", purb->pipe);
+ printk ("status :%d\n", purb->status);
+ printk ("transfer_flags :%08X\n", purb->transfer_flags);
+ printk ("transfer_buffer :%p\n", purb->transfer_buffer);
+ printk ("transfer_buffer_length:%d\n", purb->transfer_buffer_length);
+ printk ("actual_length :%d\n", purb->actual_length);
+ printk ("setup_packet :%p\n", purb->setup_packet);
+ printk ("start_frame :%d\n", purb->start_frame);
+ printk ("number_of_packets :%d\n", purb->number_of_packets);
+ printk ("interval :%d\n", purb->interval);
+ printk ("error_count :%d\n", purb->error_count);
+ printk ("context :%p\n", purb->context);
+ printk ("complete :%p\n", purb->complete);
+}
+
diff --git a/drivers/usb/ohci-hcd.c b/drivers/usb/usb-ohci.c
index 30274cb85..509c49903 100644
--- a/drivers/usb/ohci-hcd.c
+++ b/drivers/usb/usb-ohci.c
@@ -50,7 +50,7 @@
#define OHCI_USE_NPS
#include "usb.h"
-#include "ohci-hcd.h"
+#include "usb-ohci.h"
#ifdef CONFIG_APM
#include <linux/apm_bios.h>
@@ -544,7 +544,7 @@ static int ep_link (ohci_t * ohci, ed_t * edi)
ohci->ed_controltail->hwNextED = cpu_to_le32 (virt_to_bus (ed));
}
ed->ed_prev = ohci->ed_controltail;
- ohci->ed_controltail = ed;
+ ohci->ed_controltail = edi;
break;
case BULK:
@@ -555,7 +555,7 @@ static int ep_link (ohci_t * ohci, ed_t * edi)
ohci->ed_bulktail->hwNextED = cpu_to_le32 (virt_to_bus (ed));
}
ed->ed_prev = ohci->ed_bulktail;
- ohci->ed_bulktail = ed;
+ ohci->ed_bulktail = edi;
break;
case INT:
@@ -596,7 +596,7 @@ static int ep_link (ohci_t * ohci, ed_t * edi)
}
ed->ed_prev = NULL;
}
- ohci->ed_isotail = ed;
+ ohci->ed_isotail = edi;
#ifdef DEBUG
ep_print_int_eds (ohci, "LINK_ISO");
#endif
@@ -711,13 +711,14 @@ static int ep_unlink (ohci_t * ohci, ed_t * ed)
static ed_t * ep_add_ed (struct usb_device * usb_dev, unsigned int pipe, int interval, int load)
{
ohci_t * ohci = usb_dev->bus->hcpriv;
- td_t * td;
+ td_t * td;
+ ed_t * ed_ret;
volatile ed_t * ed;
spin_lock (&usb_ed_lock);
- ed = &(usb_to_ohci (usb_dev)->ed[(usb_pipeendpoint (pipe) << 1) |
+ 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))
@@ -749,7 +750,7 @@ static ed_t * ep_add_ed (struct usb_device * usb_dev, unsigned int pipe, int int
}
spin_unlock(&usb_ed_lock);
- return ed;
+ return ed_ret;
}
/*-------------------------------------------------------------------------*/
@@ -802,7 +803,7 @@ static void td_fill (unsigned int info, void * data, int len, urb_t * urb, int t
td_pt = urb_priv->td [index];
/* fill the old dummy TD */
- td = (td_t *) bus_to_virt (le32_to_cpup (&urb_priv->ed->hwTailP) & 0xfffffff0);
+ td = urb_priv->td [index] = (td_t *) bus_to_virt (le32_to_cpup (&urb_priv->ed->hwTailP) & 0xfffffff0);
td->ed = urb_priv->ed;
td->index = index;
td->urb = urb;
@@ -820,7 +821,6 @@ static void td_fill (unsigned int info, void * data, int len, urb_t * urb, int t
td->hwPSW [0] = cpu_to_le16 ((virt_to_bus (data) & 0x0FFF) | 0xE000);
td_pt->hwNextTD = 0;
td->ed->hwTailP = td->hwNextTD;
- urb_priv->td [index] = td;
td->next_dl_td = NULL; //td_pt;
}
@@ -1050,11 +1050,10 @@ static void dl_done_list (ohci_t * ohci, td_t * td_list)
}
} else {
if (tdBE != 0) {
- dlen = (bus_to_virt (tdBE) - urb->transfer_buffer + 1);
if (td_list->hwCBP == 0)
- urb->actual_length += dlen;
+ urb->actual_length = bus_to_virt (tdBE) - urb->transfer_buffer + 1;
else
- urb->actual_length += (bus_to_virt(tdCBP) - urb->transfer_buffer);
+ urb->actual_length = bus_to_virt (tdCBP) - urb->transfer_buffer;
}
}
}
diff --git a/drivers/usb/ohci-hcd.h b/drivers/usb/usb-ohci.h
index f3d71154f..6098f0b39 100644
--- a/drivers/usb/ohci-hcd.h
+++ b/drivers/usb/usb-ohci.h
@@ -3,7 +3,7 @@
*
*(C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
*
- * ohci-hcd.h
+ * usb-ohci.h
*
*/
diff --git a/drivers/usb/usb-serial.c b/drivers/usb/usb-serial.c
index 8826bc522..9f37fcc9e 100644
--- a/drivers/usb/usb-serial.c
+++ b/drivers/usb/usb-serial.c
@@ -14,6 +14,24 @@
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
+ * (01/25/2000) gkh
+ * Added initial framework for FTDI serial converter so that Bill Ryder
+ * has a place to put his code.
+ * Added the vendor specific info from Handspring. Now we can print out
+ * informational debug messages as well as understand what is happening.
+ *
+ * (01/23/2000) gkh
+ * Fixed problem of crash when trying to open a port that didn't have a
+ * device assigned to it. Made the minor node finding a little smarter,
+ * now it looks to find a continous space for the new device.
+ *
+ * (01/21/2000) gkh
+ * Fixed bug in visor_startup with patch from Miles Lott (milos@insync.net)
+ * Fixed get_serial_by_minor which was all messed up for multi port
+ * devices. Fixed multi port problem for generic devices. Now the number
+ * of ports is determined by the number of bulk out endpoints for the
+ * generic device.
+ *
* (01/19/2000) gkh
* Removed lots of cruft that was around from the old (pre urb) driver
* interface.
@@ -141,15 +159,16 @@ static void usb_serial_disconnect(struct usb_device *dev, void *ptr);
/* USB Serial devices vendor ids and device ids that this driver supports */
#define BELKIN_VENDOR_ID 0x056c
-#define BELKIN_SERIAL_CONVERTER 0x8007
+#define BELKIN_SERIAL_CONVERTER_ID 0x8007
#define PERACOM_VENDOR_ID 0x0565
-#define PERACOM_SERIAL_CONVERTER 0x0001
+#define PERACOM_SERIAL_CONVERTER_ID 0x0001
#define CONNECT_TECH_VENDOR_ID 0x0710
#define CONNECT_TECH_FAKE_WHITE_HEAT_ID 0x0001
#define CONNECT_TECH_WHITE_HEAT_ID 0x8001
#define HANDSPRING_VENDOR_ID 0x082d
#define HANDSPRING_VISOR_ID 0x0100
-
+#define FTDI_VENDOR_ID 0x0403
+#define FTDI_SERIAL_CONVERTER_ID 0x8372
#define SERIAL_TTY_MAJOR 188 /* Nice legal number now */
#define SERIAL_TTY_MINORS 16 /* Actually we are allowed 255, but this is good for now */
@@ -267,7 +286,7 @@ static void etek_serial_close (struct tty_struct *tty, struct file *filp);
#ifdef CONFIG_USB_SERIAL_BELKIN
/* All of the device info needed for the Belkin Serial Converter */
static __u16 belkin_vendor_id = BELKIN_VENDOR_ID;
-static __u16 belkin_product_id = BELKIN_SERIAL_CONVERTER;
+static __u16 belkin_product_id = BELKIN_SERIAL_CONVERTER_ID;
static struct usb_serial_device_type belkin_device = {
name: "Belkin",
idVendor: &belkin_vendor_id, /* the Belkin vendor id */
@@ -291,7 +310,7 @@ static struct usb_serial_device_type belkin_device = {
#ifdef CONFIG_USB_SERIAL_PERACOM
/* All of the device info needed for the Peracom Serial Converter */
static __u16 peracom_vendor_id = PERACOM_VENDOR_ID;
-static __u16 peracom_product_id = PERACOM_SERIAL_CONVERTER;
+static __u16 peracom_product_id = PERACOM_SERIAL_CONVERTER_ID;
static struct usb_serial_device_type peracom_device = {
name: "Peracom",
idVendor: &peracom_vendor_id, /* the Peracom vendor id */
@@ -359,6 +378,58 @@ static struct usb_serial_device_type whiteheat_device = {
#ifdef CONFIG_USB_SERIAL_VISOR
+
+/****************************************************************************
+ * Handspring Visor Vendor specific request codes (bRequest values)
+ * A big thank you to Handspring for providing the following information.
+ * If anyone wants the original file where these values and structures came
+ * from, send email to <greg@kroah.com>.
+ ****************************************************************************/
+
+/****************************************************************************
+ * VISOR_REQUEST_BYTES_AVAILABLE asks the visor for the number of bytes that
+ * are available to be transfered to the host for the specified endpoint.
+ * Currently this is not used, and always returns 0x0001
+ ****************************************************************************/
+#define VISOR_REQUEST_BYTES_AVAILABLE 0x01
+
+/****************************************************************************
+ * VISOR_CLOSE_NOTIFICATION is set to the device to notify it that the host
+ * is now closing the pipe. An empty packet is sent in response.
+ ****************************************************************************/
+#define VISOR_CLOSE_NOTIFICATION 0x02
+
+/****************************************************************************
+ * VISOR_GET_CONNECTION_INFORMATION is sent by the host during enumeration to
+ * get the endpoints used by the connection.
+ ****************************************************************************/
+#define VISOR_GET_CONNECTION_INFORMATION 0x03
+
+
+/****************************************************************************
+ * VISOR_GET_CONNECTION_INFORMATION returns data in the following format
+ ****************************************************************************/
+struct visor_connection_info {
+ __u16 num_ports;
+ struct {
+ __u8 port_function_id;
+ __u8 port;
+ } connections[2];
+};
+
+
+/* struct visor_connection_info.connection[x].port defines: */
+#define VISOR_ENDPOINT_1 0x01
+#define VISOR_ENDPOINT_2 0x02
+
+/* struct visor_connection_info.connection[x].port_function_id defines: */
+#define VISOR_FUNCTION_GENERIC 0x00
+#define VISOR_FUNCTION_DEBUGGER 0x01
+#define VISOR_FUNCTION_HOTSYNC 0x02
+#define VISOR_FUNCTION_CONSOLE 0x03
+#define VISOR_FUNCTION_REMOTE_FILE_SYS 0x04
+
+
/* function prototypes for a handspring visor */
static int visor_serial_open (struct tty_struct *tty, struct file *filp);
static void visor_serial_close (struct tty_struct *tty, struct file *filp);
@@ -391,6 +462,34 @@ static struct usb_serial_device_type handspring_device = {
};
#endif
+
+#ifdef CONFIG_USB_SERIAL_FTDI
+/* function prototypes for a FTDI serial converter */
+static int ftdi_serial_open (struct tty_struct *tty, struct file *filp);
+static void ftdi_serial_close (struct tty_struct *tty, struct file *filp);
+
+/* All of the device info needed for the Handspring Visor */
+static __u16 ftdi_vendor_id = FTDI_VENDOR_ID;
+static __u16 ftdi_product_id = FTDI_SERIAL_CONVERTER_ID;
+static struct usb_serial_device_type ftdi_device = {
+ name: "FTDI",
+ idVendor: &ftdi_vendor_id, /* the FTDI vendor ID */
+ idProduct: &ftdi_product_id, /* the FTDI product id */
+ needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */
+ needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */
+ needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */
+ num_interrupt_in: 0,
+ num_bulk_in: 1,
+ num_bulk_out: 1,
+ num_ports: 1,
+ open: ftdi_serial_open,
+ close: ftdi_serial_close,
+ write: generic_serial_write,
+ write_room: generic_write_room,
+ chars_in_buffer: generic_chars_in_buffer
+};
+#endif
+
/* To add support for another serial converter, create a usb_serial_device_type
structure for that device, and add it to this list, making sure that the last
entry is NULL. */
@@ -411,6 +510,9 @@ static struct usb_serial_device_type *usb_serial_devices[] = {
#ifdef CONFIG_USB_SERIAL_VISOR
&handspring_device,
#endif
+#ifdef CONFIG_USB_SERIAL_FTDI
+ &ftdi_device,
+#endif
NULL
};
@@ -438,20 +540,27 @@ static struct usb_serial *get_serial_by_minor (int minor)
dbg("get_serial_by_minor %d", minor);
- for (i = 0; i < SERIAL_TTY_MINORS; ++i)
- if (serial_table[i])
- if (serial_table[i] != SERIAL_PTR_EMPTY)
- if (serial_table[i]->minor == minor)
- return (serial_table[i]);
+ if (serial_table[minor] == NULL)
+ return (NULL);
- return (NULL);
+ if (serial_table[minor] != SERIAL_PTR_EMPTY)
+ return (serial_table[minor]);
+
+ i = minor;
+ while (serial_table[i] == SERIAL_PTR_EMPTY) {
+ if (i == 0)
+ return (NULL);
+ --i;
+ }
+ return (serial_table[i]);
}
static struct usb_serial *get_free_serial (int num_ports, int *minor)
{
struct usb_serial *serial = NULL;
- int i;
+ int i, j;
+ int good_spot;
dbg("get_free_serial %d", num_ports);
@@ -459,6 +568,14 @@ static struct usb_serial *get_free_serial (int num_ports, int *minor)
for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
if (serial_table[i])
continue;
+
+ good_spot = 1;
+ for (j = 0; j < num_ports-1; ++j)
+ if (serial_table[i+j])
+ good_spot = 0;
+ if (good_spot == 0)
+ continue;
+
if (!(serial = kmalloc(sizeof(struct usb_serial), GFP_KERNEL))) {
err("Out of memory");
return NULL;
@@ -467,7 +584,7 @@ static struct usb_serial *get_free_serial (int num_ports, int *minor)
serial_table[i] = serial;
*minor = i;
dbg("minor base = %d", *minor);
- for (i = *minor+1; (i < num_ports) && (i < SERIAL_TTY_MINORS); ++i)
+ for (i = *minor+1; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i)
serial_table[i] = SERIAL_PTR_EMPTY;
return (serial);
}
@@ -538,6 +655,9 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
dbg("serial_open");
+ /* initialize the pointer incase something fails */
+ tty->driver_data = NULL;
+
/* get the serial object associated with this tty pointer */
serial = get_serial_by_minor (MINOR(tty->device));
@@ -567,15 +687,20 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
static void serial_close(struct tty_struct *tty, struct file * filp)
{
struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
- int port = MINOR(tty->device) - serial->minor;
+ int port;
+
+ dbg("serial_close");
- dbg("serial_close port %d", port);
-
- /* do some sanity checking that we really have a device present */
if (!serial) {
dbg("serial == NULL!");
return;
}
+
+ port = MINOR(tty->device) - serial->minor;
+
+ dbg("serial_close port %d", port);
+
+ /* do some sanity checking that we really have a device present */
if (!serial->type) {
dbg("serial->type == NULL!");
return;
@@ -997,9 +1122,18 @@ static void visor_serial_close(struct tty_struct *tty, struct file * filp)
{
struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
int port = MINOR(tty->device) - serial->minor;
+ unsigned char *transfer_buffer = kmalloc (0x12, GFP_KERNEL);
dbg("visor_serial_close port %d", port);
+ if (!transfer_buffer) {
+ err("visor_serial_close: kmalloc(%d) failed.\n", 0x12);
+ } else {
+ /* send a shutdown message to the device */
+ usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_CLOSE_NOTIFICATION,
+ 0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 300);
+ }
+
/* shutdown our bulk reads and writes */
usb_unlink_urb (&serial->write_urb[port]);
usb_unlink_urb (&serial->read_urb[port]);
@@ -1034,51 +1168,10 @@ static void visor_unthrottle (struct tty_struct * tty)
}
-/*
- Here's the raw dump of the vendor specific command data that the Visor sends on Win98
-______________________________________________________________________
-SETUP(0xB4) ADDR(0x02) ENDP(0x0) CRC5(0x15)
-______________________________________________________________________
-DATA0(0xC3) DATA(C2 03 00 00 00 00 12 00 ) CRC16(0xB0BB)
-______________________________________________________________________
-ACK(0x4B)
-______________________________________________________________________
-IN(0x96) ADDR(0x02) ENDP(0x0) CRC5(0x15)
-______________________________________________________________________
-DATA1(0xD2) DATA(02 00 00 01 02 02 ) CRC16(0xF4E6)
-______________________________________________________________________
-ACK(0x4B)
-______________________________________________________________________
-OUT(0x87) ADDR(0x02) ENDP(0x0) CRC5(0x15)
-______________________________________________________________________
-DATA1(0xD2) DATA() CRC16(0x0000)
-______________________________________________________________________
-ACK(0x4B)
-______________________________________________________________________
-SETUP(0xB4) ADDR(0x02) ENDP(0x0) CRC5(0x15)
-______________________________________________________________________
-DATA0(0xC3) DATA(C2 01 00 00 05 00 02 00 ) CRC16(0xC488)
-______________________________________________________________________
-ACK(0x4B)
-______________________________________________________________________
-IN(0x96) ADDR(0x02) ENDP(0x0) CRC5(0x15)
-______________________________________________________________________
-DATA1(0xD2) DATA(01 00 ) CRC16(0xFFFB)
-______________________________________________________________________
-ACK(0x4B)
-______________________________________________________________________
-OUT(0x87) ADDR(0x02) ENDP(0x0) CRC5(0x15)
-______________________________________________________________________
-DATA1(0xD2) DATA() CRC16(0x0000)
-______________________________________________________________________
-ACK(0x4B)
-______________________________________________________________________
-*/
-
static int visor_startup (struct usb_serial *serial)
{
- /* send out two unknown commands that I found by looking at a Win98 trace */
int response;
+ int i;
unsigned char *transfer_buffer = kmalloc (256, GFP_KERNEL);
if (!transfer_buffer) {
@@ -1091,18 +1184,44 @@ static int visor_startup (struct usb_serial *serial)
dbg("visor_setup: Set config to 1");
usb_set_configuration (serial->dev, 1);
- response = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), 0x03, 0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 300);
+ /* send a get connection info request */
+ response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_GET_CONNECTION_INFORMATION,
+ 0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 300);
if (response < 0) {
- err("visor_startup: error getting first vendor specific message");
+ err("visor_startup: error getting connection information");
} else {
- dbg("visor_startup: First vendor specific message successful");
+#ifdef DEBUG
+ struct visor_connection_info *connection_info = (struct visor_connection_info *)transfer_buffer;
+ char *string;
+ dbg("%s: Number of ports: %d", serial->type->name, connection_info->num_ports);
+ for (i = 0; i < connection_info->num_ports; ++i) {
+ switch (connection_info->connections[i].port_function_id) {
+ case VISOR_FUNCTION_GENERIC:
+ string = "Generic";
+ break;
+ case VISOR_FUNCTION_DEBUGGER:
+ string = "Debugger";
+ break;
+ case VISOR_FUNCTION_HOTSYNC:
+ string = "HotSync";
+ break;
+ case VISOR_FUNCTION_REMOTE_FILE_SYS:
+ string = "Remote File System";
+ break;
+ default:
+ string = "unknown";
+ break;
+ }
+ dbg("%s: port %d, is for %s", serial->type->name, connection_info->connections[i].port, string);
+ }
+#endif
}
- response = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), 0x01, 0xc2, 0x0000, 0x0005, transfer_buffer, 0x02, 300);
+ /* ask for the number of bytes available, but ignore the response as it is broken */
+ response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_REQUEST_BYTES_AVAILABLE,
+ 0xc2, 0x0000, 0x0005, transfer_buffer, 0x02, 300);
if (response < 0) {
- err("visor_startup: error getting second vendor specific message");
- } else {
- dbg("visor_startup: Second vendor specific message successful");
+ err("visor_startup: error getting bytes available request");
}
kfree (transfer_buffer);
@@ -1115,6 +1234,54 @@ static int visor_startup (struct usb_serial *serial)
#endif /* CONFIG_USB_SERIAL_VISOR*/
+#ifdef CONFIG_USB_SERIAL_FTDI
+/******************************************************************************
+ * FTDI Serial Converter specific driver functions
+ ******************************************************************************/
+static int ftdi_serial_open (struct tty_struct *tty, struct file *filp)
+{
+ struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
+ int port = MINOR(tty->device) - serial->minor;
+
+ dbg("ftdi_serial_open port %d", port);
+
+ if (serial->active[port]) {
+ dbg ("device already open");
+ return -EINVAL;
+ }
+ serial->active[port] = 1;
+
+ /*Start reading from the device*/
+ if (usb_submit_urb(&serial->read_urb[port]))
+ dbg("usb_submit_urb(read bulk) failed");
+
+ /* Need to do device specific setup here (control lines, baud rate, etc.) */
+ /* FIXME!!! */
+
+ return (0);
+}
+
+
+static void ftdi_serial_close (struct tty_struct *tty, struct file *filp)
+{
+ struct usb_serial *serial = (struct usb_serial *) tty->driver_data;
+ int port = MINOR(tty->device) - serial->minor;
+
+ dbg("ftdi_serial_close port %d", port);
+
+ /* Need to change the control lines here */
+ /* FIXME */
+
+ /* shutdown our bulk reads and writes */
+ usb_unlink_urb (&serial->write_urb[port]);
+ usb_unlink_urb (&serial->read_urb[port]);
+ serial->active[port] = 0;
+}
+
+
+#endif
+
+
/*****************************************************************************
* generic devices specific driver functions
*****************************************************************************/
@@ -1260,6 +1427,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
int num_interrupt_in = 0;
int num_bulk_in = 0;
int num_bulk_out = 0;
+ int num_ports;
/* loop through our list of known serial converters, and see if this device matches */
device_num = 0;
@@ -1317,7 +1485,14 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
/* found all that we need */
info("%s converter detected", type->name);
- serial = get_free_serial (type->num_ports, &minor);
+#ifdef CONFIG_USB_SERIAL_GENERIC
+ if (type == &generic_device)
+ num_ports = num_bulk_out;
+ else
+#endif
+ num_ports = type->num_ports;
+
+ serial = get_free_serial (num_ports, &minor);
if (serial == NULL) {
err("No more free serial devices");
return NULL;
@@ -1326,7 +1501,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
serial->dev = dev;
serial->type = type;
serial->minor = minor;
- serial->num_ports = type->num_ports;
+ serial->num_ports = num_ports;
serial->num_bulk_in = num_bulk_in;
serial->num_bulk_out = num_bulk_out;
serial->num_interrupt_in = num_interrupt_in;
@@ -1350,7 +1525,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
}
for (i = 0; i < num_bulk_out; ++i) {
- serial->bulk_out_size[i] = bulk_out_endpoint[i]->wMaxPacketSize;
+ serial->bulk_out_size[i] = bulk_out_endpoint[i]->wMaxPacketSize * 2;
serial->bulk_out_buffer[i] = kmalloc (serial->bulk_out_size[i], GFP_KERNEL);
if (!serial->bulk_out_buffer[i]) {
err("Couldn't allocate bulk_out_buffer");
@@ -1417,6 +1592,7 @@ static void usb_serial_disconnect(struct usb_device *dev, void *ptr)
usb_unlink_urb (&serial->write_urb[i]);
usb_unlink_urb (&serial->read_urb[i]);
serial->active[i] = 0;
+ serial_table[serial->minor + i] = NULL;
}
/* free up any memory that we allocated */
@@ -1434,7 +1610,6 @@ static void usb_serial_disconnect(struct usb_device *dev, void *ptr)
info("%s converter now disconnected from ttyUSB%d", serial->type->name, serial->minor + i);
}
- serial_table[serial->minor] = NULL;
kfree (serial);
} else {
diff --git a/drivers/usb/uhci.c b/drivers/usb/usb-uhci.c
index 09dc04283..3fe469699 100644
--- a/drivers/usb/uhci.c
+++ b/drivers/usb/usb-uhci.c
@@ -12,7 +12,7 @@
* (C) Copyright 1999 Johannes Erdfelt
* (C) Copyright 1999 Randy Dunlap
*
- * $Id: uhci.c,v 1.149 1999/12/26 20:57:14 acher Exp $
+ * $Id: usb-uhci.c,v 1.169 2000/01/20 19:50:11 acher Exp $
*/
#include <linux/config.h>
@@ -34,50 +34,45 @@
#include <asm/irq.h>
#include <asm/system.h>
-#undef DEBUG
+/* This enables debug printks */
+//#define DEBUG
+/* This enables all symbols to be exported, to ease debugging oopses */
+#define DEBUG_SYMBOLS
+/* This enables an extra UHCI slab for memory debugging */
+//#define DEBUG_SLAB
#include "usb.h"
-#include "uhci.h"
+#include "usb-uhci.h"
#include "uhci-debug.h"
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-#define __init
-#define __exit
-#endif
-
-#ifdef __alpha
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-extern long __kernel_thread (unsigned long, int (*)(void *), void *);
-static inline long kernel_thread (int (*fn) (void *), void *arg, unsigned long flags)
-{
- return __kernel_thread (flags | CLONE_VM, fn, arg);
-}
-#undef CONFIG_APM
-#endif
-#endif
-
#ifdef CONFIG_APM
#include <linux/apm_bios.h>
static int handle_apm_event (apm_event_t event);
#endif
-/* We added an UHCI_SLAB slab support just for debugging purposes. In real
- life this compile option is NOT recommended, because slab caches are not
- suitable for modules.
-*/
+#ifdef DEBUG_SYMBOLS
+#define _static
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#endif
+#else
+#define _static static
+#endif
-// #define _UHCI_SLAB
-#ifdef _UHCI_SLAB
+#ifdef DEBUG_SLAB
static kmem_cache_t *uhci_desc_kmem;
static kmem_cache_t *urb_priv_kmem;
#endif
-static int rh_submit_urb (purb_t purb);
-static int rh_unlink_urb (purb_t purb);
+_static int rh_submit_urb (purb_t purb);
+_static int rh_unlink_urb (purb_t purb);
static puhci_t devs = NULL;
+/* used by userspace UHCI data structure dumper */
+puhci_t *uhci_devices = &devs;
+
/*-------------------------------------------------------------------*/
-static void queue_urb (puhci_t s, struct list_head *p, int do_lock)
+_static void queue_urb (puhci_t s, struct list_head *p, int do_lock)
{
unsigned long flags=0;
@@ -91,7 +86,7 @@ static void queue_urb (puhci_t s, struct list_head *p, int do_lock)
}
/*-------------------------------------------------------------------*/
-static void dequeue_urb (puhci_t s, struct list_head *p, int do_lock)
+_static void dequeue_urb (puhci_t s, struct list_head *p, int do_lock)
{
unsigned long flags=0;
@@ -105,9 +100,9 @@ static void dequeue_urb (puhci_t s, struct list_head *p, int do_lock)
}
/*-------------------------------------------------------------------*/
-static int alloc_td (puhci_desc_t * new, int flags)
+_static int alloc_td (puhci_desc_t * new, int flags)
{
-#ifdef _UHCI_SLAB
+#ifdef DEBUG_SLAB
*new= kmem_cache_alloc(uhci_desc_kmem, in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL);
#else
*new = (uhci_desc_t *) kmalloc (sizeof (uhci_desc_t), in_interrupt ()? GFP_ATOMIC : GFP_KERNEL);
@@ -119,6 +114,7 @@ static int alloc_td (puhci_desc_t * new, int flags)
(*new)->hw.td.link = UHCI_PTR_TERM | (flags & UHCI_PTR_BITS); // last by default
(*new)->type = TD_TYPE;
+ mb();
INIT_LIST_HEAD (&(*new)->vertical);
INIT_LIST_HEAD (&(*new)->horizontal);
@@ -126,7 +122,7 @@ static int alloc_td (puhci_desc_t * new, int flags)
}
/*-------------------------------------------------------------------*/
/* insert td at last position in td-list of qh (vertical) */
-static int insert_td (puhci_t s, puhci_desc_t qh, puhci_desc_t new, int flags)
+_static int insert_td (puhci_t s, puhci_desc_t qh, puhci_desc_t new, int flags)
{
uhci_desc_t *prev;
unsigned long xxx;
@@ -145,14 +141,14 @@ static int insert_td (puhci_t s, puhci_desc_t qh, puhci_desc_t new, int flags)
// implicitely remove TERM bit of prev
prev->hw.td.link = virt_to_bus (new) | (flags & UHCI_PTR_DEPTH);
}
-
+ mb();
spin_unlock_irqrestore (&s->td_lock, xxx);
return 0;
}
/*-------------------------------------------------------------------*/
/* insert new_td after td (horizontal) */
-static int insert_td_horizontal (puhci_t s, puhci_desc_t td, puhci_desc_t new, int flags)
+_static int insert_td_horizontal (puhci_t s, puhci_desc_t td, puhci_desc_t new, int flags)
{
uhci_desc_t *next;
unsigned long xxx;
@@ -161,15 +157,16 @@ static int insert_td_horizontal (puhci_t s, puhci_desc_t td, puhci_desc_t new, i
next = list_entry (td->horizontal.next, uhci_desc_t, horizontal);
new->hw.td.link = td->hw.td.link;
+ mb();
list_add (&new->horizontal, &td->horizontal);
td->hw.td.link = virt_to_bus (new);
-
+ mb();
spin_unlock_irqrestore (&s->td_lock, xxx);
return 0;
}
/*-------------------------------------------------------------------*/
-static int unlink_td (puhci_t s, puhci_desc_t element)
+_static int unlink_td (puhci_t s, puhci_desc_t element)
{
uhci_desc_t *next, *prev;
int dir = 0;
@@ -193,7 +190,7 @@ static int unlink_td (puhci_t s, puhci_desc_t element)
else
prev->hw.qh.element = element->hw.td.link;
- wmb ();
+ mb ();
if (dir == 0)
list_del (&element->vertical);
@@ -205,9 +202,9 @@ static int unlink_td (puhci_t s, puhci_desc_t element)
return 0;
}
/*-------------------------------------------------------------------*/
-static int delete_desc (puhci_desc_t element)
+_static int delete_desc (puhci_desc_t element)
{
-#ifdef _UHCI_SLAB
+#ifdef DEBUG_SLAB
kmem_cache_free(uhci_desc_kmem, element);
#else
kfree (element);
@@ -216,9 +213,9 @@ static int delete_desc (puhci_desc_t element)
}
/*-------------------------------------------------------------------*/
// Allocates qh element
-static int alloc_qh (puhci_desc_t * new)
+_static int alloc_qh (puhci_desc_t * new)
{
-#ifdef _UHCI_SLAB
+#ifdef DEBUG_SLAB
*new= kmem_cache_alloc(uhci_desc_kmem, in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL);
#else
*new = (uhci_desc_t *) kmalloc (sizeof (uhci_desc_t), in_interrupt ()? GFP_ATOMIC : GFP_KERNEL);
@@ -230,6 +227,7 @@ static int alloc_qh (puhci_desc_t * new)
(*new)->hw.qh.head = UHCI_PTR_TERM;
(*new)->hw.qh.element = UHCI_PTR_TERM;
(*new)->type = QH_TYPE;
+ mb();
INIT_LIST_HEAD (&(*new)->horizontal);
INIT_LIST_HEAD (&(*new)->vertical);
@@ -240,7 +238,7 @@ static int alloc_qh (puhci_desc_t * new)
/*-------------------------------------------------------------------*/
// inserts new qh before/after the qh at pos
// flags: 0: insert before pos, 1: insert after pos (for low speed transfers)
-static int insert_qh (puhci_t s, puhci_desc_t pos, puhci_desc_t new, int flags)
+_static int insert_qh (puhci_t s, puhci_desc_t pos, puhci_desc_t new, int flags)
{
puhci_desc_t old;
unsigned long xxx;
@@ -252,7 +250,7 @@ static int insert_qh (puhci_t s, puhci_desc_t pos, puhci_desc_t new, int flags)
old = list_entry (pos->horizontal.prev, uhci_desc_t, horizontal);
list_add_tail (&new->horizontal, &pos->horizontal);
new->hw.qh.head = MAKE_QH_ADDR (pos) ;
-
+ mb();
if (!(old->hw.qh.head & UHCI_PTR_TERM))
old->hw.qh.head = MAKE_QH_ADDR (new) ;
}
@@ -260,18 +258,19 @@ static int insert_qh (puhci_t s, puhci_desc_t pos, puhci_desc_t new, int flags)
// (POS) (OLD) -> (POS) (NEW) (OLD)
old = list_entry (pos->horizontal.next, uhci_desc_t, horizontal);
list_add (&new->horizontal, &pos->horizontal);
- pos->hw.qh.head = MAKE_QH_ADDR (new) ;
new->hw.qh.head = MAKE_QH_ADDR (old);
+ mb();
+ pos->hw.qh.head = MAKE_QH_ADDR (new) ;
}
- wmb ();
+ mb ();
spin_unlock_irqrestore (&s->qh_lock, xxx);
return 0;
}
/*-------------------------------------------------------------------*/
-static int unlink_qh (puhci_t s, puhci_desc_t element)
+_static int unlink_qh (puhci_t s, puhci_desc_t element)
{
puhci_desc_t next, prev;
unsigned long xxx;
@@ -281,7 +280,7 @@ static int unlink_qh (puhci_t s, puhci_desc_t element)
next = list_entry (element->horizontal.next, uhci_desc_t, horizontal);
prev = list_entry (element->horizontal.prev, uhci_desc_t, horizontal);
prev->hw.qh.head = element->hw.qh.head;
- wmb ();
+ mb ();
list_del (&element->horizontal);
spin_unlock_irqrestore (&s->qh_lock, xxx);
@@ -289,7 +288,7 @@ static int unlink_qh (puhci_t s, puhci_desc_t element)
return 0;
}
/*-------------------------------------------------------------------*/
-static int delete_qh (puhci_t s, puhci_desc_t qh)
+_static int delete_qh (puhci_t s, puhci_desc_t qh)
{
puhci_desc_t td;
struct list_head *p;
@@ -307,7 +306,7 @@ static int delete_qh (puhci_t s, puhci_desc_t qh)
return 0;
}
/*-------------------------------------------------------------------*/
-void clean_td_chain (puhci_desc_t td)
+_static void clean_td_chain (puhci_desc_t td)
{
struct list_head *p;
puhci_desc_t td1;
@@ -324,7 +323,7 @@ void clean_td_chain (puhci_desc_t td)
}
/*-------------------------------------------------------------------*/
// Removes ALL qhs in chain (paranoia!)
-static void cleanup_skel (puhci_t s)
+_static void cleanup_skel (puhci_t s)
{
unsigned int n;
puhci_desc_t td;
@@ -367,11 +366,12 @@ static void cleanup_skel (puhci_t s)
if (s->chain_end)
kfree (s->chain_end);
}
+ dbg("cleanup_skel finished");
}
/*-------------------------------------------------------------------*/
// allocates framelist and qh-skeletons
// only HW-links provide continous linking, SW-links stay in their domain (ISO/INT)
-static int init_skel (puhci_t s)
+_static int init_skel (puhci_t s)
{
int n, ret;
puhci_desc_t qh, td;
@@ -442,27 +442,32 @@ static int init_skel (puhci_t s)
goto init_skel_cleanup;
s->int_chain[n] = td;
if (n == 0) {
- s->int_chain[0]->hw.td.link = virt_to_bus (s->control_chain);
+ s->int_chain[0]->hw.td.link = virt_to_bus (s->control_chain) | UHCI_PTR_QH;
}
else {
s->int_chain[n]->hw.td.link = virt_to_bus (s->int_chain[0]);
}
}
- dbg("linking skeleton INT-TDs");
+ dbg("Linking skeleton INT-TDs");
for (n = 0; n < 1024; n++) {
// link all iso-tds to the interrupt chains
int m, o;
- //dbg("framelist[%i]=%x",n,s->framelist[n]);
- for (o = 1, m = 2; m <= 128; o++, m += m) {
- // n&(m-1) = n%m
- if ((n & (m - 1)) == ((m - 1) / 2)) {
- ((puhci_desc_t) s->iso_td[n])->hw.td.link = virt_to_bus (s->int_chain[o]);
+ dbg("framelist[%i]=%x",n,s->framelist[n]);
+ if ((n&127)==127)
+ ((puhci_desc_t) s->iso_td[n])->hw.td.link = virt_to_bus(s->int_chain[0]);
+ else {
+ for (o = 1, m = 2; m <= 128; o++, m += m) {
+ // n&(m-1) = n%m
+ if ((n & (m - 1)) == ((m - 1) / 2)) {
+ ((puhci_desc_t) s->iso_td[n])->hw.td.link = virt_to_bus (s->int_chain[o]);
+ }
}
}
}
+ mb();
//uhci_show_queue(s->control_chain);
dbg("init_skel exit");
return 0; // OK
@@ -473,7 +478,7 @@ static int init_skel (puhci_t s)
}
/*-------------------------------------------------------------------*/
-static void fill_td (puhci_desc_t td, int status, int info, __u32 buffer)
+_static void fill_td (puhci_desc_t td, int status, int info, __u32 buffer)
{
td->hw.td.status = status;
td->hw.td.info = info;
@@ -484,7 +489,7 @@ static void fill_td (puhci_desc_t td, int status, int info, __u32 buffer)
// LOW LEVEL STUFF
// assembles QHs und TDs for control, bulk and iso
/*-------------------------------------------------------------------*/
-static int uhci_submit_control_urb (purb_t purb)
+_static int uhci_submit_control_urb (purb_t purb)
{
puhci_desc_t qh, td;
puhci_t s = (puhci_t) purb->dev->bus->hcpriv;
@@ -532,6 +537,7 @@ static int uhci_submit_control_urb (purb_t purb)
purb->setup_packet[4], purb->setup_packet[5], purb->setup_packet[6], purb->setup_packet[7]);
//uhci_show_td(td);
#endif
+
/* Build the DATA TD's */
len = purb->transfer_buffer_length;
bytesrequested = len;
@@ -587,18 +593,23 @@ static int uhci_submit_control_urb (purb_t purb)
list_add (&qh->desc_list, &purb_priv->desc_list);
+ purb->status = USB_ST_URB_PENDING;
+ queue_urb (s, &purb->urb_list,1); // queue before inserting in desc chain
+
+ //uhci_show_queue(qh);
+
/* Start it up... put low speed first */
if (purb->pipe & TD_CTRL_LS)
insert_qh (s, s->control_chain, qh, 1); // insert after control chain
else
insert_qh (s, s->bulk_chain, qh, 0); // insert before bulk chain
- //uhci_show_queue(s->control_chain);
-
+
+ //uhci_show_queue(qh);
dbg("uhci_submit_control end");
return 0;
}
/*-------------------------------------------------------------------*/
-static int uhci_submit_bulk_urb (purb_t purb)
+_static int uhci_submit_bulk_urb (purb_t purb)
{
puhci_t s = (puhci_t) purb->dev->bus->hcpriv;
purb_priv_t purb_priv = purb->hcpriv;
@@ -669,6 +680,9 @@ static int uhci_submit_bulk_urb (purb_t purb)
list_add (&qh->desc_list, &purb_priv->desc_list);
+ purb->status = USB_ST_URB_PENDING;
+ queue_urb (s, &purb->urb_list,1);
+
insert_qh (s, s->chain_end, qh, 0); // insert before end marker
//uhci_show_queue(s->bulk_chain);
@@ -679,7 +693,7 @@ static int uhci_submit_bulk_urb (purb_t purb)
// unlinks an urb by dequeuing its qh, waits some frames and forgets it
// Problem: unlinking in interrupt requires waiting for one frame (udelay)
// to allow the whole structures to be safely removed
-static int uhci_unlink_urb (purb_t purb)
+_static int uhci_unlink_urb (purb_t purb)
{
puhci_t s;
puhci_desc_t qh;
@@ -697,7 +711,6 @@ static int uhci_unlink_urb (purb_t purb)
return rh_unlink_urb (purb);
if(!in_interrupt()) {
- // is the following really necessary? dequeue_urb has its own spinlock (GA)
spin_lock_irqsave (&s->unlink_urb_lock, flags); // do not allow interrupts
}
@@ -723,7 +736,7 @@ static int uhci_unlink_urb (purb_t purb)
if (in_interrupt ())
udelay (1000);
else
- schedule_timeout (1 + 1 * HZ / 1000);
+ wait_ms(1);
while ((p = purb_priv->desc_list.next) != &purb_priv->desc_list) {
td = list_entry (p, uhci_desc_t, desc_list);
list_del (p);
@@ -741,12 +754,12 @@ static int uhci_unlink_urb (purb_t purb)
if (in_interrupt ())
udelay (1000);
else
- schedule_timeout (1 + 1 * HZ / 1000);
+ wait_ms(1);
delete_qh (s, qh); // remove it physically
}
-#ifdef _UHCI_SLAB
+#ifdef DEBUG_SLAB
kmem_cache_free(urb_priv_kmem, purb->hcpriv);
#else
kfree (purb->hcpriv);
@@ -769,7 +782,7 @@ static int uhci_unlink_urb (purb_t purb)
// In case of ASAP iso transfer, search the URB-list for already queued URBs
// for this EP and calculate the earliest start frame for the new
// URB (easy seamless URB continuation!)
-static int find_iso_limits (purb_t purb, unsigned int *start, unsigned int *end)
+_static int find_iso_limits (purb_t purb, unsigned int *start, unsigned int *end)
{
purb_t u, last_urb = NULL;
puhci_t s = (puhci_t) purb->dev->bus->hcpriv;
@@ -803,32 +816,7 @@ static int find_iso_limits (purb_t purb, unsigned int *start, unsigned int *end)
/*-------------------------------------------------------------------*/
// adjust start_frame according to scheduling constraints (ASAP etc)
-static void jnx_show_desc (puhci_desc_t d)
-{
- switch (d->type) {
- case TD_TYPE:
- dbg("td @ 0x%08lx: link 0x%08x status 0x%08x info 0x%08x buffer 0x%08x",
- (unsigned long) d, d->hw.td.link, d->hw.td.status, d->hw.td.info, d->hw.td.buffer);
- if (!(d->hw.td.link & UHCI_PTR_TERM))
- jnx_show_desc ((puhci_desc_t) bus_to_virt (d->hw.td.link & ~UHCI_PTR_BITS));
- break;
-
- case QH_TYPE:
- dbg("qh @ 0x%08lx: head 0x%08x element 0x%08x",
- (unsigned long) d, d->hw.qh.head, d->hw.qh.element);
- if (!(d->hw.qh.element & UHCI_PTR_TERM))
- jnx_show_desc ((puhci_desc_t) bus_to_virt (d->hw.qh.element & ~UHCI_PTR_BITS));
- if (!(d->hw.qh.head & UHCI_PTR_TERM))
- jnx_show_desc ((puhci_desc_t) bus_to_virt (d->hw.qh.head & ~UHCI_PTR_BITS));
- break;
-
- default:
- dbg("desc @ 0x%08lx: invalid type %u", (unsigned long) d, d->type);
- }
-}
-
-/*-------------------------------------------------------------------*/
-static int iso_find_start (purb_t purb)
+_static int iso_find_start (purb_t purb)
{
puhci_t s = (puhci_t) purb->dev->bus->hcpriv;
unsigned int now;
@@ -856,6 +844,8 @@ static int iso_find_start (purb_t purb)
dbg("iso_find_start: warning, ASAP gap, should not happen");
dbg("iso_find_start: now %u start_frame %u number_of_packets %u pipe 0x%08x",
now, purb->start_frame, purb->number_of_packets, purb->pipe);
+// The following code is only for debugging purposes...
+#if 0
{
puhci_t s = (puhci_t) purb->dev->bus->hcpriv;
struct list_head *p;
@@ -879,19 +869,10 @@ static int iso_find_start (purb_t purb)
b = (u->start_frame + u->number_of_packets - 1) & 1023;
}
spin_unlock_irqrestore(&s->urb_list_lock, flags);
-#if 0
- if (a != -1 && b != -1) {
- do {
- jnx_show_desc (s->iso_td[a]);
- a = (a + 1) & 1023;
- }
- while (a != b);
- }
-#endif
}
+#endif
purb->start_frame = (now + 5) & 1023; // 5ms setup should be enough //FIXME!
//return -EAGAIN; //FIXME
-
}
}
}
@@ -906,6 +887,7 @@ static int iso_find_start (purb_t purb)
/* check if either start_frame or start_frame+number_of_packets-1 lies between start_limit and stop_limit */
if (limits)
return 0;
+
if (((purb->start_frame - start_limit) & 1023) < queued_size ||
((purb->start_frame + purb->number_of_packets - 1 - start_limit) & 1023) < queued_size) {
dbg("iso_find_start: start_frame %u number_of_packets %u start_limit %u stop_limit %u",
@@ -920,7 +902,7 @@ static int iso_find_start (purb_t purb)
// ASAP-flag set implicitely
// if period==0, the the transfer is only done once (usb_scsi need this...)
-static int uhci_submit_int_urb (purb_t purb)
+_static int uhci_submit_int_urb (purb_t purb)
{
puhci_t s = (puhci_t) purb->dev->bus->hcpriv;
purb_priv_t purb_priv = purb->hcpriv;
@@ -965,7 +947,7 @@ static int uhci_submit_int_urb (purb_t purb)
return -ENOMEM;
status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC |
- (purb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (1 << 27);
+ (purb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27);
destination = (purb->pipe & PIPE_DEVEP_MASK) | usb_packetid (purb->pipe) |
(((purb->transfer_buffer_length - 1) & 0x7ff) << 21);
@@ -975,6 +957,10 @@ static int uhci_submit_int_urb (purb_t purb)
fill_td (td, status, info, virt_to_bus (purb->transfer_buffer));
list_add_tail (&td->desc_list, &purb_priv->desc_list);
+
+ purb->status = USB_ST_URB_PENDING;
+ queue_urb (s, &purb->urb_list,1);
+
insert_td_horizontal (s, s->int_chain[nint], td, UHCI_PTR_DEPTH); // store in INT-TDs
usb_dotoggle (purb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe));
@@ -989,11 +975,13 @@ static int uhci_submit_int_urb (purb_t purb)
return 0;
}
/*-------------------------------------------------------------------*/
-static int uhci_submit_iso_urb (purb_t purb)
+_static int uhci_submit_iso_urb (purb_t purb)
{
puhci_t s = (puhci_t) purb->dev->bus->hcpriv;
purb_priv_t purb_priv = purb->hcpriv;
- int n, ret;
+ int pipe=purb->pipe;
+ int maxsze = usb_maxpacket (purb->dev, pipe, usb_pipeout (pipe));
+ int n, ret, last=0;
puhci_desc_t td, *tdm;
int status, destination;
unsigned long flags;
@@ -1022,6 +1010,11 @@ static int uhci_submit_iso_urb (purb_t purb)
tdm[n] = 0;
continue;
}
+ if(purb->iso_frame_desc[n].length > maxsze) {
+ err("submit_iso: purb->iso_frame_desc[%d].length(%d)>%d",n , purb->iso_frame_desc[n].length, maxsze);
+ tdm[n] = 0;
+ continue;
+ }
ret = alloc_td (&td, UHCI_PTR_DEPTH);
if (ret) {
int i; // Cleanup allocated TDs
@@ -1033,6 +1026,7 @@ static int uhci_submit_iso_urb (purb_t purb)
ret = -ENOMEM;
goto err;
}
+ last=n;
tdm[n] = td;
}
@@ -1040,17 +1034,24 @@ static int uhci_submit_iso_urb (purb_t purb)
destination = (purb->pipe & PIPE_DEVEP_MASK) | usb_packetid (purb->pipe);
+
// Queue all allocated TDs
for (n = 0; n < purb->number_of_packets; n++) {
td = tdm[n];
if (!td)
continue;
- if (n + 1 >= purb->number_of_packets)
+
+ if (n == last)
status |= TD_CTRL_IOC;
fill_td (td, status, destination | (((purb->iso_frame_desc[n].length - 1) & 0x7ff) << 21),
virt_to_bus (purb->transfer_buffer + purb->iso_frame_desc[n].offset));
list_add_tail (&td->desc_list, &purb_priv->desc_list);
+
+ if (n == last) {
+ purb->status = USB_ST_URB_PENDING;
+ queue_urb (s, &purb->urb_list,1);
+ }
insert_td_horizontal (s, s->iso_td[(purb->start_frame + n) & 1023], td, UHCI_PTR_DEPTH); // store in iso-tds
//uhci_show_td(td);
@@ -1066,33 +1067,31 @@ static int uhci_submit_iso_urb (purb_t purb)
}
/*-------------------------------------------------------------------*/
-static int search_dev_ep (puhci_t s, purb_t purb)
+_static int search_dev_ep (puhci_t s, purb_t purb)
{
unsigned long flags;
struct list_head *p = s->urb_list.next;
purb_t tmp;
+ unsigned int mask = usb_pipecontrol(purb->pipe) ? (~USB_DIR_IN) : (~0);
dbg("search_dev_ep:");
spin_lock_irqsave (&s->urb_list_lock, flags);
-
for (; p != &s->urb_list; p = p->next) {
tmp = list_entry (p, urb_t, urb_list);
dbg("urb: %p", tmp);
// we can accept this urb if it is not queued at this time
// or if non-iso transfer requests should be scheduled for the same device and pipe
- if ((usb_pipetype (purb->pipe) != PIPE_ISOCHRONOUS &&
- tmp->dev == purb->dev && tmp->pipe == purb->pipe) || (purb == tmp)) {
+ if ((!usb_pipeisoc(purb->pipe) && tmp->dev == purb->dev && !((tmp->pipe ^ purb->pipe) & mask)) ||
+ (purb == tmp)) {
spin_unlock_irqrestore (&s->urb_list_lock, flags);
return 1; // found another urb already queued for processing
}
}
-
spin_unlock_irqrestore (&s->urb_list_lock, flags);
-
return 0;
}
/*-------------------------------------------------------------------*/
-static int uhci_submit_urb (purb_t purb)
+_static int uhci_submit_urb (purb_t purb)
{
puhci_t s;
purb_priv_t purb_priv;
@@ -1115,7 +1114,7 @@ static int uhci_submit_urb (purb_t purb)
}
-#ifdef _UHCI_SLAB
+#ifdef DEBUG_SLAB
purb_priv = kmem_cache_alloc(urb_priv_kmem, in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL);
#else
purb_priv = kmalloc (sizeof (urb_priv_t), in_interrupt ()? GFP_ATOMIC : GFP_KERNEL);
@@ -1152,25 +1151,25 @@ static int uhci_submit_urb (purb_t purb)
if (ret != USB_ST_NOERROR) {
usb_dec_dev_use (purb->dev);
-#ifdef _UHCI_SLAB
+#ifdef DEBUG_SLAB
kmem_cache_free(urb_priv_kmem, purb_priv);
#else
kfree (purb_priv);
#endif
return ret;
}
-
+/*
purb->status = USB_ST_URB_PENDING;
queue_urb (s, &purb->urb_list,1);
dbg("submit_urb: exit");
-
+*/
return 0;
}
/*-------------------------------------------------------------------
Virtual Root Hub
-------------------------------------------------------------------*/
-static __u8 root_hub_dev_des[] =
+_static __u8 root_hub_dev_des[] =
{
0x12, /* __u8 bLength; */
0x01, /* __u8 bDescriptorType; Device */
@@ -1194,7 +1193,7 @@ static __u8 root_hub_dev_des[] =
/* Configuration descriptor */
-static __u8 root_hub_config_des[] =
+_static __u8 root_hub_config_des[] =
{
0x09, /* __u8 bLength; */
0x02, /* __u8 bDescriptorType; Configuration */
@@ -1229,7 +1228,7 @@ static __u8 root_hub_config_des[] =
};
-static __u8 root_hub_hub_des[] =
+_static __u8 root_hub_hub_des[] =
{
0x09, /* __u8 bLength; */
0x29, /* __u8 bDescriptorType; Hub-descriptor */
@@ -1244,7 +1243,7 @@ static __u8 root_hub_hub_des[] =
/*-------------------------------------------------------------------------*/
/* prepare Interrupt pipe transaction data; HUB INTERRUPT ENDPOINT */
-static int rh_send_irq (purb_t purb)
+_static int rh_send_irq (purb_t purb)
{
int len = 1;
@@ -1273,9 +1272,9 @@ static int rh_send_irq (purb_t purb)
/*-------------------------------------------------------------------------*/
/* Virtual Root Hub INTs are polled by this timer every "intervall" ms */
-static int rh_init_int_timer (purb_t purb);
+_static int rh_init_int_timer (purb_t purb);
-static void rh_int_timer_do (unsigned long ptr)
+_static void rh_int_timer_do (unsigned long ptr)
{
int len;
@@ -1295,7 +1294,7 @@ static void rh_int_timer_do (unsigned long ptr)
/*-------------------------------------------------------------------------*/
/* Root Hub INTs are polled by this timer */
-static int rh_init_int_timer (purb_t purb)
+_static int rh_init_int_timer (purb_t purb)
{
puhci_t uhci = purb->dev->bus->hcpriv;
@@ -1329,7 +1328,7 @@ static int rh_init_int_timer (purb_t purb)
*************************/
-static int rh_submit_urb (purb_t purb)
+_static int rh_submit_urb (purb_t purb)
{
struct usb_device *usb_dev = purb->dev;
puhci_t uhci = usb_dev->bus->hcpriv;
@@ -1519,7 +1518,7 @@ static int rh_submit_urb (purb_t purb)
}
/*-------------------------------------------------------------------------*/
-static int rh_unlink_urb (purb_t purb)
+_static int rh_unlink_urb (purb_t purb)
{
puhci_t uhci = purb->dev->bus->hcpriv;
@@ -1530,49 +1529,47 @@ static int rh_unlink_urb (purb_t purb)
}
/*-------------------------------------------------------------------*/
-#define UHCI_DEBUG
-
/*
* Map status to standard result codes
*
* <status> is (td->status & 0xFE0000) [a.k.a. uhci_status_bits(td->status)
* <dir_out> is True for output TDs and False for input TDs.
*/
-static int uhci_map_status (int status, int dir_out)
+_static int uhci_map_status (int status, int dir_out)
{
if (!status)
return USB_ST_NOERROR;
if (status & TD_CTRL_BITSTUFF) /* Bitstuff error */
- return USB_ST_BITSTUFF;
+ return -EPROTO;
if (status & TD_CTRL_CRCTIMEO) { /* CRC/Timeout */
if (dir_out)
- return USB_ST_NORESPONSE;
+ return -ETIMEDOUT;
else
- return USB_ST_CRC;
+ return -EILSEQ;
}
if (status & TD_CTRL_NAK) /* NAK */
- return USB_ST_TIMEOUT;
+ return -ETIMEDOUT;
if (status & TD_CTRL_BABBLE) /* Babble */
return -EPIPE;
if (status & TD_CTRL_DBUFERR) /* Buffer error */
- return USB_ST_BUFFERUNDERRUN;
+ return -ENOSR;
if (status & TD_CTRL_STALLED) /* Stalled */
return -EPIPE;
if (status & TD_CTRL_ACTIVE) /* Active */
return USB_ST_NOERROR;
- return USB_ST_INTERNALERROR;
+ return -EPROTO;
}
/*
* Only the USB core should call uhci_alloc_dev and uhci_free_dev
*/
-static int uhci_alloc_dev (struct usb_device *usb_dev)
+_static int uhci_alloc_dev (struct usb_device *usb_dev)
{
return 0;
}
-static int uhci_free_dev (struct usb_device *usb_dev)
+_static int uhci_free_dev (struct usb_device *usb_dev)
{
return 0;
}
@@ -1582,7 +1579,7 @@ static int uhci_free_dev (struct usb_device *usb_dev)
*
* returns the current frame number for a USB bus/controller.
*/
-static int uhci_get_current_frame_number (struct usb_device *usb_dev)
+_static int uhci_get_current_frame_number (struct usb_device *usb_dev)
{
return UHCI_GET_CURRENT_FRAME ((puhci_t) usb_dev->bus->hcpriv);
}
@@ -1606,7 +1603,7 @@ struct usb_operations uhci_device_operations =
* when the transfered length fits exactly in maxsze-packets. A bit
* more intelligence is needed to detect this and finish without error.
*/
-static int process_transfer (puhci_t s, purb_t purb)
+_static int process_transfer (puhci_t s, purb_t purb)
{
int ret = USB_ST_NOERROR;
purb_priv_t purb_priv = purb->hcpriv;
@@ -1666,7 +1663,7 @@ static int process_transfer (puhci_t s, purb_t purb)
purb->actual_length += actual_length;
#if 0
- if (i++==0)
+ // if (i++==0)
uhci_show_td (desc); // show first TD of each transfer
#endif
@@ -1681,9 +1678,11 @@ static int process_transfer (puhci_t s, purb_t purb)
// short read during control-IN: re-start status stage
if ((usb_pipetype (purb->pipe) == PIPE_CONTROL)) {
if (uhci_packetid(last_desc->hw.td.info) == USB_PID_OUT) {
- uhci_show_td (last_desc);
+
qh->hw.qh.element = virt_to_bus (last_desc); // re-trigger status stage
- info("short packet during control transfer, retrigger status stage @ %p",last_desc);
+ dbg("short packet during control transfer, retrigger status stage @ %p",last_desc);
+ uhci_show_td (desc);
+ uhci_show_td (last_desc);
purb_priv->short_control_packet=1;
return 0;
}
@@ -1707,6 +1706,7 @@ static int process_transfer (puhci_t s, purb_t purb)
status & TD_CTRL_ACTIVE &&
status & TD_CTRL_NAK )
{
+ dbg("APS WORKAROUND");
ret=0;
status=0;
}
@@ -1719,18 +1719,23 @@ static int process_transfer (puhci_t s, purb_t purb)
dbg("process_transfer: urb %p, wanted len %d, len %d status %x err %d",
purb,purb->transfer_buffer_length,purb->actual_length, purb->status, purb->error_count);
//dbg("process_transfer: exit");
+#if 0
+ if (purb->actual_length){
+ char *uu;
+ uu=purb->transfer_buffer;
+ dbg("%x %x %x %x %x %x %x %x",
+ *uu,*(uu+1),*(uu+2),*(uu+3),*(uu+4),*(uu+5),*(uu+6),*(uu+7));
+ }
+#endif
return ret;
}
-static int process_interrupt (puhci_t s, purb_t purb)
+_static int process_interrupt (puhci_t s, purb_t purb)
{
int i, ret = USB_ST_URB_PENDING;
purb_priv_t purb_priv = purb->hcpriv;
struct list_head *p = purb_priv->desc_list.next;
puhci_desc_t desc = list_entry (purb_priv->desc_list.prev, uhci_desc_t, desc_list);
- int data_toggle = usb_gettoggle (purb->dev, usb_pipeendpoint (purb->pipe),
- usb_pipeout (purb->pipe)); // save initial data_toggle
- // extracted and remapped info from TD
int actual_length;
int status = USB_ST_NOERROR;
@@ -1764,6 +1769,7 @@ static int process_interrupt (puhci_t s, purb_t purb)
// if any error occured: ignore this td, and continue
if (status != USB_ST_NOERROR) {
+ uhci_show_td (desc);
purb->error_count++;
goto recycle;
}
@@ -1772,23 +1778,28 @@ static int process_interrupt (puhci_t s, purb_t purb)
// FIXME: SPD?
- data_toggle = uhci_toggle (desc->hw.td.info);
-
- if (purb->complete && status != USB_ST_TIMEOUT) {
- // for last td, no user completion is needed
- dbg("process_interrupt: calling completion");
+ recycle:
+ if (purb->complete) {
+ //dbg("process_interrupt: calling completion, status %i",status);
purb->status = status;
purb->complete ((struct urb *) purb);
purb->status = USB_ST_URB_PENDING;
}
- recycle:
+
// Recycle INT-TD if interval!=0, else mark TD as one-shot
if (purb->interval) {
- desc->hw.td.status |= TD_CTRL_ACTIVE;
desc->hw.td.info &= ~(1 << TD_TOKEN_TOGGLE);
- desc->hw.td.info |= (usb_gettoggle (purb->dev, usb_pipeendpoint (purb->pipe),
- usb_pipeout (purb->pipe)) << TD_TOKEN_TOGGLE);
- usb_dotoggle (purb->dev, usb_pipeendpoint (purb->pipe), usb_pipeout (purb->pipe));
+ if (status==0) {
+ desc->hw.td.info |= (usb_gettoggle (purb->dev, usb_pipeendpoint (purb->pipe),
+ usb_pipeout (purb->pipe)) << TD_TOKEN_TOGGLE);
+ usb_dotoggle (purb->dev, usb_pipeendpoint (purb->pipe), usb_pipeout (purb->pipe));
+ } else {
+ desc->hw.td.info |= (!usb_gettoggle (purb->dev, usb_pipeendpoint (purb->pipe),
+ usb_pipeout (purb->pipe)) << TD_TOKEN_TOGGLE);
+ }
+ desc->hw.td.status= (purb->pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC |
+ (purb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27);
+ wmb();
}
else {
desc->hw.td.status &= ~TD_CTRL_IOC; // inactivate TD
@@ -1799,7 +1810,7 @@ static int process_interrupt (puhci_t s, purb_t purb)
}
-static int process_iso (puhci_t s, purb_t purb)
+_static int process_iso (puhci_t s, purb_t purb)
{
int i;
int ret = USB_ST_NOERROR;
@@ -1821,10 +1832,12 @@ static int process_iso (puhci_t s, purb_t purb)
//uhci_show_td(desc);
if (desc->hw.td.status & TD_CTRL_ACTIVE) {
// means we have completed the last TD, but not the TDs before
+ desc->hw.td.status &= ~TD_CTRL_ACTIVE;
dbg("TD still active (%x)- grrr. paranoia!", desc->hw.td.status);
ret = USB_ST_PARTIAL_ERROR;
purb->iso_frame_desc[i].status = ret;
unlink_td (s, desc);
+ // FIXME: immediate deletion may be dangerous
goto err;
}
@@ -1864,7 +1877,7 @@ static int process_iso (puhci_t s, purb_t purb)
}
-static int process_urb (puhci_t s, struct list_head *p)
+_static int process_urb (puhci_t s, struct list_head *p)
{
int ret = USB_ST_NOERROR;
purb_t purb;
@@ -1893,7 +1906,7 @@ static int process_urb (puhci_t s, struct list_head *p)
dbg("dequeued urb: %p", purb);
dequeue_urb (s, p, 1);
-#ifdef _UHCI_SLAB
+#ifdef DEBUG_SLAB
kmem_cache_free(urb_priv_kmem, purb->hcpriv);
#else
kfree (purb->hcpriv);
@@ -1947,7 +1960,7 @@ static int process_urb (puhci_t s, struct list_head *p)
return ret;
}
-static void uhci_interrupt (int irq, void *__uhci, struct pt_regs *regs)
+_static void uhci_interrupt (int irq, void *__uhci, struct pt_regs *regs)
{
puhci_t s = __uhci;
unsigned int io_addr = s->io_addr;
@@ -1958,14 +1971,23 @@ static void uhci_interrupt (int irq, void *__uhci, struct pt_regs *regs)
* Read the interrupt status, and write it back to clear the
* interrupt cause
*/
- dbg("interrupt");
+
status = inw (io_addr + USBSTS);
if (!status) /* shared interrupt, not mine */
return;
+ dbg("interrupt");
+
if (status != 1) {
- dbg("interrupt, status %x", status);
+ warn("interrupt, status %x", status);
+
+ // remove host controller halted state
+ if ((status&0x20) && (s->running)) {
+ // more to be done - check TDs for invalid entries
+ // but TDs are only invalid if somewhere else is a (memory ?) problem
+ outw (USBCMD_RS | inw(io_addr + USBCMD), io_addr + USBCMD);
+ }
//uhci_show_status (s);
}
//beep(1000);
@@ -1995,10 +2017,10 @@ static void uhci_interrupt (int irq, void *__uhci, struct pt_regs *regs)
#ifdef __alpha
mb (); // ?
#endif
- dbg("done");
+ dbg("done\n\n");
}
-static void reset_hc (puhci_t s)
+_static void reset_hc (puhci_t s)
{
unsigned int io_addr = s->io_addr;
@@ -2010,7 +2032,7 @@ static void reset_hc (puhci_t s)
wait_ms (10);
}
-static void start_hc (puhci_t s)
+_static void start_hc (puhci_t s)
{
unsigned int io_addr = s->io_addr;
int timeout = 1000;
@@ -2040,16 +2062,17 @@ static void start_hc (puhci_t s)
/* Run and mark it configured with a 64-byte max packet */
outw (USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD);
s->apm_state = 1;
+ s->running = 1;
}
-static void __exit uhci_cleanup_dev(puhci_t s)
+_static void __exit uhci_cleanup_dev(puhci_t s)
{
struct usb_device *root_hub = s->bus->root_hub;
if (root_hub)
usb_disconnect (&root_hub);
usb_deregister_bus (s->bus);
-
+ s->running = 0;
reset_hc (s);
release_region (s->io_addr, s->io_size);
free_irq (s->irq, s);
@@ -2059,7 +2082,7 @@ static void __exit uhci_cleanup_dev(puhci_t s)
}
-static int __init uhci_start_usb (puhci_t s)
+_static int __init uhci_start_usb (puhci_t s)
{ /* start it up */
/* connect the virtual root hub */
struct usb_device *usb_dev;
@@ -2079,7 +2102,7 @@ static int __init uhci_start_usb (puhci_t s)
return 0;
}
-static int __init alloc_uhci (int irq, unsigned int io_addr, unsigned int io_size)
+_static int __init alloc_uhci (int irq, unsigned int io_addr, unsigned int io_size)
{
puhci_t s;
struct usb_bus *bus;
@@ -2169,7 +2192,7 @@ static int __init alloc_uhci (int irq, unsigned int io_addr, unsigned int io_siz
return 0;
}
-static int __init start_uhci (struct pci_dev *dev)
+_static int __init start_uhci (struct pci_dev *dev)
{
int i;
@@ -2201,7 +2224,7 @@ static int __init start_uhci (struct pci_dev *dev)
}
#ifdef CONFIG_APM
-static int handle_apm_event (apm_event_t event)
+_static int handle_apm_event (apm_event_t event)
{
static int down = 0;
puhci_t s = devs;
@@ -2243,7 +2266,7 @@ int __init uhci_init (void)
u8 type;
int i=0;
-#ifdef _UHCI_SLAB
+#ifdef DEBUG_SLAB
char *slabname=kmalloc(16, GFP_KERNEL);
if(!slabname)
@@ -2313,7 +2336,7 @@ void __exit uhci_cleanup (void)
devs = devs->next;
uhci_cleanup_dev(s);
}
-#ifdef _UHCI_SLAB
+#ifdef DEBUG_SLAB
kmem_cache_shrink(uhci_desc_kmem);
kmem_cache_shrink(urb_priv_kmem);
#endif
diff --git a/drivers/usb/uhci.h b/drivers/usb/usb-uhci.h
index d8ef7f038..2afef1cf1 100644
--- a/drivers/usb/uhci.h
+++ b/drivers/usb/usb-uhci.h
@@ -2,10 +2,10 @@
#define __LINUX_UHCI_H
/*
- $Id: uhci.h,v 1.30 1999/12/15 17:57:25 fliegl Exp $
+ $Id: usb-uhci.h,v 1.31 2000/01/15 22:02:30 acher Exp $
*/
#define MODNAME "usb-uhci"
-#define VERSTR "version v0.9 time " __TIME__ " " __DATE__
+#define VERSTR "version v1.169 time " __TIME__ " " __DATE__
/* Command register */
#define USBCMD 0
@@ -160,6 +160,7 @@ typedef struct uhci {
unsigned int io_addr;
unsigned int io_size;
unsigned int maxports;
+ int running;
int apm_state;
diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c
index 6b02641a9..213f69036 100644
--- a/drivers/usb/usb.c
+++ b/drivers/usb/usb.c
@@ -15,7 +15,7 @@
* It should be considered a slave, with no callbacks. Callbacks
* are evil.
*
- * $Id: usb.c,v 1.39 1999/12/27 15:17:47 acher Exp $
+ * $Id: usb.c,v 1.53 2000/01/14 16:19:09 acher Exp $
*/
#include <linux/config.h>
@@ -486,7 +486,8 @@ urb_t* usb_alloc_urb(int iso_packets)
/*-------------------------------------------------------------------*/
void usb_free_urb(urb_t* urb)
{
- kfree(urb);
+ if(urb)
+ kfree(urb);
}
/*-------------------------------------------------------------------*/
int usb_submit_urb(urb_t *urb)
@@ -515,7 +516,7 @@ int usb_unlink_urb(urb_t *urb)
static void usb_api_blocking_completion(urb_t *urb)
{
api_wrapper_data *awd = (api_wrapper_data *)urb->context;
-
+
if (waitqueue_active(awd->wakeup))
wake_up(awd->wakeup);
#if 0
@@ -541,7 +542,7 @@ static void usb_api_async_completion(urb_t *urb)
*-------------------------------------------------------------------*/
// Starts urb and waits for completion or timeout
-static int usb_start_wait_urb(urb_t *urb, int timeout, unsigned long* rval)
+static int usb_start_wait_urb(urb_t *urb, int timeout, int* actual_length)
{
DECLARE_WAITQUEUE(wait, current);
DECLARE_WAIT_QUEUE_HEAD(wqh);
@@ -551,7 +552,7 @@ static int usb_start_wait_urb(urb_t *urb, int timeout, unsigned long* rval)
awd.wakeup=&wqh;
awd.handler=0;
init_waitqueue_head(&wqh);
- current->state = TASK_UNINTERRUPTIBLE;
+ current->state = TASK_INTERRUPTIBLE;
add_wait_queue(&wqh, &wait);
urb->context=&awd;
status=usb_submit_urb(urb);
@@ -572,15 +573,15 @@ static int usb_start_wait_urb(urb_t *urb, int timeout, unsigned long* rval)
if (!status) {
// timeout
- dbg("usb_control/bulk_msg: timeout");
+ printk("usb_control/bulk_msg: timeout\n");
usb_unlink_urb(urb); // remove urb safely
status=-ETIMEDOUT;
}
else
status=urb->status;
- if (rval)
- *rval=urb->actual_length;
+ if (actual_length)
+ *actual_length=urb->actual_length;
usb_free_urb(urb);
return status;
@@ -593,7 +594,7 @@ int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe,
{
urb_t *urb;
int retv;
- unsigned long length;
+ int length;
urb=usb_alloc_urb(0);
if (!urb)
@@ -601,7 +602,7 @@ int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe,
FILL_CONTROL_URB(urb, usb_dev, pipe, (unsigned char*)cmd, data, len, /* build urb */
(usb_complete_t)usb_api_blocking_completion,0);
-
+
retv=usb_start_wait_urb(urb,timeout, &length);
if (retv < 0)
return retv;
@@ -613,15 +614,25 @@ int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe,
int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype,
__u16 value, __u16 index, void *data, __u16 size, int timeout)
{
- devrequest dr;
-
- dr.requesttype = requesttype;
- dr.request = request;
- dr.value = cpu_to_le16p(&value);
- dr.index = cpu_to_le16p(&index);
- dr.length = cpu_to_le16p(&size);
+ devrequest *dr = kmalloc(sizeof(devrequest), GFP_KERNEL);
+ int ret;
+
+ if(!dr)
+ return -ENOMEM;
+
+ dr->requesttype = requesttype;
+ dr->request = request;
+ dr->value = cpu_to_le16p(&value);
+ dr->index = cpu_to_le16p(&index);
+ dr->length = cpu_to_le16p(&size);
+
//dbg("usb_control_msg");
- return usb_internal_control_msg(dev, pipe, &dr, data, size, timeout);
+
+ ret=usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
+
+ kfree(dr);
+
+ return ret;
}
/*-------------------------------------------------------------------*/
@@ -629,7 +640,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u
/* synchronous behavior */
int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
- void *data, int len, unsigned long *rval, int timeout)
+ void *data, int len, int *actual_length, int timeout)
{
urb_t *urb;
@@ -643,7 +654,7 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
FILL_BULK_URB(urb,usb_dev,pipe,(unsigned char*)data,len, /* build urb */
(usb_complete_t)usb_api_blocking_completion,0);
- return usb_start_wait_urb(urb,timeout,rval);
+ return usb_start_wait_urb(urb,timeout,actual_length);
}
/*-------------------------------------------------------------------*/
@@ -1087,7 +1098,7 @@ int usb_parse_configuration(struct usb_device *dev, struct usb_config_descriptor
for (i = 0; i < config->bNumInterfaces; i++) {
header = (struct usb_descriptor_header *)buffer;
- if (header->bLength > size) {
+ if ((header->bLength > size) || (header->bLength <= 2)) {
err("ran out of descriptors parsing");
return -1;
}
@@ -1222,7 +1233,8 @@ void usb_disconnect(struct usb_device **pdev)
/* Free up all the children.. */
for (i = 0; i < USB_MAXCHILDREN; i++) {
struct usb_device **child = dev->children + i;
- usb_disconnect(child);
+ if (*child)
+ usb_disconnect(child);
}
/* remove /proc/bus/usb entry */
@@ -1246,6 +1258,9 @@ void usb_connect(struct usb_device *dev)
{
int devnum;
// FIXME needs locking for SMP!!
+ /* why? this is called only from the hub thread,
+ * which hopefully doesn't run on multiple CPU's simulatenously 8-)
+ */
dev->descriptor.bMaxPacketSize0 = 8; /* Start off at 8 bytes */
devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1);
if (devnum < 128) {
@@ -1272,6 +1287,8 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char
{
int i = 5;
int result;
+
+ memset(buf,0,size); // Make sure we parse really received data
while (i--) {
if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
@@ -1283,12 +1300,12 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char
return result;
}
-int usb_get_class_descriptor(struct usb_device *dev, unsigned char type,
- unsigned char id, unsigned char index, void *buf, int size)
+int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
+ unsigned char type, unsigned char id, void *buf, int size)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
- (type << 8) + id, index, buf, size, HZ * GET_TIMEOUT);
+ (type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT);
}
int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size)
@@ -1317,31 +1334,31 @@ int usb_get_status(struct usb_device *dev, int type, int target, void *data)
USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2, HZ * GET_TIMEOUT);
}
-int usb_get_protocol(struct usb_device *dev)
+int usb_get_protocol(struct usb_device *dev, int ifnum)
{
unsigned char type;
int ret;
if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_PROTOCOL, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- 0, 1, &type, 1, HZ * GET_TIMEOUT)) < 0)
+ 0, ifnum, &type, 1, HZ * GET_TIMEOUT)) < 0)
return ret;
return type;
}
-int usb_set_protocol(struct usb_device *dev, int protocol)
+int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol)
{
return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- protocol, 1, NULL, 0, HZ * SET_TIMEOUT);
+ protocol, ifnum, NULL, 0, HZ * SET_TIMEOUT);
}
-int usb_set_idle(struct usb_device *dev, int duration, int report_id)
+int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id)
{
return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- (duration << 8) | report_id, 1, NULL, 0, HZ * SET_TIMEOUT);
+ (duration << 8) | report_id, ifnum, NULL, 0, HZ * SET_TIMEOUT);
}
static void usb_set_maxpacket(struct usb_device *dev)
@@ -1373,10 +1390,11 @@ static void usb_set_maxpacket(struct usb_device *dev)
* endp: endpoint number in bits 0-3;
* direction flag in bit 7 (1 = IN, 0 = OUT)
*/
-int usb_clear_halt(struct usb_device *dev, int endp)
+int usb_clear_halt(struct usb_device *dev, int pipe)
{
int result;
__u16 status;
+ int endp=usb_pipeendpoint(pipe)|(usb_pipein(pipe)<<7);
/*
if (!usb_endpoint_halted(dev, endp & 0x0f, usb_endpoint_out(endp)))
@@ -1399,11 +1417,11 @@ int usb_clear_halt(struct usb_device *dev, int endp)
if (status & 1)
return -EPIPE; /* still halted */
- usb_endpoint_running(dev, endp & 0x0f, usb_endpoint_out(endp));
+ usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
/* toggle is reset on clear */
- usb_settoggle(dev, endp & 0x0f, usb_endpoint_out(endp), 0);
+ usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
return 0;
}
@@ -1462,18 +1480,18 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
return 0;
}
-int usb_get_report(struct usb_device *dev, unsigned char type, unsigned char id, unsigned char index, void *buf, int size)
+int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_REPORT, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- (type << 8) + id, index, buf, size, HZ * GET_TIMEOUT);
+ (type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT);
}
-int usb_set_report(struct usb_device *dev, unsigned char type, unsigned char id, unsigned char index, void *buf, int size)
+int usb_set_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size)
{
return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- (type << 8) + id, index, buf, size, HZ);
+ (type << 8) + id, ifnum, buf, size, HZ);
}
int usb_get_configuration(struct usb_device *dev)
@@ -1482,6 +1500,7 @@ int usb_get_configuration(struct usb_device *dev)
unsigned int cfgno;
unsigned char buffer[8];
unsigned char *bigbuffer;
+ unsigned int tmp;
struct usb_config_descriptor *desc =
(struct usb_config_descriptor *)buffer;
@@ -1511,8 +1530,11 @@ int usb_get_configuration(struct usb_device *dev)
/* We grab the first 8 bytes so we know how long the whole */
/* configuration is */
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
- if (result < 0) {
- err("unable to get descriptor");
+ if (result < 8) {
+ if (result < 0)
+ err("unable to get descriptor");
+ else
+ err("config descriptor too short (expected %i, got %i)",8,result);
goto err;
}
@@ -1525,13 +1547,19 @@ int usb_get_configuration(struct usb_device *dev)
result=-ENOMEM;
goto err;
}
-
+ tmp=desc->wTotalLength;
/* Now that we know the length, get the whole thing */
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, desc->wTotalLength);
if (result < 0) {
err("couldn't get all of config descriptors");
kfree(bigbuffer);
goto err;
+ }
+
+ if (result < tmp) {
+ err("config descriptor too short (expected %i, got %i)",tmp,result);
+ kfree(bigbuffer);
+ goto err;
}
result = usb_parse_configuration(dev, &dev->config[cfgno], bigbuffer);
kfree(bigbuffer);
@@ -1551,13 +1579,17 @@ int usb_get_configuration(struct usb_device *dev)
return result;
}
+/*
+ * usb_string:
+ * returns string length (> 0) or error (< 0)
+ */
int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
{
unsigned char *tbuf;
int err;
unsigned int u, idx;
- if (size <= 0 || !buf)
+ if (size <= 0 || !buf || !index)
return -EINVAL;
buf[0] = 0;
tbuf = kmalloc(256, GFP_KERNEL);
@@ -1574,15 +1606,15 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
err = usb_get_string(dev, dev->string_langid, index, tbuf, tbuf[0]);
if (err < 0)
goto errout;
- size--;
- for (idx = 0, u = 2; u < tbuf[0]; u += 2) {
+
+ size--; /* leave room for trailing NULL char in output buffer */
+ for (idx = 0, u = 2; u < err; u += 2) {
if (idx >= size)
break;
- if (tbuf[u+1]) {
- buf[idx++] = '?'; /* non ASCII character */
- continue;
- }
- buf[idx++] = tbuf[u];
+ if (tbuf[u+1]) /* high byte */
+ buf[idx++] = '?'; /* non-ASCII character */
+ else
+ buf[idx++] = tbuf[u];
}
buf[idx] = 0;
err = idx;
@@ -1603,6 +1635,7 @@ int usb_new_device(struct usb_device *dev)
{
unsigned char *buf;
int addr, err;
+ int tmp;
info("USB new device connect, assigned device number %d", dev->devnum);
@@ -1615,13 +1648,15 @@ int usb_new_device(struct usb_device *dev)
dev->devnum = 0;
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);
- if (err < 0) {
- err("USB device not responding, giving up (error=%d)", err);
+ if (err < 8) {
+ if (err < 0)
+ err("USB device not responding, giving up (error=%d)", err);
+ else
+ err("USB device descriptor short read (expected %i, got %i)",8,err);
clear_bit(addr, &dev->bus->devmap.devicemap);
dev->devnum = -1;
return 1;
}
-
dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0;
dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
switch (dev->descriptor.bMaxPacketSize0) {
@@ -1644,9 +1679,15 @@ int usb_new_device(struct usb_device *dev)
wait_ms(10); /* Let the SET_ADDRESS settle */
+ tmp = sizeof(dev->descriptor);
+
err = usb_get_device_descriptor(dev);
- if (err < 0) {
- err("unable to get device descriptor (error=%d)",err);
+ if (err < tmp) {
+ if (err < 0)
+ err("unable to get device descriptor (error=%d)",err);
+ else
+ err("USB device descriptor short read (expected %i, got %i)",tmp,err);
+
clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
dev->devnum = -1;
return 1;
@@ -1684,9 +1725,12 @@ int usb_new_device(struct usb_device *dev)
info("USB device number %d default language ID 0x%x", dev->devnum, dev->string_langid);
}
- usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer);
- usb_show_string(dev, "Product", dev->descriptor.iProduct);
- usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
+ if (dev->descriptor.iManufacturer)
+ usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer);
+ if (dev->descriptor.iProduct)
+ usb_show_string(dev, "Product", dev->descriptor.iProduct);
+ if (dev->descriptor.iSerialNumber)
+ usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
/* now that the basic setup is over, add a /proc/bus/usb entry */
usbdevfs_add_device(dev);
diff --git a/drivers/usb/usb.h b/drivers/usb/usb.h
index c6f52047b..ec2754b1f 100644
--- a/drivers/usb/usb.h
+++ b/drivers/usb/usb.h
@@ -4,6 +4,9 @@
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/version.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h> /* for in_interrupt() */
/* USB constants */
@@ -116,7 +119,6 @@
#include <linux/config.h>
#include <linux/list.h>
-#include <linux/sched.h>
#define USB_MAJOR 180
@@ -159,8 +161,12 @@ typedef struct wait_queue *wait_queue_head_t;
static __inline__ void wait_ms(unsigned int ms)
{
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout(1 + ms * HZ / 1000);
+ if(!in_interrupt()) {
+ current->state = TASK_UNINTERRUPTIBLE;
+ schedule_timeout(1 + ms * HZ / 1000);
+ }
+ else
+ mdelay(ms);
}
typedef struct {
@@ -428,7 +434,7 @@ void usb_free_urb (purb_t purb);
int usb_submit_urb(purb_t purb);
int usb_unlink_urb(purb_t purb);
int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest *cmd, void *data, int len, int timeout);
-int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, unsigned long *rval, int timeout);
+int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout);
/*-------------------------------------------------------------------*
* COMPATIBILITY STUFF *
@@ -661,22 +667,22 @@ int usb_new_device(struct usb_device *dev);
int usb_set_address(struct usb_device *dev);
int usb_get_descriptor(struct usb_device *dev, unsigned char desctype,
unsigned char descindex, void *buf, int size);
-int usb_get_class_descriptor(struct usb_device *dev, unsigned char desctype,
- unsigned char descindex, unsigned char ifnum, void *buf, int size);
+int usb_get_class_descriptor(struct usb_device *dev, int ifnum, unsigned char desctype,
+ unsigned char descindex, void *buf, int size);
int usb_get_device_descriptor(struct usb_device *dev);
int __usb_get_extra_descriptor(char *buffer, unsigned size, unsigned char type, void **ptr);
-int usb_get_status (struct usb_device *dev, int type, int target, void *data);
-int usb_get_protocol(struct usb_device *dev);
-int usb_set_protocol(struct usb_device *dev, int protocol);
-int usb_set_interface(struct usb_device *dev, int interface, int alternate);
-int usb_set_idle(struct usb_device *dev, int duration, int report_id);
+int usb_get_status(struct usb_device *dev, int type, int target, void *data);
+int usb_get_protocol(struct usb_device *dev, int ifnum);
+int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol);
+int usb_set_interface(struct usb_device *dev, int ifnum, int alternate);
+int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id);
int usb_set_configuration(struct usb_device *dev, int configuration);
-int usb_get_report(struct usb_device *dev, unsigned char type,
- unsigned char id, unsigned char index, void *buf, int size);
-int usb_set_report(struct usb_device *dev, unsigned char type,
- unsigned char id, unsigned char index, void *buf, int size);
+int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type,
+ unsigned char id, void *buf, int size);
+int usb_set_report(struct usb_device *dev, int ifnum, unsigned char type,
+ unsigned char id, void *buf, int size);
int usb_string(struct usb_device *dev, int index, char *buf, size_t size);
-int usb_clear_halt(struct usb_device *dev, int endp);
+int usb_clear_halt(struct usb_device *dev, int pipe);
#define usb_get_extra_descriptor(ifpoint,type,ptr)\
__usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,type,(void**)ptr)
diff --git a/drivers/usb/usb_scsi.c b/drivers/usb/usb_scsi.c
deleted file mode 100644
index 885cdac77..000000000
--- a/drivers/usb/usb_scsi.c
+++ /dev/null
@@ -1,1539 +0,0 @@
-/* Driver for USB Mass Storage compliant devices
- *
- * (c) 1999 Michael Gee (michael@linuxspecific.com)
- * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
- *
- * Further reference:
- * This driver is based on the 'USB Mass Storage Class' document. This
- * describes in detail the protocol used to communicate with such
- * devices. Clearly, the designers had SCSI commands in mind when they
- * created this document. The commands are all similar to commands
- * in the SCSI-II specification.
- *
- * It is important to note that in a number of cases this class exhibits
- * class-specific exemptions from the USB specification. Notably the
- * usage of NAK, STALL and ACK differs from the norm, in that they are
- * used to communicate wait, failed and OK on commands.
- * Also, for certain devices, the interrupt endpoint is used to convey
- * status of a command.
- *
- * Basically, this stuff is WEIRD!!
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/random.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/malloc.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-
-#include <linux/blk.h>
-#include "../scsi/scsi.h"
-#include "../scsi/hosts.h"
-#include "../scsi/sd.h"
-
-#include "usb.h"
-#include "usb_scsi.h"
-
-/* direction table -- this indicates the direction of the data
- * transfer for each command code -- a 1 indicates input
- */
-unsigned char us_direction[256/8] = {
- 0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
- 0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/*
- * Per device data
- */
-
-static int my_host_number;
-
-int usb_stor_debug = 1;
-
-struct us_data {
- struct us_data *next; /* next device */
- struct usb_device *pusb_dev;
- unsigned int flags; /* from filter initially */
- __u8 ifnum; /* interface number */
- __u8 ep_in; /* in endpoint */
- __u8 ep_out; /* out ....... */
- __u8 ep_int; /* interrupt . */
- __u8 subclass; /* as in overview */
- __u8 protocol; /* .............. */
- __u8 attention_done; /* force attn on first cmd */
- int (*pop)(Scsi_Cmnd *); /* protocol specific do cmd */
- int (*pop_reset)(struct us_data *); /* ........... device reset */
- GUID(guid); /* unique dev id */
- struct Scsi_Host *host; /* our dummy host data */
- Scsi_Host_Template *htmplt; /* own host template */
- int host_number; /* to find us */
- int host_no; /* allocated by scsi */
- int fixedlength; /* expand commands */
- Scsi_Cmnd *srb; /* current srb */
- int action; /* what to do */
- wait_queue_head_t waitq; /* thread waits */
- wait_queue_head_t ip_waitq; /* for CBI interrupts */
- __u16 ip_data; /* interrupt data */
- int ip_wanted; /* needed */
- int pid; /* control thread */
- struct semaphore *notify; /* wait for thread to begin */
- void *irq_handle; /* for USB int requests */
- unsigned int irqpipe; /* pipe for release_irq */
- int mode_xlate; /* trans MODE_6 to _10? */
-};
-
-/*
- * kernel thread actions
- */
-
-#define US_ACT_COMMAND 1
-#define US_ACT_ABORT 2
-#define US_ACT_DEVICE_RESET 3
-#define US_ACT_BUS_RESET 4
-#define US_ACT_HOST_RESET 5
-
-static struct us_data *us_list;
-
-static void * storage_probe(struct usb_device *dev, unsigned int ifnum);
-static void storage_disconnect(struct usb_device *dev, void *ptr);
-static struct usb_driver storage_driver = {
- "usb-storage",
- storage_probe,
- storage_disconnect,
- { NULL, NULL }
-};
-
-/***********************************************************************
- * Data transfer routines
- ***********************************************************************/
-
-/* transfer one buffer (breaking into packets if necessary) */
-static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
-{
- int max_size = usb_maxpacket(us->pusb_dev, pipe, usb_pipeout(pipe)) * 16;
- int this_xfer;
- int result;
- unsigned long partial;
- int maxtry = 100;
-
- /* while we have data to transfer */
- while (length) {
-
- /* calculate how long this will be -- maximum or a remainder */
- this_xfer = length > max_size ? max_size : length;
- length -= this_xfer;
-
- do {
- /* transfer the data */
- US_DEBUGP("Bulk xfer %x(%d)\n", (unsigned int)buf, this_xfer);
- result = usb_bulk_msg(us->pusb_dev, pipe, buf,
- this_xfer, &partial, HZ*5);
- US_DEBUGP("bulk_msg returned %d xferred %lu/%d\n",
- result, partial, this_xfer);
-
- /* if we stall, we need to clear it before we go on */
- if (result == USB_ST_STALL) {
- US_DEBUGP("clearing endpoint halt for pipe %x\n", pipe);
- usb_clear_halt(us->pusb_dev,
- usb_pipeendpoint(pipe) | (pipe & USB_DIR_IN));
- }
-
- /* we want to retry if the device reported NAK */
- if (result == USB_ST_TIMEOUT) {
-
- /* if our try counter reaches 0, bail out */
- if (!maxtry--)
- break;
-
- /* otherwise, we did transmit some data, and we update pointers */
- this_xfer -= partial;
- buf += partial;
-
- } else if (!result && partial != this_xfer) {
- /* result is an error, not a NAK, and short data - assume end */
- result = USB_ST_DATAUNDERRUN;
- break;
-
- } else if (result == USB_ST_STALL && us->protocol == US_PR_CB) {
- /* for CB devices, a stall isn't fatal? */
-
- /* if our try counter reaches 0, bail out */
- if (!maxtry--)
- break;
-
- this_xfer -= partial;
- buf += partial;
- }
-
- /* continue until this transfer is done */
- } while ( this_xfer );
-
- /* if we have some nonzero result, we return it here */
- if (result)
- return result;
-
- /* otherwise, we advance the buf pointer
- * note that the code above doesn't advance the pointer if all
- * goes well
- */
- buf += this_xfer;
- }
-
- /* if we get here, we're done and successful */
- return 0;
-}
-
-/* transfer one SCSI command, using scatter-gather if requested */
-static int us_transfer(Scsi_Cmnd *srb, int dir_in)
-{
- struct us_data *us = (struct us_data *)srb->host_scribble;
- int i;
- int result = -1;
- unsigned int pipe = dir_in ? usb_rcvbulkpipe(us->pusb_dev, us->ep_in) :
- usb_sndbulkpipe(us->pusb_dev, us->ep_out);
-
- if (srb->use_sg) {
- struct scatterlist *sg = (struct scatterlist *) srb->request_buffer;
-
- for (i = 0; i < srb->use_sg; i++) {
- result = us_one_transfer(us, pipe, sg[i].address, sg[i].length);
- if (result)
- break;
- }
- }
- else
- result = us_one_transfer(us, pipe,
- srb->request_buffer, srb->request_bufflen);
-
- if (result)
- US_DEBUGP("us_transfer returning error %d\n", result);
- return result;
-}
-
-/* calculate the length of the data transfer (not the command) for any
- * given SCSI command
- */
-static unsigned int us_transfer_length(Scsi_Cmnd *srb)
-{
- int i;
- unsigned int total = 0;
-
- /* always zero for some commands */
- switch (srb->cmnd[0]) {
- case SEEK_6:
- case SEEK_10:
- case REZERO_UNIT:
- case ALLOW_MEDIUM_REMOVAL:
- case START_STOP:
- case TEST_UNIT_READY:
- return 0;
-
- default:
- break;
- }
-
- if (srb->use_sg) {
- struct scatterlist *sg = (struct scatterlist *) srb->request_buffer;
-
- for (i = 0; i < srb->use_sg; i++) {
- total += sg[i].length;
- }
- return total;
- }
- else
- return srb->request_bufflen;
-}
-
-/***********************************************************************
- * Transport routines
- ***********************************************************************/
-
-static int CBI_irq(int state, void *buffer, int len, void *dev_id)
-{
- struct us_data *us = (struct us_data *)dev_id;
-
- US_DEBUGP("CBI_irq() called!!\n");
-
- if (state != USB_ST_REMOVED) {
- us->ip_data = le16_to_cpup((__u16 *)buffer);
- US_DEBUGP("Interrupt Status %x\n", us->ip_data);
- }
-
- if (us->ip_wanted) {
- us->ip_wanted = 0;
- wake_up(&us->ip_waitq);
- }
-
- /* this return code is truly meaningless */
- return 0;
-}
-
-static int pop_CB_reset(struct us_data *us)
-{
- unsigned char cmd[12];
- int result;
-
- US_DEBUGP("pop_CB_reset\n");
-
- memset(cmd, -1, sizeof(cmd));
- cmd[0] = SEND_DIAGNOSTIC;
- cmd[1] = 4;
- result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
- US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- 0, us->ifnum, cmd, sizeof(cmd), HZ*5);
-
- /* long wait for reset */
-
- schedule_timeout(HZ*6);
-
- US_DEBUGP("pop_CB_reset: clearing endpoint halt\n");
- usb_clear_halt(us->pusb_dev, us->ep_in | USB_DIR_IN);
- usb_clear_halt(us->pusb_dev, us->ep_out | USB_DIR_OUT);
-
- US_DEBUGP("pop_CB_reset done\n");
- return 0;
-}
-
-static int pop_CB_command(Scsi_Cmnd *srb)
-{
- struct us_data *us = (struct us_data *)srb->host_scribble;
- unsigned char cmd[16];
- int result;
- int retry = 5;
- int done_start = 0;
-
- /* we'll try this up to 5 times? */
- while (retry--) {
- if (us->flags & US_FL_FIXED_COMMAND) {
- memset(cmd, 0, us->fixedlength);
-
- /* fix some commands */
-
- switch (srb->cmnd[0]) {
- case WRITE_6:
- case READ_6:
- cmd[0] = srb->cmnd[0] | 0x20;
- cmd[1] = srb->cmnd[1] & 0xE0;
- cmd[2] = 0;
- cmd[3] = srb->cmnd[1] & 0x1F;
- cmd[4] = srb->cmnd[2];
- cmd[5] = srb->cmnd[3];
- cmd[8] = srb->cmnd[4];
- break;
-
- case MODE_SENSE:
- case MODE_SELECT:
- us->mode_xlate = (srb->cmnd[0] == MODE_SENSE);
- cmd[0] = srb->cmnd[0] | 0x40;
- cmd[1] = srb->cmnd[1];
- cmd[2] = srb->cmnd[2];
- cmd[8] = srb->cmnd[4];
- break;
-
- default:
- us->mode_xlate = 0;
- memcpy(cmd, srb->cmnd, srb->cmd_len);
- break;
- } /* switch */
-
- result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
- US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- 0, us->ifnum,
- cmd, us->fixedlength, HZ*5);
- US_DEBUGP("First usb_control_msg returns %d\n", result);
-
- /* For UFI, if this is the first time we've sent this TEST_UNIT_READY
- * command, we can try again
- */
- if (!done_start && (us->subclass == US_SC_UFI)
- && (cmd[0] == TEST_UNIT_READY) && (result < 0)) {
-
- /* as per spec try a start command, wait and retry */
- wait_ms(100);
-
- done_start++;
- memset(cmd, 0, sizeof(cmd));
- cmd[0] = START_STOP;
- cmd[4] = 1; /* start */
-
- result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
- US_CBI_ADSC,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- 0, us->ifnum,
- cmd, us->fixedlength, HZ*5);
- US_DEBUGP("Next usb_control_msg returns %d\n", result);
-
- /* allow another retry */
- retry++;
- continue;
- }
- } else { /* !US_FL_FIXED_COMMAND */
- result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
- US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- 0, us->ifnum,
- srb->cmnd, srb->cmd_len, HZ*5);
- }
-
- /* return an answer if we've got one */
- if (/*result != USB_ST_STALL &&*/ result != USB_ST_TIMEOUT)
- return result;
- }
-
- /* all done -- return our status */
- return result;
-}
-
-/*
- * Control/Bulk status handler
- */
-
-static int pop_CB_status(Scsi_Cmnd *srb)
-{
- struct us_data *us = (struct us_data *)srb->host_scribble;
- int result;
- __u8 status[2];
- int retry = 5;
-
- US_DEBUGP("pop_CB_status, proto=%x\n", us->protocol);
- switch (us->protocol) {
- case US_PR_CB:
- /* get from control */
-
- while (retry--) {
- result = usb_control_msg(us->pusb_dev, usb_rcvctrlpipe(us->pusb_dev,0),
- USB_REQ_GET_STATUS, USB_DIR_IN |
- USB_TYPE_STANDARD | USB_RECIP_DEVICE,
- 0, us->ifnum, status, sizeof(status), HZ*5);
- if (result != USB_ST_TIMEOUT)
- break;
- }
- if (result) {
- US_DEBUGP("Bad AP status request %d\n", result);
- return DID_ABORT << 16;
- }
- US_DEBUGP("Got AP status %x %x\n", status[0], status[1]);
- if (srb->cmnd[0] != REQUEST_SENSE && srb->cmnd[0] != INQUIRY &&
- ( (status[0] & ~3) || status[1]))
- return (DID_OK << 16) | 2;
- else
- return DID_OK << 16;
- break;
-
- case US_PR_CBI:
- /* get from interrupt pipe */
-
- /* add interrupt transfer, marked for removal */
- us->ip_wanted = 1;
-
- /* go to sleep until we get this interrup */
- sleep_on(&us->ip_waitq);
-
- /* NO! We don't release this IRQ. We just re-use the handler
- usb_release_irq(us->pusb_dev, us->irq_handle, us->irqpipe);
- us->irq_handle = NULL;
- */
-
- if (us->ip_wanted) {
- US_DEBUGP("Did not get interrupt on CBI\n");
- us->ip_wanted = 0;
- return DID_ABORT << 16;
- }
-
- US_DEBUGP("Got interrupt data %x\n", us->ip_data);
-
- /* sort out what it means */
-
- if (us->subclass == US_SC_UFI) {
- /* gives us asc and ascq, as per request sense */
-
- if (srb->cmnd[0] == REQUEST_SENSE ||
- srb->cmnd[0] == INQUIRY)
- return DID_OK << 16;
- else
- return (DID_OK << 16) + ((us->ip_data & 0xff) ? 2 : 0);
- }
- if (us->ip_data & 0xff) {
- US_DEBUGP("Bad CBI interrupt data %x\n", us->ip_data);
- return DID_ABORT << 16;
- }
- return (DID_OK << 16) + ((us->ip_data & 0x300) ? 2 : 0);
- }
- return DID_ERROR << 16;
-}
-
-/* Protocol command handlers */
-
-static int pop_CBI(Scsi_Cmnd *srb)
-{
- int result;
-
- US_DEBUGP("CBI gets a command:\n");
- US_DEBUG(us_show_command(srb));
-
- /* run the command */
- if ((result = pop_CB_command(srb)) < 0) {
- US_DEBUGP("Call to pop_CB_command returned %d\n", result);
- if (result == USB_ST_STALL || result == USB_ST_TIMEOUT) {
- return (DID_OK << 16) | 2;
- }
- return DID_ERROR << 16;
- }
-
- /* transfer the data */
- if (us_transfer_length(srb)) {
- result = us_transfer(srb, US_DIRECTION(srb->cmnd[0]));
- if ((result < 0) &&
- (result != USB_ST_DATAUNDERRUN) &&
- (result != USB_ST_STALL)) {
- US_DEBUGP("CBI attempted to transfer data, result is %x\n", result);
- return DID_ERROR << 16;
- }
-#if 0
- else if (result == USB_ST_DATAUNDERRUN) {
- return DID_OK << 16;
- }
- } else {
- if (!result) {
- return DID_OK << 16;
- }
-#endif
- }
-
- /* get status */
- return pop_CB_status(srb);
-}
-
-static int pop_Bulk_reset(struct us_data *us)
-{
- int result;
-
- result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
- US_BULK_RESET, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- US_BULK_RESET_HARD, us->ifnum,
- NULL, 0, HZ*5);
- if (result)
- US_DEBUGP("Bulk hard reset failed %d\n", result);
- usb_clear_halt(us->pusb_dev, us->ep_in | USB_DIR_IN);
- usb_clear_halt(us->pusb_dev, us->ep_out | USB_DIR_OUT);
-
- /* long wait for reset */
-
- schedule_timeout(HZ*6);
-
- return result;
-}
-
-/*
- * The bulk only protocol handler.
- * Uses the in and out endpoints to transfer commands and data (nasty)
- */
-static int pop_Bulk(Scsi_Cmnd *srb)
-{
- struct us_data *us = (struct us_data *)srb->host_scribble;
- struct bulk_cb_wrap bcb;
- struct bulk_cs_wrap bcs;
- int result;
- unsigned long partial;
- int stall;
-
- /* set up the command wrapper */
-
- bcb.Signature = US_BULK_CB_SIGN;
- bcb.DataTransferLength = us_transfer_length(srb);;
- bcb.Flags = US_DIRECTION(srb->cmnd[0]) << 7;
- bcb.Tag = srb->serial_number;
- bcb.Lun = 0;
- memset(bcb.CDB, 0, sizeof(bcb.CDB));
- memcpy(bcb.CDB, srb->cmnd, srb->cmd_len);
- if (us->flags & US_FL_FIXED_COMMAND) {
- bcb.Length = us->fixedlength;
- } else {
- bcb.Length = srb->cmd_len;
- }
-
- /* send it to out endpoint */
-
- US_DEBUGP("Bulk command S %x T %x L %d F %d CL %d\n",
- bcb.Signature, bcb.Tag, bcb.DataTransferLength,
- bcb.Flags, bcb.Length);
- result = usb_bulk_msg(us->pusb_dev,
- usb_sndbulkpipe(us->pusb_dev, us->ep_out), &bcb,
- US_BULK_CB_WRAP_LEN, &partial, HZ*5);
- if (result) {
- US_DEBUGP("Bulk command result %x\n", result);
- return DID_ABORT << 16;
- }
-
- //return DID_BAD_TARGET << 16;
- /* send/receive data */
-
- if (bcb.DataTransferLength) {
- result = us_transfer(srb, bcb.Flags);
- if (result && result != USB_ST_DATAUNDERRUN && result != USB_ST_STALL) {
- US_DEBUGP("Bulk transfer result %x\n", result);
- return DID_ABORT << 16;
- }
- }
-
- /* get status */
-
- stall = 0;
- do {
- result = usb_bulk_msg(us->pusb_dev,
- usb_rcvbulkpipe(us->pusb_dev, us->ep_in), &bcs,
- US_BULK_CS_WRAP_LEN, &partial, HZ*5);
- if (result == USB_ST_STALL || result == USB_ST_TIMEOUT)
- stall++;
- else
- break;
- } while ( stall < 3);
- if (result && result != USB_ST_DATAUNDERRUN) {
- US_DEBUGP("Bulk status result = %x\n", result);
- return DID_ABORT << 16;
- }
-
- /* check bulk status */
-
- US_DEBUGP("Bulk status S %x T %x R %d V %x\n",
- bcs.Signature, bcs.Tag, bcs.Residue, bcs.Status);
- if (bcs.Signature != US_BULK_CS_SIGN || bcs.Tag != bcb.Tag ||
- bcs.Status > US_BULK_STAT_PHASE) {
- US_DEBUGP("Bulk logical error\n");
- return DID_ABORT << 16;
- }
-
- /* We need to fix some of this status handling. */
- switch (bcs.Status) {
- case US_BULK_STAT_OK:
- return DID_OK << 16;
-
- case US_BULK_STAT_FAIL:
- /* check for underrun - dont report */
- if (bcs.Residue)
- return DID_OK << 16;
- //pop_Bulk_reset(us);
- break;
-
- case US_BULK_STAT_PHASE:
- return DID_ERROR << 16;
- }
-
- return (DID_OK << 16) | 2; /* check sense required */
-}
-
-/* Host functions */
-
-/* detect adapter (always true ) */
-static int us_detect(struct SHT *sht)
-{
- /* FIXME - not nice at all, but how else ? */
- struct us_data *us = (struct us_data *)sht->proc_dir;
- char name[32];
-
- /* set up our name */
- sprintf(name, "usbscsi%d", us->host_number);
- sht->name = sht->proc_name = kmalloc(strlen(name)+1, GFP_KERNEL);
- if (!sht->proc_name)
- return 0;
- strcpy(sht->proc_name, name);
-
- /* we start with no /proc directory entry */
- sht->proc_dir = NULL;
-
- /* register the host */
- us->host = scsi_register(sht, sizeof(us));
- if (us->host) {
- us->host->hostdata[0] = (unsigned long)us;
- us->host_no = us->host->host_no;
- return 1;
- }
-
- /* odd... didn't register properly. Abort and free pointers */
- kfree(sht->proc_name);
- sht->proc_name = NULL;
- sht->name = NULL;
- return 0;
-}
-
-/* release - must be here to stop scsi
- * from trying to release IRQ etc.
- * Kill off our data
- */
-static int us_release(struct Scsi_Host *psh)
-{
- struct us_data *us = (struct us_data *)psh->hostdata[0];
- struct us_data *prev = (struct us_data *)&us_list;
-
- if (us->irq_handle) {
- usb_release_irq(us->pusb_dev, us->irq_handle, us->irqpipe);
- us->irq_handle = NULL;
- }
- if (us->pusb_dev)
- usb_deregister(&storage_driver);
-
- /* FIXME - leaves hanging host template copy */
- /* (because scsi layer uses it after removal !!!) */
- while (prev->next != us)
- prev = prev->next;
- prev->next = us->next;
- return 0;
-}
-
-/* run command */
-static int us_command( Scsi_Cmnd *srb )
-{
- US_DEBUGP("Bad use of us_command\n");
-
- return DID_BAD_TARGET << 16;
-}
-
-/* run command */
-static int us_queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
-{
- struct us_data *us = (struct us_data *)srb->host->hostdata[0];
-
- US_DEBUGP("Command wakeup\n");
- if (us->srb) {
- /* busy */
- }
- srb->host_scribble = (unsigned char *)us;
- us->srb = srb;
- srb->scsi_done = done;
- us->action = US_ACT_COMMAND;
-
- /* wake up the process task */
-
- wake_up_interruptible(&us->waitq);
-
- return 0;
-}
-
-static int us_abort( Scsi_Cmnd *srb )
-{
- return 0;
-}
-
-static int us_bus_reset( Scsi_Cmnd *srb )
-{
- struct us_data *us = (struct us_data *)srb->host->hostdata[0];
-
- US_DEBUGP("Bus reset requested\n");
- us->pop_reset(us);
- return SUCCESS;
-}
-
-static int us_host_reset( Scsi_Cmnd *srb )
-{
- return 0;
-}
-
-/***********************************************************************
- * /proc/scsi/ functions
- ***********************************************************************/
-
-/* we use this macro to help us write into the buffer */
-#undef SPRINTF
-#define SPRINTF(args...) do { if (pos < (buffer + length)) pos += sprintf (pos, ## args); } while (0)
-
-int usb_stor_proc_info (char *buffer, char **start, off_t offset,
- int length, int hostno, int inout)
-{
- struct us_data *us = us_list;
- char *pos = buffer;
- char *tmp_ptr;
-
- /* find our data from hostno */
- while (us) {
- if (us->host_no == hostno)
- break;
- us = us->next;
- }
-
- /* if we couldn't find it, we return an error */
- if (!us)
- return -ESRCH;
-
- /* if someone is sending us data, just throw it away */
- if (inout)
- return length;
-
- /* print the controler name */
- SPRINTF ("Host scsi%d: usb-scsi\n", hostno);
-
- /* print product and vendor strings */
- tmp_ptr = kmalloc(256, GFP_KERNEL);
- if (!us->pusb_dev || !tmp_ptr) {
- SPRINTF("Vendor: Unknown Vendor\n");
- SPRINTF("Product: Unknown Product\n");
- } else {
- SPRINTF("Vendor: ");
- if (usb_string(us->pusb_dev, us->pusb_dev->descriptor.iManufacturer, tmp_ptr, 256) > 0)
- SPRINTF("%s\n", tmp_ptr);
- else
- SPRINTF("Unknown Vendor\n");
-
- SPRINTF("Product: ");
- if (usb_string(us->pusb_dev, us->pusb_dev->descriptor.iProduct, tmp_ptr, 256) > 0)
- SPRINTF("%s\n", tmp_ptr);
- else
- SPRINTF("Unknown Vendor\n");
- }
- kfree(tmp_ptr);
-
- SPRINTF("Protocol: ");
- switch (us->protocol) {
- case US_PR_CB:
- SPRINTF("Control/Bulk\n");
- break;
-
- case US_PR_CBI:
- SPRINTF("Control/Bulk/Interrupt\n");
- break;
-
- case US_PR_BULK:
- SPRINTF("Bulk only\n");
- break;
-
- default:
- SPRINTF("Unknown Protocol\n");
- break;
- }
-
- /* show the GUID of the device */
- SPRINTF("GUID: " GUID_FORMAT "\n", GUID_ARGS(us->guid));
-
- /*
- * Calculate start of next buffer, and return value.
- */
- *start = buffer + offset;
-
- if ((pos - buffer) < offset)
- return (0);
- else if ((pos - buffer - offset) < length)
- return (pos - buffer - offset);
- else
- return (length);
-}
-
-/*
- * this defines our 'host'
- */
-
-static Scsi_Host_Template my_host_template = {
- NULL, /* next */
- NULL, /* module */
- NULL, /* proc_dir */
- usb_stor_proc_info,
- NULL, /* name - points to unique */
- us_detect,
- us_release,
- NULL, /* info */
- NULL, /* ioctl */
- us_command,
- us_queuecommand,
- NULL, /* eh_strategy */
- us_abort,
- us_bus_reset,
- us_bus_reset,
- us_host_reset,
- NULL, /* abort */
- NULL, /* reset */
- NULL, /* slave_attach */
- NULL, /* bios_param */
- 1, /* can_queue */
- -1, /* this_id */
- SG_ALL, /* sg_tablesize */
- 1, /* cmd_per_lun */
- 0, /* present */
- FALSE, /* unchecked_isa_dma */
- FALSE, /* use_clustering */
- TRUE, /* use_new_eh_code */
- TRUE /* emulated */
-};
-
-static unsigned char sense_notready[] = {
- 0x70, /* current error */
- 0x00,
- 0x02, /* not ready */
- 0x00,
- 0x00,
- 10, /* additional length */
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x04, /* not ready */
- 0x03, /* manual intervention */
- 0x00,
- 0x00,
- 0x00,
- 0x00
-};
-
-static int usb_stor_control_thread(void * __us)
-{
- struct us_data *us = (struct us_data *)__us;
- int action;
-
- lock_kernel();
-
- /*
- * This thread doesn't need any user-level access,
- * so get rid of all our resources..
- */
- daemonize();
-
- sprintf(current->comm, "usbscsi%d", us->host_number);
-
- unlock_kernel();
-
- up(us->notify);
-
- for(;;) {
- siginfo_t info;
- int unsigned long signr;
-
- interruptible_sleep_on(&us->waitq);
-
- action = us->action;
- us->action = 0;
-
- switch (action) {
- case US_ACT_COMMAND:
- if (us->srb->target || us->srb->lun) {
- /* bad device */
- US_DEBUGP( "Bad device number (%d/%d) or dev %x\n",
- us->srb->target, us->srb->lun, (unsigned int)us->pusb_dev);
- us->srb->result = DID_BAD_TARGET << 16;
- } else if (!us->pusb_dev) {
-
- /* our device has gone - pretend not ready */
-
- if (us->srb->cmnd[0] == REQUEST_SENSE) {
- memcpy(us->srb->request_buffer, sense_notready, sizeof(sense_notready));
- us->srb->result = DID_OK << 16;
- } else {
- us->srb->result = (DID_OK << 16) | 2;
- }
- } else {
- US_DEBUG(us_show_command(us->srb));
-
- if (us->srb->cmnd[0] == START_STOP &&
- us->pusb_dev->descriptor.idProduct == 0x0001 &&
- us->pusb_dev->descriptor.idVendor == 0x04e6)
- us->srb->result = DID_OK << 16;
- else {
- unsigned int savelen = us->srb->request_bufflen;
- unsigned int saveallocation = 0;
-
- /* check for variable length - do properly if so */
- switch (us->srb->cmnd[0]) {
- case REQUEST_SENSE:
- if (us->srb->request_bufflen > 18)
- us->srb->request_bufflen = 18;
- else
- break;
- saveallocation = us->srb->cmnd[4];
- us->srb->cmnd[4] = 18;
- break;
-
- case INQUIRY:
- if (us->srb->request_bufflen > 36)
- us->srb->request_bufflen = 36;
- else
- break;
- saveallocation = us->srb->cmnd[4];
- us->srb->cmnd[4] = 36;
- break;
-
- case MODE_SENSE:
- if (us->srb->request_bufflen > 4)
- us->srb->request_bufflen = 4;
- else
- break;
- saveallocation = us->srb->cmnd[4];
- us->srb->cmnd[4] = 4;
- break;
-
- case LOG_SENSE:
- case MODE_SENSE_10:
- if (us->srb->request_bufflen > 8)
- us->srb->request_bufflen = 8;
- else
- break;
- saveallocation = (us->srb->cmnd[7] << 8) | us->srb->cmnd[8];
- us->srb->cmnd[7] = 0;
- us->srb->cmnd[8] = 8;
- break;
-
- default:
- break;
- } /* end switch on cmnd[0] */
-
-#if 0
- /* translate READ_6 to READ_10 */
- if (us->srb->cmnd[0] == 0x08) {
-
- /* get the control */
- us->srb->cmnd[9] = us->srb->cmnd[5];
-
- /* get the length */
- us->srb->cmnd[8] = us->srb->cmnd[6];
- us->srb->cmnd[7] = 0;
-
- /* set the reserved area to 0 */
- us->srb->cmnd[6] = 0;
-
- /* get LBA */
- us->srb->cmnd[5] = us->srb->cmnd[3];
- us->srb->cmnd[4] = us->srb->cmnd[2];
- us->srb->cmnd[3] = 0;
- us->srb->cmnd[2] = 0;
-
- /* LUN and other info in cmnd[1] can stay */
-
- /* fix command code */
- us->srb->cmnd[0] = 0x28;
-
- US_DEBUGP("Changing READ_6 to READ_10\n");
- US_DEBUG(us_show_command(us->srb));
- }
-
- /* translate WRITE_6 to WRITE_10 */
- if (us->srb->cmnd[0] == 0x0A) {
-
- /* get the control */
- us->srb->cmnd[9] = us->srb->cmnd[5];
-
- /* get the length */
- us->srb->cmnd[8] = us->srb->cmnd[4];
- us->srb->cmnd[7] = 0;
-
- /* set the reserved area to 0 */
- us->srb->cmnd[6] = 0;
-
- /* get LBA */
- us->srb->cmnd[5] = us->srb->cmnd[3];
- us->srb->cmnd[4] = us->srb->cmnd[2];
- us->srb->cmnd[3] = 0;
- us->srb->cmnd[2] = 0;
-
- /* LUN and other info in cmnd[1] can stay */
-
- /* fix command code */
- us->srb->cmnd[0] = 0x2A;
-
- US_DEBUGP("Changing WRITE_6 to WRITE_10\n");
- US_DEBUG(us_show_command(us->srb));
- }
-#endif
-
- /* let's do the command */
- us->srb->result = us->pop(us->srb);
-
- if (savelen != us->srb->request_bufflen &&
- us->srb->result == (DID_OK << 16)) {
- unsigned char *p = (unsigned char *)us->srb->request_buffer;
- unsigned int length = 0;
-
- /* set correct length and retry */
- switch (us->srb->cmnd[0]) {
- case REQUEST_SENSE:
- /* simply return 18 bytes */
- p[7] = 10;
- length = us->srb->request_bufflen;
- break;
-
- case INQUIRY:
- length = p[4] + 5 > savelen ? savelen : p[4] + 5;
- us->srb->cmnd[4] = length;
- break;
-
- case MODE_SENSE:
- US_DEBUGP("MODE_SENSE Mode data length is %d\n", p[0]);
- length = p[0] + 1 > savelen ? savelen : p[0] + 1;
- us->srb->cmnd[4] = length;
- break;
-
- case LOG_SENSE:
- length = ((p[2] << 8) + p[3]) + 4 > savelen ? savelen : ((p[2] << 8) + p[3]) + 4;
- us->srb->cmnd[7] = length >> 8;
- us->srb->cmnd[8] = length;
- break;
-
- case MODE_SENSE_10:
- US_DEBUGP("MODE_SENSE_10 Mode data length is %d\n",
- (p[0] << 8) + p[1]);
- length = ((p[0] << 8) + p[1]) + 6 > savelen ? savelen : ((p[0] << 8) + p[1]) + 6;
- us->srb->cmnd[7] = length >> 8;
- us->srb->cmnd[8] = length;
- break;
- } /* end switch on cmnd[0] */
-
- US_DEBUGP("Old/New length = %d/%d\n",
- savelen, length);
-
- if (us->srb->request_bufflen != length) {
- US_DEBUGP("redoing cmd with len=%d\n", length);
- us->srb->request_bufflen = length;
- us->srb->result = us->pop(us->srb);
- }
- /* reset back to original values */
-
- us->srb->request_bufflen = savelen;
- switch (us->srb->cmnd[0]) {
- case INQUIRY:
- if ((((unsigned char*)us->srb->request_buffer)[2] & 0x7) == 0) {
- US_DEBUGP("Fixing INQUIRY data, setting SCSI rev to 2\n");
- ((unsigned char*)us->srb->request_buffer)[2] |= 2;
- }
- /* FALL THROUGH */
- case REQUEST_SENSE:
- case MODE_SENSE:
- if (us->srb->use_sg == 0 && length > 0) {
- int i;
- printk(KERN_DEBUG "Data is");
- for (i = 0; i < 32 && i < length; ++i)
- printk(" %.2x", ((unsigned char *)us->srb->request_buffer)[i]);
- if (i < length)
- printk(" ...");
- printk("\n");
- }
- us->srb->cmnd[4] = saveallocation;
- if (us->mode_xlate) {
- /* convert MODE_SENSE_10 return data
- * format to MODE_SENSE_6 format */
- unsigned char *dta = (unsigned char *)us->srb->request_buffer;
- dta[0] = dta[1]; /* data len */
- dta[1] = dta[2]; /* med type */
- dta[2] = dta[3]; /* dev-spec prm */
- dta[3] = dta[7]; /* block desc len */
- printk (KERN_DEBUG USB_SCSI "new MODE_SENSE_6 data = %.2X %.2X %.2X %.2X\n",
- dta[0], dta[1], dta[2], dta[3]);
- }
- break;
-
- case LOG_SENSE:
- case MODE_SENSE_10:
- us->srb->cmnd[7] = saveallocation >> 8;
- us->srb->cmnd[8] = saveallocation;
- break;
- } /* end switch on cmnd[0] */
- }
- /* force attention on first command */
- if (!us->attention_done) {
- US_DEBUGP("forcing unit attention\n");
- if (us->srb->cmnd[0] == REQUEST_SENSE) {
- if (us->srb->result == (DID_OK << 16)) {
- unsigned char *p = (unsigned char *)us->srb->request_buffer;
-
- us->attention_done = 1;
- if ((p[2] & 0x0f) != UNIT_ATTENTION) {
- p[2] = UNIT_ATTENTION;
- p[12] = 0x29; /* power on, reset or bus-reset */
- p[13] = 0;
- }
- }
- } else if (us->srb->cmnd[0] != INQUIRY &&
- us->srb->result == (DID_OK << 16)) {
- us->srb->result |= 2; /* force check condition */
- }
- }
- }
- }
- US_DEBUGP("scsi cmd done, result=%x\n", us->srb->result);
- us->srb->scsi_done(us->srb);
- us->srb = NULL;
- break;
-
- case US_ACT_ABORT:
- break;
-
- case US_ACT_DEVICE_RESET:
- break;
-
- case US_ACT_BUS_RESET:
- break;
-
- case US_ACT_HOST_RESET:
- break;
-
- } /* end switch on action */
-
- if (signal_pending(current)) {
- /* sending SIGUSR1 makes us print out some info */
- spin_lock_irq(&current->sigmask_lock);
- signr = dequeue_signal(&current->blocked, &info);
- spin_unlock_irq(&current->sigmask_lock);
-
- if (signr == SIGUSR2) {
- usb_stor_debug = !usb_stor_debug;
- printk(USB_SCSI "debug toggle = %d\n", usb_stor_debug);
- } else {
- break; /* exit the loop on any other signal */
- }
- }
- }
-
- // MOD_DEC_USE_COUNT;
-
- printk("usb_stor_control_thread exiting\n");
-
- return 0;
-}
-
-/* Probe to see if a new device is actually a SCSI device */
-static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
-{
- struct usb_interface_descriptor *interface;
- int i;
- char mf[32]; /* manufacturer */
- char prod[32]; /* product */
- char serial[32]; /* serial number */
- struct us_data *ss = NULL;
- unsigned int flags = 0;
- GUID(guid); /* Global Unique Identifier */
- struct us_data *prev;
- Scsi_Host_Template *htmplt;
- int protocol = 0;
- int subclass = 0;
- struct usb_interface_descriptor *altsetting =
- &(dev->actconfig->interface[ifnum].altsetting[0]);
-
- /* clear the GUID and fetch the strings */
- GUID_CLEAR(guid);
- usb_string(dev, dev->descriptor.iManufacturer, mf, sizeof(mf));
- usb_string(dev, dev->descriptor.iProduct, prod, sizeof(prod));
- usb_string(dev, dev->descriptor.iSerialNumber, serial, sizeof(serial));
-
- /* let's examine the device now */
-
- /* We make an exception for the shuttle E-USB */
- if (dev->descriptor.idVendor == 0x04e6 &&
- dev->descriptor.idProduct == 0x0001) {
- protocol = US_PR_CB;
- subclass = US_SC_8070; /* an assumption */
- } else if (dev->descriptor.bDeviceClass != 0 ||
- altsetting->bInterfaceClass != USB_CLASS_MASS_STORAGE ||
- altsetting->bInterfaceSubClass < US_SC_MIN ||
- altsetting->bInterfaceSubClass > US_SC_MAX) {
- /* if it's not a mass storage, we go no further */
- return NULL;
- }
-
- /* At this point, we know we've got a live one */
- US_DEBUGP("USB Mass Storage device detected\n");
-
- /* Create a GUID for this device */
- if (dev->descriptor.iSerialNumber && serial[0]) {
- /* If we have a serial number, and it's a non-NULL string */
- make_guid(guid, dev->descriptor.idVendor,
- dev->descriptor.idProduct,
- serial);
- } else {
- /* We don't have a serial number, so we use 0 */
- make_guid(guid, dev->descriptor.idVendor,
- dev->descriptor.idProduct, "0");
- }
-
- /* Now check if we have seen this GUID before, and restore
- * the flags if we find it
- */
- for (ss = us_list; ss != NULL; ss = ss->next) {
- if (!ss->pusb_dev && GUID_EQUAL(guid, ss->guid)) {
- US_DEBUGP("Found existing GUID " GUID_FORMAT "\n",
- GUID_ARGS(guid));
- flags = ss->flags;
- break;
- }
- }
-
- /* If ss == NULL, then this is a new device. Allocate memory for it */
- if (!ss) {
- if ((ss = (struct us_data *)kmalloc(sizeof(*ss),
- GFP_KERNEL)) == NULL) {
- printk(KERN_WARNING USB_SCSI "Out of memory\n");
- return NULL;
- }
- memset(ss, 0, sizeof(struct us_data));
- }
-
- /* Initialize the us_data structure with some useful info */
- interface = altsetting;
- ss->flags = flags;
- ss->ifnum = ifnum;
- ss->pusb_dev = dev;
- ss->attention_done = 0;
-
- /* If the device has subclass and protocol, then use that. Otherwise,
- * take data from the specific interface.
- */
- if (subclass) {
- ss->subclass = subclass;
- ss->protocol = protocol;
- } else {
- ss->subclass = interface->bInterfaceSubClass;
- ss->protocol = interface->bInterfaceProtocol;
- }
-
- /* set the handler pointers based on the protocol */
- US_DEBUGP("Protocol: ");
- switch (ss->protocol) {
- case US_PR_CB:
- US_DEBUGPX("Control/Bulk\n");
- ss->pop = pop_CBI;
- ss->pop_reset = pop_CB_reset;
- break;
-
- case US_PR_CBI:
- US_DEBUGPX("Control/Bulk/Interrupt\n");
- ss->pop = pop_CBI;
- ss->pop_reset = pop_CB_reset;
- break;
-
- case US_PR_BULK:
- US_DEBUGPX("Bulk\n");
- ss->pop = pop_Bulk;
- ss->pop_reset = pop_Bulk_reset;
- break;
-
- default:
- US_DEBUGPX("Unknown\n");
- kfree(ss);
- return NULL;
- break;
- }
-
- /*
- * We are expecting a minimum of 2 endpoints - in and out (bulk).
- * An optional interrupt is OK (necessary for CBI protocol).
- * We will ignore any others.
- */
- for (i = 0; i < interface->bNumEndpoints; i++) {
- /* is it an BULK endpoint? */
- if ((interface->endpoint[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
- == USB_ENDPOINT_XFER_BULK) {
- if (interface->endpoint[i].bEndpointAddress & USB_DIR_IN)
- ss->ep_in = interface->endpoint[i].bEndpointAddress &
- USB_ENDPOINT_NUMBER_MASK;
- else
- ss->ep_out = interface->endpoint[i].bEndpointAddress &
- USB_ENDPOINT_NUMBER_MASK;
- }
-
- /* is it an interrupt endpoint? */
- if ((interface->endpoint[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
- == USB_ENDPOINT_XFER_INT) {
- ss->ep_int = interface->endpoint[i].bEndpointAddress &
- USB_ENDPOINT_NUMBER_MASK;
- }
- }
- US_DEBUGP("Endpoints In %d Out %d Int %d\n",
- ss->ep_in, ss->ep_out, ss->ep_int);
-
- /* Do some basic sanity checks, and bail if we find a problem */
- if (usb_set_interface(dev, interface->bInterfaceNumber, 0) ||
- !ss->ep_in || !ss->ep_out ||
- (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
- US_DEBUGP("Problems with device\n");
- if (ss->host) {
- scsi_unregister_module(MODULE_SCSI_HA, ss->htmplt);
- kfree(ss->htmplt->name);
- kfree(ss->htmplt);
- }
-
- kfree(ss);
- return NULL;
- }
-
- /* If this is a new device (i.e. we haven't seen it before), we need to
- * generate a scsi host definition, and register with scsi above us
- */
- if (!ss->host) {
- /* copy the GUID we created before */
- US_DEBUGP("New GUID " GUID_FORMAT "\n", GUID_ARGS(guid));
- memcpy(ss->guid, guid, sizeof(guid));
-
- /* set class specific stuff */
- US_DEBUGP("SubClass: ");
- switch (ss->subclass) {
- case US_SC_RBC:
- US_DEBUGPX("Reduced Block Commands\n");
- break;
-
- case US_SC_8020:
- US_DEBUGPX("8020\n");
- break;
-
- case US_SC_QIC:
- US_DEBUGPX("QIC157\n");
- break;
-
- case US_SC_8070:
- US_DEBUGPX("8070\n");
- ss->flags |= US_FL_FIXED_COMMAND;
- ss->fixedlength = 12;
- break;
-
- case US_SC_SCSI:
- US_DEBUGPX("Transparent SCSI\n");
- break;
-
- case US_SC_UFI:
- US_DEBUGPX("UFI\n");
- ss->flags |= US_FL_FIXED_COMMAND;
- ss->fixedlength = 12;
- break;
-
- default:
- US_DEBUGPX("Unknown\n");
- break;
- }
-
- /* Allocate memory for the SCSI Host Template */
- if ((htmplt = (Scsi_Host_Template *)
- kmalloc(sizeof(*ss->htmplt), GFP_KERNEL)) == NULL ) {
-
- printk(KERN_WARNING USB_SCSI "Out of memory\n");
-
- kfree(ss);
- return NULL;
- }
-
- /* Initialize the host template based on the default one */
- memcpy(htmplt, &my_host_template, sizeof(my_host_template));
-
- /* Grab the next host number */
- ss->host_number = my_host_number++;
-
- /* MDD: FIXME: this is bad. We abuse this pointer so we
- * can pass the ss pointer to the host controler thread
- * in us_detect
- */
- (struct us_data *)htmplt->proc_dir = ss;
-
- /* shuttle E-USB */
- if (dev->descriptor.idVendor == 0x04e6 &&
- dev->descriptor.idProduct == 0x0001) {
- __u8 qstat[2];
- int result;
-
- result = usb_control_msg(ss->pusb_dev, usb_rcvctrlpipe(dev,0),
- 1, 0xC0,
- 0, ss->ifnum,
- qstat, 2, HZ*5);
- US_DEBUGP("C0 status %x %x\n", qstat[0], qstat[1]);
- init_waitqueue_head(&ss->ip_waitq);
- ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
- result = usb_request_irq(ss->pusb_dev, ss->irqpipe, CBI_irq,
- 255, (void *)ss, &ss->irq_handle);
- if (result)
- return NULL;
-
- interruptible_sleep_on_timeout(&ss->ip_waitq, HZ*6);
- } else if (ss->protocol == US_PR_CBI)
- {
- int result;
-
- init_waitqueue_head(&ss->ip_waitq);
-
- /* set up the IRQ pipe and handler */
- /* FIXME: This needs to get the period from the device */
- ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
- result = usb_request_irq(ss->pusb_dev, ss->irqpipe, CBI_irq,
- 255, (void *)ss, &ss->irq_handle);
- if (result) {
- US_DEBUGP("usb_request_irq failed (0x%x), No interrupt for CBI\n",
- result);
- }
- }
-
-
- /* start up our thread */
- {
- DECLARE_MUTEX_LOCKED(sem);
-
- init_waitqueue_head(&ss->waitq);
-
- ss->notify = &sem;
- ss->pid = kernel_thread(usb_stor_control_thread, ss,
- CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
- if (ss->pid < 0) {
- printk(KERN_WARNING USB_SCSI "Unable to start control thread\n");
- kfree(htmplt);
-
- kfree(ss);
- return NULL;
- }
-
- /* wait for it to start */
- down(&sem);
- }
-
- /* now register - our detect function will be called */
-
- scsi_register_module(MODULE_SCSI_HA, htmplt);
-
- /* put us in the list */
-
- prev = (struct us_data *)&us_list;
- while (prev->next)
- prev = prev->next;
- prev->next = ss;
- }
-
- printk(KERN_WARNING "WARNING: USB SCSI data integrity not assured\n");
- printk(KERN_INFO "USB SCSI device found at address %d\n", dev->devnum);
-
- return ss;
-}
-
-/* Handle a disconnect event from the USB core */
-static void storage_disconnect(struct usb_device *dev, void *ptr)
-{
- struct us_data *ss = ptr;
-
- if (!ss)
- return;
-
- ss->pusb_dev = NULL;
- // MOD_DEC_USE_COUNT;
-}
-
-
-/***********************************************************************
- * Initialization and registration
- ***********************************************************************/
-
-int usb_stor_init(void)
-{
- // MOD_INC_USE_COUNT;
-
- if (usb_register(&storage_driver) < 0)
- return -1;
-
- printk(KERN_INFO "USB SCSI support registered.\n");
- return 0;
-}
-
-#ifdef MODULE
-int init_module(void)
-{
- /* MDD: Perhaps we should register the host here */
- return usb_stor_init();
-}
-
-void cleanup_module(void)
-{
- usb_deregister(&storage_driver);
-}
-#endif
diff --git a/drivers/usb/usb_scsi_debug.c b/drivers/usb/usb_scsi_debug.c
deleted file mode 100644
index d29622cad..000000000
--- a/drivers/usb/usb_scsi_debug.c
+++ /dev/null
@@ -1,102 +0,0 @@
-
-/* Driver for USB scsi like devices
- *
- * (C) Michael Gee (michael@linuxspecific.com) 1999
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/miscdevice.h>
-#include <linux/random.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/malloc.h>
-#include <linux/spinlock.h>
-
-#include <linux/blk.h>
-#include "../scsi/scsi.h"
-#include "../scsi/hosts.h"
-#include "../scsi/sd.h"
-
-#include "usb.h"
-#include "usb_scsi.h"
-
-void us_show_command(Scsi_Cmnd *srb)
-{
- char *what = NULL;
-
- switch (srb->cmnd[0]) {
- case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break;
- case REZERO_UNIT: what = "REZERO_UNIT"; break;
- case REQUEST_SENSE: what = "REQUEST_SENSE"; break;
- case FORMAT_UNIT: what = "FORMAT_UNIT"; break;
- case READ_BLOCK_LIMITS: what = "READ_BLOCK_LIMITS"; break;
- case REASSIGN_BLOCKS: what = "REASSIGN_BLOCKS"; break;
- case READ_6: what = "READ_6"; break;
- case WRITE_6: what = "WRITE_6"; break;
- case SEEK_6: what = "SEEK_6"; break;
- case READ_REVERSE: what = "READ_REVERSE"; break;
- case WRITE_FILEMARKS: what = "WRITE_FILEMARKS"; break;
- case SPACE: what = "SPACE"; break;
- case INQUIRY: what = "INQUIRY"; break;
- case RECOVER_BUFFERED_DATA: what = "RECOVER_BUFFERED_DATA"; break;
- case MODE_SELECT: what = "MODE_SELECT"; break;
- case RESERVE: what = "RESERVE"; break;
- case RELEASE: what = "RELEASE"; break;
- case COPY: what = "COPY"; break;
- case ERASE: what = "ERASE"; break;
- case MODE_SENSE: what = "MODE_SENSE"; break;
- case START_STOP: what = "START_STOP"; break;
- case RECEIVE_DIAGNOSTIC: what = "RECEIVE_DIAGNOSTIC"; break;
- case SEND_DIAGNOSTIC: what = "SEND_DIAGNOSTIC"; break;
- case ALLOW_MEDIUM_REMOVAL: what = "ALLOW_MEDIUM_REMOVAL"; break;
- case SET_WINDOW: what = "SET_WINDOW"; break;
- case READ_CAPACITY: what = "READ_CAPACITY"; break;
- case READ_10: what = "READ_10"; break;
- case WRITE_10: what = "WRITE_10"; break;
- case SEEK_10: what = "SEEK_10"; break;
- case WRITE_VERIFY: what = "WRITE_VERIFY"; break;
- case VERIFY: what = "VERIFY"; break;
- case SEARCH_HIGH: what = "SEARCH_HIGH"; break;
- case SEARCH_EQUAL: what = "SEARCH_EQUAL"; break;
- case SEARCH_LOW: what = "SEARCH_LOW"; break;
- case SET_LIMITS: what = "SET_LIMITS"; break;
- case READ_POSITION: what = "READ_POSITION"; break;
- case SYNCHRONIZE_CACHE: what = "SYNCHRONIZE_CACHE"; break;
- case LOCK_UNLOCK_CACHE: what = "LOCK_UNLOCK_CACHE"; break;
- case READ_DEFECT_DATA: what = "READ_DEFECT_DATA"; break;
- case MEDIUM_SCAN: what = "MEDIUM_SCAN"; break;
- case COMPARE: what = "COMPARE"; break;
- case COPY_VERIFY: what = "COPY_VERIFY"; break;
- case WRITE_BUFFER: what = "WRITE_BUFFER"; break;
- case READ_BUFFER: what = "READ_BUFFER"; break;
- case UPDATE_BLOCK: what = "UPDATE_BLOCK"; break;
- case READ_LONG: what = "READ_LONG"; break;
- case WRITE_LONG: what = "WRITE_LONG"; break;
- case CHANGE_DEFINITION: what = "CHANGE_DEFINITION"; break;
- case WRITE_SAME: what = "WRITE_SAME"; break;
- case READ_TOC: what = "READ_TOC"; break;
- case LOG_SELECT: what = "LOG_SELECT"; break;
- case LOG_SENSE: what = "LOG_SENSE"; break;
- case MODE_SELECT_10: what = "MODE_SELECT_10"; break;
- case MODE_SENSE_10: what = "MODE_SENSE_10"; break;
- case MOVE_MEDIUM: what = "MOVE_MEDIUM"; break;
- case READ_12: what = "READ_12"; break;
- case WRITE_12: what = "WRITE_12"; break;
- case WRITE_VERIFY_12: what = "WRITE_VERIFY_12"; break;
- case SEARCH_HIGH_12: what = "SEARCH_HIGH_12"; break;
- case SEARCH_EQUAL_12: what = "SEARCH_EQUAL_12"; break;
- case SEARCH_LOW_12: what = "SEARCH_LOW_12"; break;
- case READ_ELEMENT_STATUS: what = "READ_ELEMENT_STATUS"; break;
- case SEND_VOLUME_TAG: what = "SEND_VOLUME_TAG"; break;
- case WRITE_LONG_2: what = "WRITE_LONG_2"; break;
- default: break;
- }
- printk(KERN_DEBUG USB_SCSI "Command %s (%d bytes)\n", what, srb->cmd_len);
- printk(KERN_DEBUG USB_SCSI " %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- srb->cmnd[0], srb->cmnd[1], srb->cmnd[2], srb->cmnd[3], srb->cmnd[4], srb->cmnd[5],
- srb->cmnd[6], srb->cmnd[7], srb->cmnd[8], srb->cmnd[9]);
-}
diff --git a/drivers/usb/usb_storage.c b/drivers/usb/usb_storage.c
new file mode 100644
index 000000000..0ebb1e413
--- /dev/null
+++ b/drivers/usb/usb_storage.c
@@ -0,0 +1,1837 @@
+/* Driver for USB Mass Storage compliant devices
+ *
+ * (c) 1999 Michael Gee (michael@linuxspecific.com)
+ * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
+ *
+ * Further reference:
+ * This driver is based on the 'USB Mass Storage Class' document. This
+ * describes in detail the protocol used to communicate with such
+ * devices. Clearly, the designers had SCSI commands in mind when they
+ * created this document. The commands are all similar to commands
+ * in the SCSI-II specification.
+ *
+ * It is important to note that in a number of cases this class exhibits
+ * class-specific exemptions from the USB specification. Notably the
+ * usage of NAK, STALL and ACK differs from the norm, in that they are
+ * used to communicate wait, failed and OK on commands.
+ * Also, for certain devices, the interrupt endpoint is used to convey
+ * status of a command.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/random.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/malloc.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+
+#include <linux/blk.h>
+#include "../scsi/scsi.h"
+#include "../scsi/hosts.h"
+#include "../scsi/sd.h"
+
+#include "usb.h"
+#include "usb_storage.h"
+
+/* direction table -- this indicates the direction of the data
+ * transfer for each command code -- a 1 indicates input
+ */
+unsigned char us_direction[256/8] = {
+ 0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
+ 0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/*
+ * Per device data
+ */
+
+static int my_host_number;
+
+int usb_stor_debug = 1;
+
+struct us_data;
+
+typedef int (*trans_cmnd)(Scsi_Cmnd*, struct us_data*);
+typedef int (*trans_reset)(struct us_data*);
+typedef void (*proto_cmnd)(Scsi_Cmnd*, struct us_data*);
+
+struct us_data {
+ struct us_data *next; /* next device */
+ struct usb_device *pusb_dev; /* this usb_device */
+ unsigned int flags; /* from filter initially */
+ __u8 ifnum; /* interface number */
+ __u8 ep_in; /* in endpoint */
+ __u8 ep_out; /* out ....... */
+ __u8 ep_int; /* interrupt . */
+ __u8 subclass; /* as in overview */
+ __u8 protocol; /* .............. */
+ __u8 attention_done; /* force attn on first cmd */
+ trans_cmnd transport; /* protocol specific do cmd */
+ trans_reset transport_reset; /* .......... device reset */
+ proto_cmnd proto_handler; /* protocol handler */
+ GUID(guid); /* unique dev id */
+ struct Scsi_Host *host; /* our dummy host data */
+ Scsi_Host_Template *htmplt; /* own host template */
+ int host_number; /* to find us */
+ int host_no; /* allocated by scsi */
+ Scsi_Cmnd *srb; /* current srb */
+ int action; /* what to do */
+ wait_queue_head_t waitq; /* thread waits */
+ wait_queue_head_t ip_waitq; /* for CBI interrupts */
+ __u16 ip_data; /* interrupt data */
+ int ip_wanted; /* needed */
+ int pid; /* control thread */
+ struct semaphore *notify; /* wait for thread to begin */
+ void *irq_handle; /* for USB int requests */
+ unsigned int irqpipe; /* pipe for release_irq */
+};
+
+/*
+ * kernel thread actions
+ */
+
+#define US_ACT_COMMAND 1
+#define US_ACT_ABORT 2
+#define US_ACT_DEVICE_RESET 3
+#define US_ACT_BUS_RESET 4
+#define US_ACT_HOST_RESET 5
+
+static struct us_data *us_list;
+
+static void * storage_probe(struct usb_device *dev, unsigned int ifnum);
+static void storage_disconnect(struct usb_device *dev, void *ptr);
+static struct usb_driver storage_driver = {
+ "usb-storage",
+ storage_probe,
+ storage_disconnect,
+ { NULL, NULL }
+};
+
+/***********************************************************************
+ * Data transfer routines
+ ***********************************************************************/
+
+/* Transfer one buffer (breaking into packets if necessary)
+ * Note that this function is necessary because if the device NAKs, we
+ * need to know that information directly
+ *
+ * FIXME: is the above true? Or will the URB status show ETIMEDOUT after
+ * retrying several times allready? Perhaps this is the way we should
+ * be going anyway?
+ */
+static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
+{
+ int max_size;
+ int this_xfer;
+ int result;
+ int partial;
+ int maxtry;
+
+ /* determine the maximum packet size for these transfers */
+ max_size = usb_maxpacket(us->pusb_dev,
+ pipe, usb_pipeout(pipe)) * 16;
+
+ /* while we have data left to transfer */
+ while (length) {
+
+ /* calculate how long this will be -- maximum or a remainder */
+ this_xfer = length > max_size ? max_size : length;
+ length -= this_xfer;
+
+ /* FIXME: this number is totally outrageous. We need to pick
+ * a better (smaller) number).
+ */
+
+ /* setup the retry counter */
+ maxtry = 100;
+
+ /* set up the transfer loop */
+ do {
+ /* transfer the data */
+ US_DEBUGP("Bulk xfer 0x%x(%d) try #%d\n",
+ (unsigned int)buf, this_xfer, 101 - maxtry);
+ result = usb_bulk_msg(us->pusb_dev, pipe, buf,
+ this_xfer, &partial, HZ*5);
+ US_DEBUGP("bulk_msg returned %d xferred %d/%d\n",
+ result, partial, this_xfer);
+
+ /* if we stall, we need to clear it before we go on */
+ if (result == -EPIPE) {
+ US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
+ usb_clear_halt(us->pusb_dev, pipe);
+ }
+
+ /* update to show what data was transferred */
+ this_xfer -= partial;
+ buf += partial;
+
+ /* NAK - we retry a few times */
+ if (result == -ETIMEDOUT) {
+
+ US_DEBUGP("us_one_transfer: device NAKed\n");
+
+ /* if our try counter reaches 0, bail out */
+ if (!maxtry--)
+ return -ETIMEDOUT;
+
+ /* just continue the while loop */
+ continue;
+ }
+
+ /* other errors (besides NAK) -- we just bail out*/
+ if (result != 0) {
+ US_DEBUGP("us_one_transfer: device returned error %d\n", result);
+ return result;
+ }
+
+ /* continue until this transfer is done */
+ } while ( this_xfer );
+ }
+
+ /* if we get here, we're done and successful */
+ return 0;
+}
+
+static unsigned int us_transfer_length(Scsi_Cmnd *srb);
+
+/* transfer one SCSI command, using scatter-gather if requested */
+/* FIXME: what do the return codes here mean? */
+static int us_transfer(Scsi_Cmnd *srb, int dir_in)
+{
+ struct us_data *us = (struct us_data *)srb->host_scribble;
+ int i;
+ int result = -1;
+ unsigned int pipe = dir_in ? usb_rcvbulkpipe(us->pusb_dev, us->ep_in) :
+ usb_sndbulkpipe(us->pusb_dev, us->ep_out);
+
+ /* FIXME: stop transferring data at us_transfer_length(), not
+ * bufflen */
+ if (srb->use_sg) {
+ struct scatterlist *sg = (struct scatterlist *) srb->request_buffer;
+
+ for (i = 0; i < srb->use_sg; i++) {
+ result = us_one_transfer(us, pipe, sg[i].address, sg[i].length);
+ if (result)
+ break;
+ }
+ }
+ else
+ result = us_one_transfer(us, pipe, srb->request_buffer,
+ us_transfer_length(srb));
+
+ if (result < 0)
+ US_DEBUGP("us_transfer returning error %d\n", result);
+ return result;
+}
+
+/* calculate the length of the data transfer (not the command) for any
+ * given SCSI command
+ */
+static unsigned int us_transfer_length(Scsi_Cmnd *srb)
+{
+ int i;
+ unsigned int total = 0;
+
+ /* always zero for some commands */
+ switch (srb->cmnd[0]) {
+ case SEEK_6:
+ case SEEK_10:
+ case REZERO_UNIT:
+ case ALLOW_MEDIUM_REMOVAL:
+ case START_STOP:
+ case TEST_UNIT_READY:
+ return 0;
+
+ case REQUEST_SENSE:
+ case INQUIRY:
+ case MODE_SENSE:
+ return srb->cmnd[4];
+
+ case LOG_SENSE:
+ case MODE_SENSE_10:
+ return (srb->cmnd[7] << 8) + srb->cmnd[8];
+
+ default:
+ break;
+ }
+
+ if (srb->use_sg) {
+ struct scatterlist *sg = (struct scatterlist *) srb->request_buffer;
+
+ for (i = 0; i < srb->use_sg; i++) {
+ total += sg[i].length;
+ }
+ return total;
+ }
+ else
+ return srb->request_bufflen;
+}
+
+/***********************************************************************
+ * Protocol routines
+ ***********************************************************************/
+
+static int CB_transport(Scsi_Cmnd *srb, struct us_data *us);
+static int Bulk_transport(Scsi_Cmnd *srb, struct us_data *us);
+
+static void ufi_command(Scsi_Cmnd *srb, struct us_data *us)
+{
+ int old_cmnd = 0;
+
+ /* fix some commands -- this is a form of mode translation
+ * UFI devices only accept 12 byte long commands
+ *
+ * NOTE: This only works because a Scsi_Cmnd struct field contains
+ * a unsigned char cmnd[12], so we know we have storage available
+ */
+
+ /* set command length to 12 bytes (this affects the transport layer) */
+ srb->cmd_len = 12;
+
+ /* determine the correct (or minimum) data length for these commands */
+ switch (us->srb->cmnd[0]) {
+
+ /* for INQUIRY, UFI devices only ever return 36 bytes */
+ case INQUIRY:
+ us->srb->cmnd[4] = 36;
+ break;
+
+ /* change MODE_SENSE/MODE_SELECT from 6 to 10 byte commands */
+ case MODE_SENSE:
+ case MODE_SELECT:
+ /* save the command so we can tell what it was */
+ old_cmnd = srb->cmnd[0];
+
+ srb->cmnd[11] = 0;
+ srb->cmnd[10] = 0;
+ srb->cmnd[9] = 0;
+
+ /* if we're sending data, we send all. If getting data,
+ * get the minimum */
+ if (srb->cmnd[0] == MODE_SELECT)
+ srb->cmnd[8] = srb->cmnd[4];
+ else
+ srb->cmnd[8] = 8;
+
+ srb->cmnd[7] = 0;
+ srb->cmnd[6] = 0;
+ srb->cmnd[5] = 0;
+ srb->cmnd[4] = 0;
+ srb->cmnd[3] = 0;
+ srb->cmnd[2] = srb->cmnd[2];
+ srb->cmnd[1] = srb->cmnd[1];
+ srb->cmnd[0] = srb->cmnd[0] | 0x40;
+ break;
+
+ /* again, for MODE_SENSE_10, we get the minimum (8) */
+ case MODE_SENSE_10:
+ us->srb->cmnd[7] = 0;
+ us->srb->cmnd[8] = 8;
+ break;
+
+ /* for REQUEST_SENSE, UFI devices only ever return 18 bytes */
+ case REQUEST_SENSE:
+ us->srb->cmnd[4] = 18;
+ break;
+
+ /* change READ_6/WRITE_6 to READ_10/WRITE_10, which
+ * are UFI commands */
+ case WRITE_6:
+ case READ_6:
+ srb->cmnd[11] = 0;
+ srb->cmnd[10] = 0;
+ srb->cmnd[9] = 0;
+ srb->cmnd[8] = srb->cmnd[4];
+ srb->cmnd[7] = 0;
+ srb->cmnd[6] = 0;
+ srb->cmnd[5] = srb->cmnd[3];
+ srb->cmnd[4] = srb->cmnd[2];
+ srb->cmnd[3] = srb->cmnd[1] & 0x1F;
+ srb->cmnd[2] = 0;
+ srb->cmnd[1] = srb->cmnd[1] & 0xE0;
+ srb->cmnd[0] = srb->cmnd[0] | 0x20;
+ break;
+ } /* end switch on cmnd[0] */
+
+ /* send the command to the transport layer */
+ us->srb->result = us->transport(srb, us);
+
+ /* if we have an error, we're going to do a
+ * REQUEST_SENSE automatically */
+
+ /* FIXME: we should only do this for device
+ * errors, not system errors */
+ if (us->srb->result) {
+ int temp_result;
+ int count;
+ void* old_request_buffer;
+
+ US_DEBUGP("Command FAILED: Issuing auto-REQUEST_SENSE\n");
+
+ /* set the result so the higher layers expect this data */
+ us->srb->result = CHECK_CONDITION;
+
+ us->srb->cmnd[0] = REQUEST_SENSE;
+ us->srb->cmnd[1] = 0;
+ us->srb->cmnd[2] = 0;
+ us->srb->cmnd[3] = 0;
+ us->srb->cmnd[4] = 18;
+ us->srb->cmnd[5] = 0;
+
+ /* set the buffer length for transfer */
+ old_request_buffer = us->srb->request_buffer;
+ us->srb->request_bufflen = 18;
+ us->srb->request_buffer = kmalloc(18, GFP_KERNEL);
+
+ /* FIXME: what if this command fails? */
+ temp_result = us->transport(us->srb, us);
+ US_DEBUGP("-- Result from auto-sense is %d\n", temp_result);
+
+ /* copy the data from the request buffer to the sense buffer */
+ for(count = 0; count < 18; count++)
+ us->srb->sense_buffer[count] =
+ ((unsigned char *)(us->srb->request_buffer))[count];
+
+ US_DEBUGP("-- sense key: 0x%x, ASC: 0x%x, ASCQ: 0x%x\n",
+ us->srb->sense_buffer[2] & 0xf,
+ us->srb->sense_buffer[12], us->srb->sense_buffer[13]);
+
+ /* we're done here */
+ kfree(us->srb->request_buffer);
+ us->srb->request_buffer = old_request_buffer;
+ return;
+ }
+
+ /* FIXME: if we need to send more data, or recieve data, we should
+ * do it here. Then, we can do status handling here also.
+ *
+ * This includes MODE_SENSE from above
+ */
+ if (old_cmnd == MODE_SENSE) {
+ unsigned char *dta = (unsigned char *)us->srb->request_buffer;
+
+ /* calculate the new length */
+ int length = (dta[0] << 8) + dta[1] + 2;
+
+ /* copy the available data length into the structure */
+ us->srb->cmnd[7] = length >> 8;
+ us->srb->cmnd[8] = length & 0xFF;
+
+ /* send the command to the transport layer */
+ us->srb->result = us->transport(srb, us);
+
+ /* FIXME: this assumes that the 2nd attempt is always
+ * successful convert MODE_SENSE_10 return data format
+ * to MODE_SENSE_6 format */
+ dta[0] = dta[1]; /* data len */
+ dta[1] = dta[2]; /* med type */
+ dta[2] = dta[3]; /* dev-spec prm */
+ dta[3] = dta[7]; /* block desc len */
+ printk (KERN_DEBUG USB_STORAGE
+ "new MODE_SENSE_6 data = %.2X %.2X %.2X %.2X\n",
+ dta[0], dta[1], dta[2], dta[3]);
+ }
+
+ /* FIXME: if this was a TEST_UNIT_READY, and we get a NOT READY/
+ * LOGICAL DRIVE NOT READY then we do a START_STOP, and retry
+ */
+
+ /* FIXME: here is where we need to fix-up the return data from
+ * an INQUIRY command to show ANSI SCSI rev 2
+ */
+
+ /* FIXME: The rest of this is bogus. usb_control_msg() will only
+ * return an error if we've really honked things up. If it just
+ * needs a START_STOP, then we'll get some data back via
+ * REQUEST_SENSE -- either way, this belongs at a higher level
+ */
+
+#if 0
+ /* For UFI, if this is the first time we've sent this TEST_UNIT_READY
+ * command, we can try again
+ */
+ if (!done_start && (us->subclass == US_SC_UFI)
+ && (cmd[0] == TEST_UNIT_READY) && (result < 0)) {
+
+ /* as per spec try a start command, wait and retry */
+ wait_ms(100);
+
+ done_start++;
+ memset(cmd, 0, sizeof(cmd));
+ cmd[0] = START_STOP;
+ cmd[4] = 1; /* start */
+
+ result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
+ US_CBI_ADSC,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, us->ifnum,
+ cmd, 12, HZ*5);
+ US_DEBUGP("Next usb_control_msg returns %d\n", result);
+
+ /* allow another retry */
+ retry++;
+ continue;
+ }
+#endif
+}
+
+static void transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us)
+{
+ unsigned int savelen = us->srb->request_bufflen;
+ unsigned int saveallocation = 0;
+
+#if 0
+ /* force attention on first command */
+ if (!us->attention_done) {
+ if (us->srb->cmnd[0] == REQUEST_SENSE) {
+ US_DEBUGP("forcing unit attention\n");
+ us->attention_done = 1;
+
+ if (us->srb->result == USB_STOR_TRANSPORT_GOOD) {
+ unsigned char *p = (unsigned char *)us->srb->request_buffer;
+
+ if ((p[2] & 0x0f) != UNIT_ATTENTION) {
+ p[2] = UNIT_ATTENTION;
+ p[12] = 0x29; /* power on, reset or bus-reset */
+ p[13] = 0;
+ } /* if ((p[2] & 0x0f) != UNIT_ATTENTION) */
+ } /* if (us->srb->result == USB_STORE_TRANSPORT_GOOD) */
+ }
+ } /* if (!us->attention_done) */
+#endif
+
+ /* If the command has a variable-length payload, then we do them
+ * in two steps -- first we do the minimum, then we recalculate
+ * then length, and re-issue the command
+ *
+ * we use savelen to remember how much buffer we really have
+ * we use savealloction to remember how much was really requested
+ */
+
+ /* FIXME: remove savelen based on mods to us_transfer_length() */
+ switch (us->srb->cmnd[0]) {
+ case REQUEST_SENSE:
+ if (us->srb->request_bufflen > 18)
+ us->srb->request_bufflen = 18;
+ else
+ break;
+ saveallocation = us->srb->cmnd[4];
+ us->srb->cmnd[4] = 18;
+ break;
+
+ case INQUIRY:
+ if (us->srb->request_bufflen > 36)
+ us->srb->request_bufflen = 36;
+ else
+ break;
+ saveallocation = us->srb->cmnd[4];
+ us->srb->cmnd[4] = 36;
+ break;
+
+ case MODE_SENSE:
+ if (us->srb->request_bufflen > 4)
+ us->srb->request_bufflen = 4;
+ else
+ break;
+ saveallocation = us->srb->cmnd[4];
+ us->srb->cmnd[4] = 4;
+ break;
+
+ case LOG_SENSE:
+ case MODE_SENSE_10:
+ if (us->srb->request_bufflen > 8)
+ us->srb->request_bufflen = 8;
+ else
+ break;
+ saveallocation = (us->srb->cmnd[7] << 8) | us->srb->cmnd[8];
+ us->srb->cmnd[7] = 0;
+ us->srb->cmnd[8] = 8;
+ break;
+
+ default:
+ break;
+ } /* end switch on cmnd[0] */
+
+ /* This code supports devices which do not support {READ|WRITE}_6
+ * Apparently, neither Windows or MacOS will use these commands,
+ * so some devices do not support them
+ */
+ if (us->flags & US_FL_MODE_XLATE) {
+
+ /* translate READ_6 to READ_10 */
+ if (us->srb->cmnd[0] == 0x08) {
+
+ /* get the control */
+ us->srb->cmnd[9] = us->srb->cmnd[5];
+
+ /* get the length */
+ us->srb->cmnd[8] = us->srb->cmnd[6];
+ us->srb->cmnd[7] = 0;
+
+ /* set the reserved area to 0 */
+ us->srb->cmnd[6] = 0;
+
+ /* get LBA */
+ us->srb->cmnd[5] = us->srb->cmnd[3];
+ us->srb->cmnd[4] = us->srb->cmnd[2];
+ us->srb->cmnd[3] = 0;
+ us->srb->cmnd[2] = 0;
+
+ /* LUN and other info in cmnd[1] can stay */
+
+ /* fix command code */
+ us->srb->cmnd[0] = 0x28;
+
+ US_DEBUGP("Changing READ_6 to READ_10\n");
+ US_DEBUG(us_show_command(us->srb));
+ }
+
+ /* translate WRITE_6 to WRITE_10 */
+ if (us->srb->cmnd[0] == 0x0A) {
+
+ /* get the control */
+ us->srb->cmnd[9] = us->srb->cmnd[5];
+
+ /* get the length */
+ us->srb->cmnd[8] = us->srb->cmnd[4];
+ us->srb->cmnd[7] = 0;
+
+ /* set the reserved area to 0 */
+ us->srb->cmnd[6] = 0;
+
+ /* get LBA */
+ us->srb->cmnd[5] = us->srb->cmnd[3];
+ us->srb->cmnd[4] = us->srb->cmnd[2];
+ us->srb->cmnd[3] = 0;
+ us->srb->cmnd[2] = 0;
+
+ /* LUN and other info in cmnd[1] can stay */
+
+ /* fix command code */
+ us->srb->cmnd[0] = 0x2A;
+
+ US_DEBUGP("Changing WRITE_6 to WRITE_10\n");
+ US_DEBUG(us_show_command(us->srb));
+ }
+ } /* end if (us->flags & US_FL_MODE_XLATE) */
+
+ /* send the command to the transport layer */
+ us->srb->result = us->transport(us->srb, us);
+
+ /* if we have an error, we're going to do a REQUEST_SENSE
+ * automatically */
+ /* FIXME: we should only do this for device errors, not
+ * system errors */
+ if (us->srb->result) {
+ int temp_result;
+ int count;
+ void* old_request_buffer;
+
+ US_DEBUGP("Command FAILED: Issuing auto-REQUEST_SENSE\n");
+
+ /* set the result so the higher layers expect this data */
+ us->srb->result = CHECK_CONDITION;
+
+ us->srb->cmnd[0] = REQUEST_SENSE;
+ us->srb->cmnd[1] = 0;
+ us->srb->cmnd[2] = 0;
+ us->srb->cmnd[3] = 0;
+ us->srb->cmnd[4] = 18;
+ us->srb->cmnd[5] = 0;
+
+ /* set the buffer length for transfer */
+ old_request_buffer = us->srb->request_buffer;
+ us->srb->request_bufflen = 18;
+ us->srb->request_buffer = kmalloc(18, GFP_KERNEL);
+
+ /* FIXME: what if this command fails? */
+ temp_result = us->transport(us->srb, us);
+ US_DEBUGP("-- Result from auto-sense is %d\n", temp_result);
+
+ /* copy the data from the request buffer to the sense buffer */
+ for(count = 0; count < 18; count++)
+ us->srb->sense_buffer[count] =
+ ((unsigned char *)(us->srb->request_buffer))[count];
+
+ US_DEBUGP("-- sense key: 0x%x, ASC: 0x%x, ASCQ: 0x%x\n",
+ us->srb->sense_buffer[2] & 0xf,
+ us->srb->sense_buffer[12], us->srb->sense_buffer[13]);
+
+ /* we're done here */
+ kfree(us->srb->request_buffer);
+ us->srb->request_buffer = old_request_buffer;
+ return;
+ }
+
+ if (savelen != us->srb->request_bufflen) {
+ unsigned char *p = (unsigned char *)us->srb->request_buffer;
+ unsigned int length = 0;
+
+ /* set correct length and retry */
+ switch (us->srb->cmnd[0]) {
+
+ /* FIXME: we should try to get all the sense data */
+ case REQUEST_SENSE:
+ /* simply return 18 bytes */
+ p[7] = 10;
+ length = us->srb->request_bufflen;
+ break;
+
+ case INQUIRY:
+ length = p[4] + 5 > savelen ? savelen : p[4] + 5;
+ us->srb->cmnd[4] = length;
+ break;
+
+ case MODE_SENSE:
+ US_DEBUGP("MODE_SENSE Mode data length is %d\n", p[0]);
+ length = p[0] + 1 > savelen ? savelen : p[0] + 1;
+ us->srb->cmnd[4] = length;
+ break;
+
+ case LOG_SENSE:
+ length = ((p[2] << 8) + p[3]) + 4 > savelen ? savelen : ((p[2] << 8) + p[3]) + 4;
+ us->srb->cmnd[7] = length >> 8;
+ us->srb->cmnd[8] = length;
+ break;
+
+ case MODE_SENSE_10:
+ US_DEBUGP("MODE_SENSE_10 Mode data length is %d\n",
+ (p[0] << 8) + p[1]);
+ length = ((p[0] << 8) + p[1]) + 6 > savelen ? savelen : ((p[0] << 8) + p[1]) + 6;
+ us->srb->cmnd[7] = length >> 8;
+ us->srb->cmnd[8] = length;
+ break;
+ } /* end switch on cmnd[0] */
+
+ US_DEBUGP("Old/New length = %d/%d\n",
+ savelen, length);
+
+ /* issue the new command */
+ /* FIXME: this assumes that the second attempt is
+ * always successful */
+ if (us->srb->request_bufflen != length) {
+ US_DEBUGP("redoing cmd with len=%d\n", length);
+ us->srb->request_bufflen = length;
+ us->srb->result = us->transport(us->srb, us);
+ }
+
+ /* reset back to original values */
+ us->srb->request_bufflen = savelen;
+
+ /* fix data as necessary */
+ switch (us->srb->cmnd[0]) {
+ case INQUIRY:
+ if ((((unsigned char*)us->srb->request_buffer)[2] & 0x7) == 0) {
+ US_DEBUGP("Fixing INQUIRY data, setting SCSI rev to 2\n");
+ ((unsigned char*)us->srb->request_buffer)[2] |= 2;
+ }
+ /* FALL THROUGH */
+ case REQUEST_SENSE:
+ case MODE_SENSE:
+ if (us->srb->use_sg == 0 && length > 0) {
+ int i;
+ printk(KERN_DEBUG "Data is");
+ for (i = 0; i < 32 && i < length; ++i)
+ printk(" %.2x", ((unsigned char *)us->srb->request_buffer)[i]);
+ if (i < length)
+ printk(" ...");
+ printk("\n");
+ }
+
+ /* FIXME: is this really necessary? */
+ us->srb->cmnd[4] = saveallocation;
+ break;
+
+ case LOG_SENSE:
+ case MODE_SENSE_10:
+ /* FIXME: is this really necessary? */
+ us->srb->cmnd[7] = saveallocation >> 8;
+ us->srb->cmnd[8] = saveallocation;
+ break;
+ } /* end switch on cmnd[0] */
+ } /* if good command */
+}
+
+/***********************************************************************
+ * Transport routines
+ ***********************************************************************/
+
+static int CBI_irq(int state, void *buffer, int len, void *dev_id)
+{
+ struct us_data *us = (struct us_data *)dev_id;
+
+ US_DEBUGP("USB IRQ recieved for device on host %d\n", us->host_no);
+
+ /* save the data for interpretation later */
+ if (state != USB_ST_REMOVED) {
+ us->ip_data = le16_to_cpup((__u16 *)buffer);
+ US_DEBUGP("Interrupt Status 0x%x\n", us->ip_data);
+ }
+
+ /* was this a wanted interrupt? */
+ if (us->ip_wanted) {
+ us->ip_wanted = 0;
+ wake_up(&us->ip_waitq);
+ } else {
+ US_DEBUGP("ERROR: Unwanted interrupt received!\n");
+ }
+
+ /* This return code is truly meaningless -- and I mean truly. It gets
+ * ignored by other layers. It used to indicate if we wanted to get
+ * another interrupt or disable the interrupt callback
+ */
+ return 0;
+}
+
+/* FIXME: this reset function doesn't really reset the port, and it
+ * should. Actually it should probably do what it's doing here, and
+ * reset the port physically
+ */
+static int CB_reset(struct us_data *us)
+{
+ unsigned char cmd[12];
+ int result;
+
+ US_DEBUGP("CB_reset\n");
+
+ memset(cmd, 0xFF, sizeof(cmd));
+ cmd[0] = SEND_DIAGNOSTIC;
+ cmd[1] = 4;
+ result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
+ US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, us->ifnum, cmd, sizeof(cmd), HZ*5);
+
+ /* long wait for reset */
+ schedule_timeout(HZ*6);
+
+ US_DEBUGP("CB_reset: clearing endpoint halt\n");
+ usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
+ usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_out));
+
+ US_DEBUGP("CB_reset done\n");
+ return 0;
+}
+
+static int pop_CB_status(Scsi_Cmnd *srb);
+
+/* FIXME: we also need a CBI_command which sets up the completion
+ * interrupt, and waits for it
+ */
+static int CB_transport(Scsi_Cmnd *srb, struct us_data *us)
+{
+ int result;
+
+ US_DEBUGP("CBI gets a command:\n");
+ US_DEBUG(us_show_command(srb));
+
+ /* FIXME: we aren't setting the ip_wanted indicator early enough, which
+ * causes some commands to never complete. This hangs the driver.
+ */
+
+ /* let's send the command via the control pipe */
+ result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
+ US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, us->ifnum,
+ srb->cmnd, srb->cmd_len, HZ*5);
+
+ /* check the return code for the command */
+ if (result < 0) {
+ US_DEBUGP("Call to usb_control_msg() returned %d\n", result);
+
+ /* a stall is a fatal condition from the device */
+ if (result == -EPIPE) {
+ US_DEBUGP("-- Stall on control pipe detected. Clearing\n");
+
+ US_DEBUGP("-- Return from usb_clear_halt() is %d\n",
+ usb_clear_halt(us->pusb_dev,
+ usb_sndctrlpipe(us->pusb_dev, 0)));
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ /* FIXME: we need to handle NAKs here */
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ /* transfer the data payload for this command, if one exists*/
+ if (us_transfer_length(srb)) {
+ result = us_transfer(srb, US_DIRECTION(srb->cmnd[0]));
+ US_DEBUGP("CBI attempted to transfer data, result is 0x%x\n", result);
+
+ /* FIXME: what do the return codes from us_transfer mean? */
+ if ((result < 0) &&
+ (result != USB_ST_DATAUNDERRUN) &&
+ (result != USB_ST_STALL)) {
+ return DID_ERROR << 16;
+ }
+ } /* if (us_transfer_length(srb)) */
+
+ /* get status and return it */
+ return pop_CB_status(srb);
+}
+
+/*
+ * Control/Bulk status handler
+ */
+
+static int pop_CB_status(Scsi_Cmnd *srb)
+{
+ struct us_data *us = (struct us_data *)srb->host_scribble;
+ int result;
+ __u8 status[2];
+ int retry = 5;
+
+ US_DEBUGP("pop_CB_status, proto=0x%x\n", us->protocol);
+ switch (us->protocol) {
+ case US_PR_CB:
+ /* get from control */
+
+ while (retry--) {
+ result = usb_control_msg(us->pusb_dev, usb_rcvctrlpipe(us->pusb_dev,0),
+ USB_REQ_GET_STATUS, USB_DIR_IN |
+ USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+ 0, us->ifnum, status, sizeof(status), HZ*5);
+ if (result != USB_ST_TIMEOUT)
+ break;
+ }
+ if (result) {
+ US_DEBUGP("Bad AP status request %d\n", result);
+ return DID_ABORT << 16;
+ }
+ US_DEBUGP("Got AP status 0x%x 0x%x\n", status[0], status[1]);
+ if (srb->cmnd[0] != REQUEST_SENSE && srb->cmnd[0] != INQUIRY &&
+ ( (status[0] & ~3) || status[1]))
+ return (DID_OK << 16) | 2;
+ else
+ return USB_STOR_TRANSPORT_GOOD;
+ break;
+
+ /* FIXME: this should be in a separate function */
+ case US_PR_CBI:
+ /* get from interrupt pipe */
+
+ /* add interrupt transfer, marked for removal */
+ us->ip_wanted = 1;
+
+ /* go to sleep until we get this interrup */
+ /* FIXME: this should be changed to use a timeout */
+ sleep_on(&us->ip_waitq);
+
+ if (us->ip_wanted) {
+ US_DEBUGP("Did not get interrupt on CBI\n");
+ us->ip_wanted = 0;
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ US_DEBUGP("Got interrupt data 0x%x\n", us->ip_data);
+
+ /* UFI gives us ASC and ASCQ, like a request sense */
+ /* FIXME: is this right? do REQUEST_SENSE and INQUIRY need special
+ * case handling?
+ */
+ if (us->subclass == US_SC_UFI) {
+ if (srb->cmnd[0] == REQUEST_SENSE ||
+ srb->cmnd[0] == INQUIRY)
+ return USB_STOR_TRANSPORT_GOOD;
+ else
+ if (us->ip_data)
+ return USB_STOR_TRANSPORT_FAILED;
+ else
+ return USB_STOR_TRANSPORT_GOOD;
+ }
+
+ /* otherwise, we interpret the data normally */
+ switch (us->ip_data) {
+ case 0x0001:
+ return USB_STOR_TRANSPORT_GOOD;
+ case 0x0002:
+ return USB_STOR_TRANSPORT_FAILED;
+ default:
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ }
+ US_DEBUGP("pop_CB_status, reached end of function\n");
+ return USB_STOR_TRANSPORT_ERROR;
+}
+
+static int Bulk_reset(struct us_data *us)
+{
+ int result;
+
+ result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
+ US_BULK_RESET, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ US_BULK_RESET_HARD, us->ifnum,
+ NULL, 0, HZ*5);
+ if (result)
+ US_DEBUGP("Bulk hard reset failed %d\n", result);
+ usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
+ usb_clear_halt(us->pusb_dev, usb_sndbulkpipe(us->pusb_dev, us->ep_out));
+
+ /* long wait for reset */
+ schedule_timeout(HZ*6);
+
+ return result;
+}
+
+/*
+ * The bulk only protocol handler.
+ * Uses the in and out endpoints to transfer commands and data
+ */
+static int Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
+{
+ struct bulk_cb_wrap bcb;
+ struct bulk_cs_wrap bcs;
+ int result;
+ int pipe;
+ int partial;
+
+ /* set up the command wrapper */
+ bcb.Signature = US_BULK_CB_SIGN;
+ bcb.DataTransferLength = us_transfer_length(srb);
+ bcb.Flags = US_DIRECTION(srb->cmnd[0]) << 7;
+ bcb.Tag = srb->serial_number;
+ bcb.Lun = 0;
+ bcb.Length = srb->cmd_len;
+
+ /* construct the pipe handle */
+ pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
+
+ /* copy the command payload */
+ memset(bcb.CDB, 0, sizeof(bcb.CDB));
+ memcpy(bcb.CDB, srb->cmnd, bcb.Length);
+
+ /* send it to out endpoint */
+ US_DEBUGP("Bulk command S 0x%x T 0x%x L %d F %d CL %d\n",
+ bcb.Signature, bcb.Tag, bcb.DataTransferLength,
+ bcb.Flags, bcb.Length);
+ result = usb_bulk_msg(us->pusb_dev, pipe, &bcb,
+ US_BULK_CB_WRAP_LEN, &partial, HZ*5);
+ US_DEBUGP("Bulk command transfer result 0x%x\n", result);
+
+ /* if we stall, we need to clear it before we go on */
+ if (result == -EPIPE) {
+ US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
+ usb_clear_halt(us->pusb_dev, pipe);
+ }
+
+ /* if the command transfered well, then we go to the data stage */
+ /* FIXME: Regardless of the status of the data stage, we go on to the
+ * status stage. Note that this implies that if a command is
+ * partially successful, we rely on the device reporting an error
+ * the CSW. The spec says that the device may just decide to short us.
+ */
+ if (result == 0) {
+ /* send/receive data payload, if there is any */
+ if (bcb.DataTransferLength) {
+ result = us_transfer(srb, bcb.Flags);
+ US_DEBUGP("Bulk data transfer result 0x%x\n", result);
+#if 0
+ if ((result < 0) && (result != USB_ST_DATAUNDERRUN)
+ && (result != USB_ST_STALL)) {
+ US_DEBUGP("Bulk data transfer result 0x%x\n", result);
+ return DID_ABORT << 16;
+ }
+#endif
+ }
+ }
+
+ /* See flow chart on pg 15 of the Bulk Only Transport spec for
+ * an explanation of how this code works.
+ */
+
+ /* construct the pipe handle */
+ pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
+
+ /* get CSW for device status */
+ result = usb_bulk_msg(us->pusb_dev, pipe, &bcs,
+ US_BULK_CS_WRAP_LEN, &partial, HZ*5);
+
+ /* did the attempt to read the CSW fail? */
+ if (result == -EPIPE) {
+ US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
+ usb_clear_halt(us->pusb_dev, pipe);
+
+ /* get the status again */
+ result = usb_bulk_msg(us->pusb_dev, pipe, &bcs,
+ US_BULK_CS_WRAP_LEN, &partial, HZ*5);
+
+ /* if it fails again, we need a reset and return an error*/
+ if (result == -EPIPE) {
+ Bulk_reset(us);
+ return (DID_ABORT << 16);
+ }
+ }
+
+ /* if we still have a failure at this point, we're in trouble */
+ if (result) {
+ US_DEBUGP("Bulk status result = 0x%x\n", result);
+ return DID_ABORT << 16;
+ }
+
+ /* check bulk status */
+ US_DEBUGP("Bulk status S 0x%x T 0x%x R %d V 0x%x\n",
+ bcs.Signature, bcs.Tag, bcs.Residue, bcs.Status);
+ if (bcs.Signature != US_BULK_CS_SIGN || bcs.Tag != bcb.Tag ||
+ bcs.Status > US_BULK_STAT_PHASE || partial != 13) {
+ US_DEBUGP("Bulk logical error\n");
+ return DID_ABORT << 16;
+ }
+
+ /* based on the status code, we report good or bad */
+ switch (bcs.Status) {
+ case US_BULK_STAT_OK:
+ /* if there is residue, we really didn't finish the command */
+ if (bcs.Residue)
+ return DID_ERROR << 16;
+ else
+ return DID_OK << 16;
+
+ case US_BULK_STAT_FAIL:
+ return DID_ERROR << 16;
+
+ case US_BULK_STAT_PHASE:
+ Bulk_reset(us);
+ return DID_ERROR << 16;
+ }
+
+ return DID_OK << 16; /* check sense required */
+}
+
+/***********************************************************************
+ * Host functions
+ ***********************************************************************/
+
+/* detect adapter (always true ) */
+static int us_detect(struct SHT *sht)
+{
+ /* FIXME - not nice at all, but how else ? */
+ struct us_data *us = (struct us_data *)sht->proc_dir;
+ char name[32];
+
+ /* set up our name */
+ sprintf(name, "usbscsi%d", us->host_number);
+ sht->name = sht->proc_name = kmalloc(strlen(name)+1, GFP_KERNEL);
+ if (!sht->proc_name)
+ return 0;
+ strcpy(sht->proc_name, name);
+
+ /* we start with no /proc directory entry */
+ sht->proc_dir = NULL;
+
+ /* register the host */
+ us->host = scsi_register(sht, sizeof(us));
+ if (us->host) {
+ us->host->hostdata[0] = (unsigned long)us;
+ us->host_no = us->host->host_no;
+ return 1;
+ }
+
+ /* odd... didn't register properly. Abort and free pointers */
+ kfree(sht->proc_name);
+ sht->proc_name = NULL;
+ sht->name = NULL;
+ return 0;
+}
+
+/* release - must be here to stop scsi
+ * from trying to release IRQ etc.
+ * Kill off our data
+ */
+static int us_release(struct Scsi_Host *psh)
+{
+ struct us_data *us = (struct us_data *)psh->hostdata[0];
+ struct us_data *prev = (struct us_data *)&us_list;
+
+ if (us->irq_handle) {
+ usb_release_irq(us->pusb_dev, us->irq_handle, us->irqpipe);
+ us->irq_handle = NULL;
+ }
+ if (us->pusb_dev)
+ usb_deregister(&storage_driver);
+
+ /* FIXME - leaves hanging host template copy */
+ /* (because scsi layer uses it after removal !!!) */
+ while (prev->next != us)
+ prev = prev->next;
+ prev->next = us->next;
+ return 0;
+}
+
+/* run command */
+static int us_command( Scsi_Cmnd *srb )
+{
+ US_DEBUGP("Bad use of us_command\n");
+
+ return DID_BAD_TARGET << 16;
+}
+
+/* run command */
+static int us_queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
+{
+ struct us_data *us = (struct us_data *)srb->host->hostdata[0];
+
+ US_DEBUGP("Command wakeup\n");
+ if (us->srb) {
+ /* busy */
+ }
+ srb->host_scribble = (unsigned char *)us;
+ us->srb = srb;
+ srb->scsi_done = done;
+ us->action = US_ACT_COMMAND;
+
+ /* wake up the process task */
+
+ wake_up_interruptible(&us->waitq);
+
+ return 0;
+}
+
+/* FIXME: This doesn't actually abort anything */
+static int us_abort( Scsi_Cmnd *srb )
+{
+ return 0;
+}
+
+static int us_bus_reset( Scsi_Cmnd *srb )
+{
+ // struct us_data *us = (struct us_data *)srb->host->hostdata[0];
+
+ US_DEBUGP("Bus reset requested\n");
+ // us->transport_reset(us);
+ return SUCCESS;
+}
+
+/* FIXME: This doesn't actually reset anything */
+static int us_host_reset( Scsi_Cmnd *srb )
+{
+ return 0;
+}
+
+/***********************************************************************
+ * /proc/scsi/ functions
+ ***********************************************************************/
+
+/* we use this macro to help us write into the buffer */
+#undef SPRINTF
+#define SPRINTF(args...) do { if (pos < (buffer + length)) pos += sprintf (pos, ## args); } while (0)
+
+int usb_stor_proc_info (char *buffer, char **start, off_t offset,
+ int length, int hostno, int inout)
+{
+ struct us_data *us = us_list;
+ char *pos = buffer;
+ char *tmp_ptr;
+
+ /* find our data from hostno */
+ while (us) {
+ if (us->host_no == hostno)
+ break;
+ us = us->next;
+ }
+
+ /* if we couldn't find it, we return an error */
+ if (!us)
+ return -ESRCH;
+
+ /* if someone is sending us data, just throw it away */
+ if (inout)
+ return length;
+
+ /* print the controler name */
+ SPRINTF ("Host scsi%d: usb-storage\n", hostno);
+
+ /* print product and vendor strings */
+ tmp_ptr = kmalloc(256, GFP_KERNEL);
+ if (!us->pusb_dev || !tmp_ptr) {
+ SPRINTF(" Vendor: Unknown Vendor\n");
+ SPRINTF(" Product: Unknown Product\n");
+ } else {
+ SPRINTF(" Vendor: ");
+ if (usb_string(us->pusb_dev, us->pusb_dev->descriptor.iManufacturer, tmp_ptr, 256) > 0)
+ SPRINTF("%s\n", tmp_ptr);
+ else
+ SPRINTF("Unknown Vendor\n");
+
+ SPRINTF(" Product: ");
+ if (usb_string(us->pusb_dev, us->pusb_dev->descriptor.iProduct, tmp_ptr, 256) > 0)
+ SPRINTF("%s\n", tmp_ptr);
+ else
+ SPRINTF("Unknown Product\n");
+ kfree(tmp_ptr);
+ }
+
+ SPRINTF(" Protocol: ");
+ switch (us->protocol) {
+ case US_PR_CB:
+ SPRINTF("Control/Bulk\n");
+ break;
+
+ case US_PR_CBI:
+ SPRINTF("Control/Bulk/Interrupt\n");
+ break;
+
+ case US_PR_BULK:
+ SPRINTF("Bulk only\n");
+ break;
+
+ default:
+ SPRINTF("Unknown Protocol\n");
+ break;
+ }
+
+ /* show the GUID of the device */
+ SPRINTF(" GUID: " GUID_FORMAT "\n", GUID_ARGS(us->guid));
+
+ /*
+ * Calculate start of next buffer, and return value.
+ */
+ *start = buffer + offset;
+
+ if ((pos - buffer) < offset)
+ return (0);
+ else if ((pos - buffer - offset) < length)
+ return (pos - buffer - offset);
+ else
+ return (length);
+}
+
+/*
+ * this defines our 'host'
+ */
+
+static Scsi_Host_Template my_host_template = {
+ NULL, /* next */
+ NULL, /* module */
+ NULL, /* proc_dir */
+ usb_stor_proc_info,
+ NULL, /* name - points to unique */
+ us_detect,
+ us_release,
+ NULL, /* info */
+ NULL, /* ioctl */
+ us_command,
+ us_queuecommand,
+ NULL, /* eh_strategy */
+ us_abort,
+ us_bus_reset,
+ us_bus_reset,
+ us_host_reset,
+ NULL, /* abort */
+ NULL, /* reset */
+ NULL, /* slave_attach */
+ NULL, /* bios_param */
+ 1, /* can_queue */
+ -1, /* this_id */
+ SG_ALL, /* sg_tablesize */
+ 1, /* cmd_per_lun */
+ 0, /* present */
+ FALSE, /* unchecked_isa_dma */
+ FALSE, /* use_clustering */
+ TRUE, /* use_new_eh_code */
+ TRUE /* emulated */
+};
+
+static unsigned char sense_notready[] = {
+ 0x70, /* current error */
+ 0x00,
+ 0x02, /* not ready */
+ 0x00,
+ 0x00,
+ 0x0a, /* additional length */
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x04, /* not ready */
+ 0x03, /* manual intervention */
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+static int usb_stor_control_thread(void * __us)
+{
+ struct us_data *us = (struct us_data *)__us;
+ int action;
+
+ lock_kernel();
+
+ /*
+ * This thread doesn't need any user-level access,
+ * so get rid of all our resources..
+ */
+ daemonize();
+
+ sprintf(current->comm, "usbscsi%d", us->host_number);
+
+ unlock_kernel();
+
+ up(us->notify);
+
+ for(;;) {
+ siginfo_t info;
+ int unsigned long signr;
+
+ interruptible_sleep_on(&us->waitq);
+
+ action = us->action;
+ us->action = 0;
+
+ /* FIXME: we need to examine placment of break; and
+ * scsi_done() calls */
+
+ switch (action) {
+ case US_ACT_COMMAND:
+ /* bad device */
+ if (us->srb->target || us->srb->lun) {
+ US_DEBUGP( "Bad device number (%d/%d) or dev 0x%x\n",
+ us->srb->target, us->srb->lun, (unsigned int)us->pusb_dev);
+ us->srb->result = DID_BAD_TARGET << 16;
+
+ us->srb->scsi_done(us->srb);
+ us->srb = NULL;
+ break;
+ }
+
+ /* our device has gone - pretend not ready */
+ /* FIXME: we also need to handle INQUIRY here,
+ * probably */
+ if (!us->pusb_dev) {
+ if (us->srb->cmnd[0] == REQUEST_SENSE) {
+ memcpy(us->srb->request_buffer, sense_notready,
+ sizeof(sense_notready));
+ us->srb->result = DID_OK << 16;
+ } else {
+ us->srb->result = (DID_OK << 16) | 2;
+ }
+
+ us->srb->scsi_done(us->srb);
+ us->srb = NULL;
+ break;
+ }
+
+ /* we've got a command, let's do it! */
+ US_DEBUG(us_show_command(us->srb));
+
+ /* FIXME: this is to support Shuttle E-USB bridges, it
+ * appears */
+ if (us->srb->cmnd[0] == START_STOP &&
+ us->pusb_dev->descriptor.idProduct == 0x0001 &&
+ us->pusb_dev->descriptor.idVendor == 0x04e6)
+ us->srb->result = DID_OK << 16;
+ else {
+ us->proto_handler(us->srb, us);
+ }
+
+ US_DEBUGP("scsi cmd done, result=0x%x\n", us->srb->result);
+ us->srb->scsi_done(us->srb);
+ us->srb = NULL;
+ break;
+
+ case US_ACT_ABORT:
+ break;
+
+ case US_ACT_DEVICE_RESET:
+ break;
+
+ case US_ACT_BUS_RESET:
+ break;
+
+ case US_ACT_HOST_RESET:
+ break;
+
+ } /* end switch on action */
+
+ if (signal_pending(current)) {
+ /* sending SIGUSR1 makes us print out some info */
+ spin_lock_irq(&current->sigmask_lock);
+ signr = dequeue_signal(&current->blocked, &info);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ if (signr == SIGUSR2) {
+ usb_stor_debug = !usb_stor_debug;
+ printk(USB_STORAGE "debug toggle = %d\n", usb_stor_debug);
+ } else {
+ break; /* exit the loop on any other signal */
+ }
+ }
+ }
+
+ // MOD_DEC_USE_COUNT;
+
+ printk("usb_stor_control_thread exiting\n");
+
+ /* FIXME: this is a hack to allow for debugging */
+ // scsi_unregister_module(MODULE_SCSI_HA, us->htmplt);
+
+ return 0;
+}
+
+/* Probe to see if a new device is actually a SCSI device */
+static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
+{
+ struct usb_interface_descriptor *interface;
+ int i;
+ char mf[32]; /* manufacturer */
+ char prod[32]; /* product */
+ char serial[32]; /* serial number */
+ struct us_data *ss = NULL;
+ unsigned int flags = 0;
+ GUID(guid); /* Global Unique Identifier */
+ struct us_data *prev;
+ Scsi_Host_Template *htmplt;
+ int protocol = 0;
+ int subclass = 0;
+ struct usb_interface_descriptor *altsetting =
+ &(dev->actconfig->interface[ifnum].altsetting[0]);
+
+ /* clear the GUID and fetch the strings */
+ GUID_CLEAR(guid);
+ memset(mf, 0, sizeof(mf));
+ memset(prod, 0, sizeof(prod));
+ memset(serial, 0, sizeof(serial));
+ if (dev->descriptor.iManufacturer)
+ usb_string(dev, dev->descriptor.iManufacturer, mf, sizeof(mf));
+ if (dev->descriptor.iProduct)
+ usb_string(dev, dev->descriptor.iProduct, prod, sizeof(prod));
+ if (dev->descriptor.iSerialNumber)
+ usb_string(dev, dev->descriptor.iSerialNumber, serial, sizeof(serial));
+
+ /* let's examine the device now */
+
+ /* We make an exception for the shuttle E-USB */
+ if (dev->descriptor.idVendor == 0x04e6 &&
+ dev->descriptor.idProduct == 0x0001) {
+ protocol = US_PR_CB;
+ subclass = US_SC_8070; /* an assumption */
+ } else if (dev->descriptor.bDeviceClass != 0 ||
+ altsetting->bInterfaceClass != USB_CLASS_MASS_STORAGE ||
+ altsetting->bInterfaceSubClass < US_SC_MIN ||
+ altsetting->bInterfaceSubClass > US_SC_MAX) {
+ /* if it's not a mass storage, we go no further */
+ return NULL;
+ }
+
+ /* At this point, we know we've got a live one */
+ US_DEBUGP("USB Mass Storage device detected\n");
+
+ /* Create a GUID for this device */
+ if (dev->descriptor.iSerialNumber && serial[0]) {
+ /* If we have a serial number, and it's a non-NULL string */
+ make_guid(guid, dev->descriptor.idVendor,
+ dev->descriptor.idProduct, serial);
+ } else {
+ /* We don't have a serial number, so we use 0 */
+ make_guid(guid, dev->descriptor.idVendor,
+ dev->descriptor.idProduct, "0");
+ }
+
+ /* Now check if we have seen this GUID before, and restore
+ * the flags if we find it
+ */
+ for (ss = us_list; ss != NULL; ss = ss->next) {
+ if (!ss->pusb_dev && GUID_EQUAL(guid, ss->guid)) {
+ US_DEBUGP("Found existing GUID " GUID_FORMAT "\n",
+ GUID_ARGS(guid));
+ flags = ss->flags;
+ break;
+ }
+ }
+
+ /* If ss == NULL, then this is a new device. Allocate memory for it */
+ if (!ss) {
+ if ((ss = (struct us_data *)kmalloc(sizeof(*ss),
+ GFP_KERNEL)) == NULL) {
+ printk(KERN_WARNING USB_STORAGE "Out of memory\n");
+ return NULL;
+ }
+ memset(ss, 0, sizeof(struct us_data));
+ }
+
+ /* Initialize the us_data structure with some useful info */
+ interface = altsetting;
+ ss->flags = flags;
+ ss->ifnum = ifnum;
+ ss->pusb_dev = dev;
+ ss->attention_done = 0;
+
+ /* If the device has subclass and protocol, then use that. Otherwise,
+ * take data from the specific interface.
+ */
+ if (subclass) {
+ ss->subclass = subclass;
+ ss->protocol = protocol;
+ } else {
+ ss->subclass = interface->bInterfaceSubClass;
+ ss->protocol = interface->bInterfaceProtocol;
+ }
+
+ /* set the handler pointers based on the protocol */
+ US_DEBUGP("Transport: ");
+ switch (ss->protocol) {
+ case US_PR_CB:
+ US_DEBUGPX("Control/Bulk\n");
+ ss->transport = CB_transport;
+ ss->transport_reset = CB_reset;
+ break;
+
+ case US_PR_CBI:
+ US_DEBUGPX("Control/Bulk/Interrupt\n");
+ ss->transport = CB_transport;
+ ss->transport_reset = CB_reset;
+ break;
+
+ case US_PR_BULK:
+ US_DEBUGPX("Bulk\n");
+ ss->transport = Bulk_transport;
+ ss->transport_reset = Bulk_reset;
+ break;
+
+ default:
+ US_DEBUGPX("Unknown\n");
+ kfree(ss);
+ return NULL;
+ break;
+ }
+
+ /*
+ * We are expecting a minimum of 2 endpoints - in and out (bulk).
+ * An optional interrupt is OK (necessary for CBI protocol).
+ * We will ignore any others.
+ */
+ for (i = 0; i < interface->bNumEndpoints; i++) {
+ /* is it an BULK endpoint? */
+ if ((interface->endpoint[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_BULK) {
+ if (interface->endpoint[i].bEndpointAddress & USB_DIR_IN)
+ ss->ep_in = interface->endpoint[i].bEndpointAddress &
+ USB_ENDPOINT_NUMBER_MASK;
+ else
+ ss->ep_out = interface->endpoint[i].bEndpointAddress &
+ USB_ENDPOINT_NUMBER_MASK;
+ }
+
+ /* is it an interrupt endpoint? */
+ if ((interface->endpoint[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_INT) {
+ ss->ep_int = interface->endpoint[i].bEndpointAddress &
+ USB_ENDPOINT_NUMBER_MASK;
+ }
+ }
+ US_DEBUGP("Endpoints In %d Out %d Int %d\n",
+ ss->ep_in, ss->ep_out, ss->ep_int);
+
+ /* Do some basic sanity checks, and bail if we find a problem */
+ if (usb_set_interface(dev, interface->bInterfaceNumber, 0) ||
+ !ss->ep_in || !ss->ep_out ||
+ (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
+ US_DEBUGP("Problems with device\n");
+ if (ss->host) {
+ scsi_unregister_module(MODULE_SCSI_HA, ss->htmplt);
+ kfree(ss->htmplt->name);
+ kfree(ss->htmplt);
+ }
+
+ kfree(ss);
+ return NULL;
+ }
+
+ /* If this is a new device (i.e. we haven't seen it before), we need to
+ * generate a scsi host definition, and register with scsi above us
+ */
+ if (!ss->host) {
+ /* copy the GUID we created before */
+ US_DEBUGP("New GUID " GUID_FORMAT "\n", GUID_ARGS(guid));
+ memcpy(ss->guid, guid, sizeof(guid));
+
+ /* set class specific stuff */
+ US_DEBUGP("Protocol: ");
+ switch (ss->subclass) {
+ case US_SC_RBC:
+ US_DEBUGPX("Reduced Block Commands\n");
+ break;
+
+ case US_SC_8020:
+ US_DEBUGPX("8020\n");
+ break;
+
+ case US_SC_QIC:
+ US_DEBUGPX("QIC157\n");
+ break;
+
+ case US_SC_8070:
+ US_DEBUGPX("8070\n");
+ break;
+
+ case US_SC_SCSI:
+ US_DEBUGPX("Transparent SCSI\n");
+ ss->proto_handler = transparent_scsi_command;
+ break;
+
+ case US_SC_UFI:
+ US_DEBUGPX("UFI\n");
+ ss->proto_handler = ufi_command;
+ break;
+
+ default:
+ US_DEBUGPX("Unknown\n");
+ break;
+ }
+
+ /* We only handle certain protocols. Currently, these are
+ *the only ones that devices use.
+ */
+ if ((ss->subclass != US_SC_SCSI) && (ss->subclass != US_SC_UFI)) {
+ US_DEBUGP("Sorry, we do not support that protocol yet.\n");
+ US_DEBUGP("If you have a device which uses one of the unsupported\n");
+ US_DEBUGP("protocols, please contact mdharm-usb@one-eyed-alien.net\n");
+
+ kfree(ss);
+ return NULL;
+ }
+
+ /* Allocate memory for the SCSI Host Template */
+ if ((htmplt = (Scsi_Host_Template *)
+ kmalloc(sizeof(*ss->htmplt), GFP_KERNEL)) == NULL ) {
+
+ printk(KERN_WARNING USB_STORAGE "Out of memory\n");
+
+ kfree(ss);
+ return NULL;
+ }
+
+ /* Initialize the host template based on the default one */
+ memcpy(htmplt, &my_host_template, sizeof(my_host_template));
+
+ /* Grab the next host number */
+ ss->host_number = my_host_number++;
+
+ /* MDD: FIXME: this is bad. We abuse this pointer so we
+ * can pass the ss pointer to the host controler thread
+ * in us_detect
+ */
+ (struct us_data *)htmplt->proc_dir = ss;
+
+ /* shuttle E-USB */
+ if (dev->descriptor.idVendor == 0x04e6 &&
+ dev->descriptor.idProduct == 0x0001) {
+ __u8 qstat[2];
+ int result;
+
+ result = usb_control_msg(ss->pusb_dev, usb_rcvctrlpipe(dev,0),
+ 1, 0xC0,
+ 0, ss->ifnum,
+ qstat, 2, HZ*5);
+ US_DEBUGP("C0 status 0x%x 0x%x\n", qstat[0], qstat[1]);
+ init_waitqueue_head(&ss->ip_waitq);
+ ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
+ result = usb_request_irq(ss->pusb_dev, ss->irqpipe, CBI_irq,
+ 255, (void *)ss, &ss->irq_handle);
+ if (result)
+ return NULL;
+
+ interruptible_sleep_on_timeout(&ss->ip_waitq, HZ*6);
+ } else if (ss->protocol == US_PR_CBI)
+ {
+ int result;
+
+ init_waitqueue_head(&ss->ip_waitq);
+
+ /* set up the IRQ pipe and handler */
+ /* FIXME: This needs to get the period from the device */
+ ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
+ result = usb_request_irq(ss->pusb_dev, ss->irqpipe, CBI_irq,
+ 255, (void *)ss, &ss->irq_handle);
+ if (result) {
+ US_DEBUGP("usb_request_irq failed (0x%x), No interrupt for CBI\n",
+ result);
+ }
+ }
+
+
+ /* start up our thread */
+ {
+ DECLARE_MUTEX_LOCKED(sem);
+
+ init_waitqueue_head(&ss->waitq);
+
+ ss->notify = &sem;
+ ss->pid = kernel_thread(usb_stor_control_thread, ss,
+ CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+ if (ss->pid < 0) {
+ printk(KERN_WARNING USB_STORAGE "Unable to start control thread\n");
+ kfree(htmplt);
+
+ kfree(ss);
+ return NULL;
+ }
+
+ /* wait for it to start */
+ down(&sem);
+ }
+
+ /* now register - our detect function will be called */
+ scsi_register_module(MODULE_SCSI_HA, htmplt);
+
+ /* put us in the list */
+ prev = (struct us_data *)&us_list;
+ while (prev->next)
+ prev = prev->next;
+ prev->next = ss;
+ }
+
+ printk(KERN_INFO "WARNING: USB Mass Storage data integrity not assured\n");
+ printk(KERN_INFO "USB Mass Storage device found at %d\n", dev->devnum);
+
+ return ss;
+}
+
+/* Handle a disconnect event from the USB core */
+static void storage_disconnect(struct usb_device *dev, void *ptr)
+{
+ struct us_data *ss = ptr;
+
+ if (!ss)
+ return;
+
+ ss->pusb_dev = NULL;
+ // MOD_DEC_USE_COUNT;
+}
+
+
+/***********************************************************************
+ * Initialization and registration
+ ***********************************************************************/
+
+int usb_stor_init(void)
+{
+ // MOD_INC_USE_COUNT;
+
+ /* register the driver, return -1 if error */
+ if (usb_register(&storage_driver) < 0)
+ return -1;
+
+ printk(KERN_INFO "USB Mass Storage support registered.\n");
+ return 0;
+}
+
+#ifdef MODULE
+int init_module(void)
+{
+ /* MDD: Perhaps we should register the host here */
+ return usb_stor_init();
+}
+
+void cleanup_module(void)
+{
+ usb_deregister(&storage_driver);
+}
+#endif
diff --git a/drivers/usb/usb_scsi.h b/drivers/usb/usb_storage.h
index 3e1feb783..114a2c12a 100644
--- a/drivers/usb/usb_scsi.h
+++ b/drivers/usb/usb_storage.h
@@ -1,25 +1,19 @@
-/* Driver for USB SCSI - include file
+/* Driver for USB mass storage - include file
*
- * (C) Michael Gee (michael@linuxspecific.com) 1999
- *
- * This driver is schizoid - it makes a USB scanner appear as both a SCSI device
- * and a character device. The latter is only available if the device has an
- * interrupt endpoint, and is used specifically to receive interrupt events.
- *
- * In order to support various 'strange' scanners, this module supports plug-in
- * device-specific filter modules, which can do their own thing when required.
+ * (c) 1999 Michael Gee (michael@linuxspecific.com)
+ * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
*
*/
#include <linux/config.h>
-#define USB_SCSI "usbscsi: "
+#define USB_STORAGE "usb-storage: "
extern int usb_stor_debug;
-#ifdef CONFIG_USB_SCSI_DEBUG
+#ifdef CONFIG_USB_STORAGE_DEBUG
void us_show_command(Scsi_Cmnd *srb);
-#define US_DEBUGP(x...) { if(usb_stor_debug) printk( KERN_DEBUG USB_SCSI ## x ); }
+#define US_DEBUGP(x...) { if(usb_stor_debug) printk( KERN_DEBUG USB_STORAGE ## x ); }
#define US_DEBUGPX(x...) { if(usb_stor_debug) printk( ## x ); }
#define US_DEBUG(x) { if(usb_stor_debug) x; }
#else
@@ -53,14 +47,15 @@ extern unsigned char us_direction[256/8];
* Bulk only data structures (Zip 100, for example)
*/
+/* command block wrapper */
struct bulk_cb_wrap {
- __u32 Signature; /* contains 'USBC' */
- __u32 Tag; /* unique per command id */
- __u32 DataTransferLength; /* size of data */
- __u8 Flags; /* direction in bit 0 */
- __u8 Lun; /* LUN normally 0 */
- __u8 Length; /* of of the CDB */
- __u8 CDB[16]; /* max command */
+ __u32 Signature; /* contains 'USBC' */
+ __u32 Tag; /* unique per command id */
+ __u32 DataTransferLength; /* size of data */
+ __u8 Flags; /* direction in bit 0 */
+ __u8 Lun; /* LUN normally 0 */
+ __u8 Length; /* of of the CDB */
+ __u8 CDB[16]; /* max command */
};
#define US_BULK_CB_WRAP_LEN 31
@@ -68,12 +63,13 @@ struct bulk_cb_wrap {
#define US_BULK_FLAG_IN 1
#define US_BULK_FLAG_OUT 0
+/* command status wrapper */
struct bulk_cs_wrap {
- __u32 Signature; /* should = 'USBS' */
- __u32 Tag; /* same as original command */
- __u32 Residue; /* amount not transferred */
- __u8 Status; /* see below */
- __u8 Filler[18];
+ __u32 Signature; /* should = 'USBS' */
+ __u32 Tag; /* same as original command */
+ __u32 Residue; /* amount not transferred */
+ __u8 Status; /* see below */
+ __u8 Filler[18];
};
#define US_BULK_CS_WRAP_LEN 31
@@ -87,24 +83,22 @@ struct bulk_cs_wrap {
#define US_BULK_RESET_HARD 0
/*
- * CBI style
+ * Transport return codes
*/
-#define US_CBI_ADSC 0
+#define USB_STOR_TRANSPORT_GOOD 0 /* Transport good, command good */
+#define USB_STOR_TRANSPORT_FAILED 1 /* Transport good, command failed */
+#define USB_STOR_TRANSPORT_ERROR 2 /* Transport bad (i.e. device dead */
/*
- * Filter device definitions
+ * CBI style
*/
-struct usb_scsi_filter {
- struct usb_scsi_filter * next; /* usb_scsi driver only */
- char *name; /* not really required */
+#define US_CBI_ADSC 0
- unsigned int flags; /* Filter flags */
- void * (* probe) (struct usb_device *, char *, char *, char *); /* probe device */
- void (* release)(void *); /* device gone */
- int (* command)(void *, Scsi_Cmnd *); /* all commands */
-};
+/*
+ * GUID definitions
+ */
#define GUID(x) __u32 x[3]
#define GUID_EQUAL(x, y) (x[0] == y[0] && x[1] == y[1] && x[2] == y[2])
@@ -122,25 +116,15 @@ static inline void make_guid( __u32 *pg, __u16 vendor, __u16 product, char *seri
pg[1] |= pg[2] >> 28;
pg[2] <<= 4;
if (*serial >= 'a')
- *serial -= 'a' - 'A';
+ *serial -= 'a' - 'A';
pg[2] |= (*serial <= '9' && *serial >= '0') ? *serial - '0'
- : *serial - 'A' + 10;
+ : *serial - 'A' + 10;
serial++;
}
}
/* Flag definitions */
-#define US_FL_IP_STATUS 0x00000001 /* status uses interrupt */
-#define US_FL_FIXED_COMMAND 0x00000002 /* expand commands to fixed size */
-
-/*
- * Called by filters to register/unregister the mini driver
- *
- * WARNING - the supplied probe function may be called before exiting this fn
- */
-int usb_scsi_register(struct usb_scsi_filter *);
-void usb_scsi_deregister(struct usb_scsi_filter *);
-
-#ifdef CONFIG_USB_HP4100
-int hp4100_init(void);
-#endif
+#define US_FL_IP_STATUS 0x00000001 /* status uses interrupt */
+#define US_FL_FIXED_COMMAND 0x00000002 /* expand commands to fixed size */
+#define US_FL_MODE_XLATE 0x00000004 /* translate _6 to _10 comands for
+ Win/MacOS compatibility */
diff --git a/drivers/usb/usb_storage_debug.c b/drivers/usb/usb_storage_debug.c
new file mode 100644
index 000000000..cff8f9a61
--- /dev/null
+++ b/drivers/usb/usb_storage_debug.c
@@ -0,0 +1,104 @@
+
+/* Driver for USB mass storage (scsi-like) devices
+ *
+ * (C) Michael Gee (michael@linuxspecific.com) 1999
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/miscdevice.h>
+#include <linux/random.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/malloc.h>
+#include <linux/spinlock.h>
+
+#include <linux/blk.h>
+#include "../scsi/scsi.h"
+#include "../scsi/hosts.h"
+#include "../scsi/sd.h"
+
+#include "usb.h"
+#include "usb_storage.h"
+
+void us_show_command(Scsi_Cmnd *srb)
+{
+ char *what = NULL;
+
+ switch (srb->cmnd[0]) {
+ case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break;
+ case REZERO_UNIT: what = "REZERO_UNIT"; break;
+ case REQUEST_SENSE: what = "REQUEST_SENSE"; break;
+ case FORMAT_UNIT: what = "FORMAT_UNIT"; break;
+ case READ_BLOCK_LIMITS: what = "READ_BLOCK_LIMITS"; break;
+ case REASSIGN_BLOCKS: what = "REASSIGN_BLOCKS"; break;
+ case READ_6: what = "READ_6"; break;
+ case WRITE_6: what = "WRITE_6"; break;
+ case SEEK_6: what = "SEEK_6"; break;
+ case READ_REVERSE: what = "READ_REVERSE"; break;
+ case WRITE_FILEMARKS: what = "WRITE_FILEMARKS"; break;
+ case SPACE: what = "SPACE"; break;
+ case INQUIRY: what = "INQUIRY"; break;
+ case RECOVER_BUFFERED_DATA: what = "RECOVER_BUFFERED_DATA"; break;
+ case MODE_SELECT: what = "MODE_SELECT"; break;
+ case RESERVE: what = "RESERVE"; break;
+ case RELEASE: what = "RELEASE"; break;
+ case COPY: what = "COPY"; break;
+ case ERASE: what = "ERASE"; break;
+ case MODE_SENSE: what = "MODE_SENSE"; break;
+ case START_STOP: what = "START_STOP"; break;
+ case RECEIVE_DIAGNOSTIC: what = "RECEIVE_DIAGNOSTIC"; break;
+ case SEND_DIAGNOSTIC: what = "SEND_DIAGNOSTIC"; break;
+ case ALLOW_MEDIUM_REMOVAL: what = "ALLOW_MEDIUM_REMOVAL"; break;
+ case SET_WINDOW: what = "SET_WINDOW"; break;
+ case READ_CAPACITY: what = "READ_CAPACITY"; break;
+ case READ_10: what = "READ_10"; break;
+ case WRITE_10: what = "WRITE_10"; break;
+ case SEEK_10: what = "SEEK_10"; break;
+ case WRITE_VERIFY: what = "WRITE_VERIFY"; break;
+ case VERIFY: what = "VERIFY"; break;
+ case SEARCH_HIGH: what = "SEARCH_HIGH"; break;
+ case SEARCH_EQUAL: what = "SEARCH_EQUAL"; break;
+ case SEARCH_LOW: what = "SEARCH_LOW"; break;
+ case SET_LIMITS: what = "SET_LIMITS"; break;
+ case READ_POSITION: what = "READ_POSITION"; break;
+ case SYNCHRONIZE_CACHE: what = "SYNCHRONIZE_CACHE"; break;
+ case LOCK_UNLOCK_CACHE: what = "LOCK_UNLOCK_CACHE"; break;
+ case READ_DEFECT_DATA: what = "READ_DEFECT_DATA"; break;
+ case MEDIUM_SCAN: what = "MEDIUM_SCAN"; break;
+ case COMPARE: what = "COMPARE"; break;
+ case COPY_VERIFY: what = "COPY_VERIFY"; break;
+ case WRITE_BUFFER: what = "WRITE_BUFFER"; break;
+ case READ_BUFFER: what = "READ_BUFFER"; break;
+ case UPDATE_BLOCK: what = "UPDATE_BLOCK"; break;
+ case READ_LONG: what = "READ_LONG"; break;
+ case WRITE_LONG: what = "WRITE_LONG"; break;
+ case CHANGE_DEFINITION: what = "CHANGE_DEFINITION"; break;
+ case WRITE_SAME: what = "WRITE_SAME"; break;
+ case READ_TOC: what = "READ_TOC"; break;
+ case LOG_SELECT: what = "LOG_SELECT"; break;
+ case LOG_SENSE: what = "LOG_SENSE"; break;
+ case MODE_SELECT_10: what = "MODE_SELECT_10"; break;
+ case MODE_SENSE_10: what = "MODE_SENSE_10"; break;
+ case MOVE_MEDIUM: what = "MOVE_MEDIUM"; break;
+ case READ_12: what = "READ_12"; break;
+ case WRITE_12: what = "WRITE_12"; break;
+ case WRITE_VERIFY_12: what = "WRITE_VERIFY_12"; break;
+ case SEARCH_HIGH_12: what = "SEARCH_HIGH_12"; break;
+ case SEARCH_EQUAL_12: what = "SEARCH_EQUAL_12"; break;
+ case SEARCH_LOW_12: what = "SEARCH_LOW_12"; break;
+ case READ_ELEMENT_STATUS: what = "READ_ELEMENT_STATUS"; break;
+ case SEND_VOLUME_TAG: what = "SEND_VOLUME_TAG"; break;
+ case WRITE_LONG_2: what = "WRITE_LONG_2"; break;
+ default: break;
+ }
+ printk(KERN_DEBUG USB_STORAGE
+ "Command %s (%d bytes)\n", what, srb->cmd_len);
+ printk(KERN_DEBUG USB_STORAGE
+ " %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ srb->cmnd[0], srb->cmnd[1], srb->cmnd[2], srb->cmnd[3], srb->cmnd[4], srb->cmnd[5],
+ srb->cmnd[6], srb->cmnd[7], srb->cmnd[8], srb->cmnd[9]);
+}
diff --git a/drivers/usb/usbdevice_fs.h b/drivers/usb/usbdevice_fs.h
index a4bd5d154..be3424a88 100644
--- a/drivers/usb/usbdevice_fs.h
+++ b/drivers/usb/usbdevice_fs.h
@@ -111,7 +111,6 @@ struct usbdevfs_urb {
#ifdef __KERNEL__
-#include <linux/config.h>
#include <linux/list.h>
#include <asm/semaphore.h>
diff --git a/drivers/usb/usbkbd.c b/drivers/usb/usbkbd.c
index 26de45a38..c6803f943 100644
--- a/drivers/usb/usbkbd.c
+++ b/drivers/usb/usbkbd.c
@@ -142,7 +142,8 @@ static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
if (!(endpoint->bEndpointAddress & 0x80)) return NULL;
if ((endpoint->bmAttributes & 3) != 3) return NULL;
- usb_set_protocol(dev, 0);
+ usb_set_protocol(dev, interface->bInterfaceNumber, 0);
+ usb_set_idle(dev, interface->bInterfaceNumber, 0, 0);
if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL;
memset(kbd, 0, sizeof(struct usb_kbd));
diff --git a/drivers/usb/usbmouse.c b/drivers/usb/usbmouse.c
index e4145d095..7276ca670 100644
--- a/drivers/usb/usbmouse.c
+++ b/drivers/usb/usbmouse.c
@@ -83,8 +83,9 @@ static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum)
if ((endpoint->bmAttributes & 3) != 3) return NULL;
#ifndef USBMOUSE_EXTRA
- usb_set_protocol(dev, 0);
+ usb_set_protocol(dev, interface->bInterfaceNumber, 0);
#endif
+ usb_set_idle(dev, interface->bInterfaceNumber, 0, 0);
if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) return NULL;
memset(mouse, 0, sizeof(struct usb_mouse));
diff --git a/drivers/usb/uss720.c b/drivers/usb/uss720.c
index 1328af1e8..d4db8546e 100644
--- a/drivers/usb/uss720.c
+++ b/drivers/usb/uss720.c
@@ -177,7 +177,7 @@ static int clear_epp_timeout(struct parport *pp)
/*
* Access functions.
*/
-
+#if 0
static int uss720_irq(int usbstatus, void *buffer, int len, void *dev_id)
{
struct parport *pp = (struct parport *)dev_id;
@@ -191,6 +191,7 @@ static int uss720_irq(int usbstatus, void *buffer, int len, void *dev_id)
parport_generic_irq(0, pp, NULL);
return 1;
}
+#endif
static void parport_uss720_write_data(struct parport *pp, unsigned char d)
{
@@ -356,7 +357,7 @@ static size_t parport_uss720_epp_write_data(struct parport *pp, const void *buf,
#else
struct parport_uss720_private *priv = pp->private_data;
struct usb_device *usbdev = priv->usbdev;
- unsigned long rlen;
+ int rlen;
int i;
if (!usbdev)
@@ -365,7 +366,7 @@ static size_t parport_uss720_epp_write_data(struct parport *pp, const void *buf,
return 0;
i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buf, length, &rlen, HZ*20);
if (i)
- printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %lu\n", buf, length, rlen);
+ printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %u\n", buf, length, rlen);
change_mode(pp, ECR_PS2);
return rlen;
#endif
@@ -417,7 +418,7 @@ static size_t parport_uss720_ecp_write_data(struct parport *pp, const void *buff
{
struct parport_uss720_private *priv = pp->private_data;
struct usb_device *usbdev = priv->usbdev;
- unsigned long rlen;
+ int rlen;
int i;
if (!usbdev)
@@ -426,7 +427,7 @@ static size_t parport_uss720_ecp_write_data(struct parport *pp, const void *buff
return 0;
i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buffer, len, &rlen, HZ*20);
if (i)
- printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %lu\n", buffer, len, rlen);
+ printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %u\n", buffer, len, rlen);
change_mode(pp, ECR_PS2);
return rlen;
}
@@ -435,7 +436,7 @@ static size_t parport_uss720_ecp_read_data(struct parport *pp, void *buffer, siz
{
struct parport_uss720_private *priv = pp->private_data;
struct usb_device *usbdev = priv->usbdev;
- unsigned long rlen;
+ int rlen;
int i;
if (!usbdev)
@@ -444,7 +445,7 @@ static size_t parport_uss720_ecp_read_data(struct parport *pp, void *buffer, siz
return 0;
i = usb_bulk_msg(usbdev, usb_rcvbulkpipe(usbdev, 2), buffer, len, &rlen, HZ*20);
if (i)
- printk(KERN_ERR "uss720: recvbulk ep 2 buf %p len %u rlen %lu\n", buffer, len, rlen);
+ printk(KERN_ERR "uss720: recvbulk ep 2 buf %p len %u rlen %u\n", buffer, len, rlen);
change_mode(pp, ECR_PS2);
return rlen;
}
@@ -468,7 +469,7 @@ static size_t parport_uss720_write_compat(struct parport *pp, const void *buffer
{
struct parport_uss720_private *priv = pp->private_data;
struct usb_device *usbdev = priv->usbdev;
- unsigned long rlen;
+ int rlen;
int i;
if (!usbdev)
@@ -477,7 +478,7 @@ static size_t parport_uss720_write_compat(struct parport *pp, const void *buffer
return 0;
i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buffer, len, &rlen, HZ*20);
if (i)
- printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %lu\n", buffer, len, rlen);
+ printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %u\n", buffer, len, rlen);
change_mode(pp, ECR_PS2);
return rlen;
}
@@ -606,8 +607,10 @@ static void * uss720_probe(struct usb_device *usbdev, unsigned int ifnum)
MOD_INC_USE_COUNT;
return pp;
+#if 0
probe_abort_port:
parport_unregister_port(pp);
+#endif
probe_abort:
kfree(priv);
return NULL;
diff --git a/drivers/usb/wmforce.c b/drivers/usb/wmforce.c
index b8fef7891..fa2d1b465 100644
--- a/drivers/usb/wmforce.c
+++ b/drivers/usb/wmforce.c
@@ -1,9 +1,9 @@
/*
* wmforce.c Version 0.1
*
- * Copyright (c) 1999 Vojtech Pavlik
+ * Copyright (c) 2000 Vojtech Pavlik
*
- * USB Logitech WingMan Force tablet support
+ * USB Logitech WingMan Force joystick support
*
* Sponsored by SuSE
*/
diff --git a/drivers/video/Config.in b/drivers/video/Config.in
index d8591ef17..2ccc8d4be 100644
--- a/drivers/video/Config.in
+++ b/drivers/video/Config.in
@@ -240,7 +240,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
- "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "m" -o \
+ "$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_SGIVW" = "m" -o \
"$CONFIG_FB_CYBER2000" = "m" ]; then
define_tristate CONFIG_FBCON_CFB16 m
fi
@@ -316,13 +316,6 @@ if [ "$CONFIG_FB" = "y" ]; then
define_tristate CONFIG_FBCON_VGA_PLANES m
fi
fi
- if [ "$CONFIG_FB_MDA" = "y" -o "$CONFIG_FB_VGA" = "y" ]; then
- define_tristate CONFIG_FBCON_VGA y
- else
- if [ "$CONFIG_FB_MDA" = "m" -o "$CONFIG_FB_VGA" = "m" ]; then
- define_tristate CONFIG_FBCON_VGA m
- fi
- fi
fi
bool ' Support only 8 pixels wide fonts' CONFIG_FBCON_FONTWIDTH8_ONLY
if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index fb578ffdb..af0a0d7c8 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -1939,7 +1939,7 @@ static u_long __init chipalloc(u_long size)
u_long ptr;
size += PAGE_SIZE-1;
- if (!(ptr = (u_long)amiga_chip_alloc(size)))
+ if (!(ptr = (u_long)amiga_chip_alloc(size, "amifb")))
panic("No Chip RAM for frame buffer");
memset((void *)ptr, 0, size);
ptr = PAGE_ALIGN(ptr);
diff --git a/drivers/video/bwtwofb.c b/drivers/video/bwtwofb.c
index cd79cd7d2..f8c0ea52d 100644
--- a/drivers/video/bwtwofb.c
+++ b/drivers/video/bwtwofb.c
@@ -1,4 +1,4 @@
-/* $Id: bwtwofb.c,v 1.11 1999/11/19 09:56:54 davem Exp $
+/* $Id: bwtwofb.c,v 1.12 2000/01/21 03:57:05 anton Exp $
* bwtwofb.c: BWtwo frame buffer driver
*
* Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -172,7 +172,7 @@ char __init *bwtwofb_init(struct fb_info_sbusfb *fb)
#ifdef CONFIG_SUN4
res.start = phys;
res.end = res.start + BWTWO_REGISTER_OFFSET + sizeof(struct bw2_regs) - 1;
- res.flags = IORESOURE_IO | (fb->iospace & 0xff);
+ res.flags = IORESOURCE_IO | (fb->iospace & 0xff);
resp = &res;
#else
resp = &fb->sbdp->resource[0];
diff --git a/drivers/video/clgenfb.c b/drivers/video/clgenfb.c
index 58a2fbb24..98a517f9f 100644
--- a/drivers/video/clgenfb.c
+++ b/drivers/video/clgenfb.c
@@ -316,7 +316,7 @@ static const struct {
#ifdef CONFIG_ZORRO
static const struct {
clgen_board_t btype;
- int key, key2;
+ zorro_id id, id2;
} clgen_zorro_probe_list[] __initdata = {
{ BT_SD64,
ZORRO_PROD_HELFRICH_SD64_RAM,
@@ -414,8 +414,6 @@ struct clgenfb_info {
} fbcon_cmap;
#ifdef CONFIG_ZORRO
- int keyRAM; /* RAM, REG zorro board keys */
- int keyREG;
unsigned long board_addr,
board_size;
#endif
@@ -2714,22 +2712,26 @@ static int __init clgen_pci_setup (struct clgenfb_info *info,
#ifdef CONFIG_ZORRO
-static int __init clgen_zorro_find (int *key_o, int *key2_o, clgen_board_t *btype)
+static int __init clgen_zorro_find (struct zorro_dev **z_o,
+ struct zorro_dev **z2_o,
+ clgen_board_t *btype)
{
- int i, key = 0;
-
- assert (key_o != NULL);
+ struct zorro_dev *z = NULL;
+ int i;
+
+ assert (z_o != NULL);
assert (btype != NULL);
- for (i = 0; i < arraysize(clgen_zorro_probe_list) && !key; i++)
- key = zorro_find (clgen_zorro_probe_list[i].key, 0, 0);
+ for (i = 0; i < arraysize(clgen_zorro_probe_list); i++)
+ if ((z = zorro_find_device(clgen_zorro_probe_list[i].id, NULL)))
+ break;
- if (key) {
- *key_o = key;
- if (clgen_zorro_probe_list[i].key2)
- *key2_o = zorro_find (clgen_zorro_probe_list[i].key2, 0, 0);
+ if (z) {
+ *z_o = z;
+ if (clgen_zorro_probe_list[i].id2)
+ *z2_o = zorro_find_device(clgen_zorro_probe_list[i].id2, NULL);
else
- *key2_o = 0;
+ *z2_o = NULL;
*btype = clgen_zorro_probe_list[i - 1].btype;
printk (KERN_INFO "clgen: %s board detected; ",
@@ -2766,26 +2768,21 @@ static void clgen_zorro_unmap (struct clgenfb_info *info)
static int __init clgen_zorro_setup (struct clgenfb_info *info,
clgen_board_t *btype)
{
- int key = 0, key2 = 0;
- const struct ConfigDev *cd = NULL;
- const struct ConfigDev *cd2 = NULL;
+ struct zorro_dev *z = NULL, *z2 = NULL;
unsigned long board_addr, board_size;
assert (info != NULL);
assert (btype != NULL);
- if (clgen_zorro_find (&key, &key2, btype))
+ if (clgen_zorro_find (&z, &z2, btype))
return -1;
- assert (key > 0);
- assert (key2 >= 0);
+ assert (z > 0);
+ assert (z2 >= 0);
assert (*btype != BT_NONE);
- info->keyRAM = key;
- info->keyREG = key2;
- cd = zorro_get_board (key);
- info->board_addr = board_addr = (unsigned long) cd->cd_BoardAddr;
- info->board_size = board_size = (unsigned long) cd->cd_BoardSize;
+ info->board_addr = board_addr = z->resource.start;
+ info->board_size = board_size = z->resource.end-z->resource.start+1;
if (!request_mem_region(board_addr, board_size, "clgenfb")) {
printk(KERN_ERR "clgen: cannot reserve region 0x%lu, abort\n",
@@ -2810,8 +2807,7 @@ static int __init clgen_zorro_setup (struct clgenfb_info *info,
info->fbmem_phys = board_addr + 16777216;
info->fbmem = ioremap (info->fbmem_phys, 16777216);
} else {
- cd2 = zorro_get_board (key2);
- printk (" REG at $%lx\n", (unsigned long) cd2->cd_BoardAddr);
+ printk (" REG at $%lx\n", (unsigned long) z2->resource.start);
info->fbmem_phys = board_addr;
if (board_addr > 0x01000000)
@@ -2820,17 +2816,12 @@ static int __init clgen_zorro_setup (struct clgenfb_info *info,
info->fbmem = (caddr_t) ZTWO_VADDR (board_addr);
/* set address for REG area of board */
- info->regs = (caddr_t) ZTWO_VADDR (cd2->cd_BoardAddr);
- info->fbregs_phys = (unsigned long) cd2->cd_BoardAddr;
+ info->regs = (caddr_t) ZTWO_VADDR (z2->resource.start);
+ info->fbregs_phys = z2->resource.start;
DPRINTK ("clgen: Virtual address for board set to: $%p\n", info->regs);
}
- /* mark this board as "autoconfigured" */
- zorro_config_board (key, 0);
- if (*btype != BT_PICASSO4)
- zorro_config_board (key2, 0);
-
printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
return 0;
@@ -2968,10 +2959,6 @@ static void clgenfb_cleanup (struct clgenfb_info *info)
switch_monitor (info, 0);
clgen_zorro_unmap (info);
-
- zorro_unconfig_board (info->keyRAM, 0);
- if (info->btype != BT_PICASSO4)
- zorro_unconfig_board (info->keyREG, 0);
#else
clgen_pci_unmap (info);
#endif /* CONFIG_ZORRO */
diff --git a/drivers/video/cvisionppc.h b/drivers/video/cvisionppc.h
index 0afc0d04e..11250eee9 100644
--- a/drivers/video/cvisionppc.h
+++ b/drivers/video/cvisionppc.h
@@ -7,7 +7,7 @@
* $Id: cvisionppc.h,v 1.8 1999/01/28 13:18:07 illo Exp $
* --------------------------------------------------------------------------
* This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
+ * License. See the file COPYING in the main directory of this archive
* for more details.
*/
diff --git a/drivers/video/cyberfb.c b/drivers/video/cyberfb.c
index 7e4aea83f..deadf90b0 100644
--- a/drivers/video/cyberfb.c
+++ b/drivers/video/cyberfb.c
@@ -1104,76 +1104,75 @@ int __init cyberfb_setup(char *options)
int __init cyberfb_init(void)
{
+ unsigned long board_addr, board_size;
struct cyberfb_par par;
- unsigned long board_addr;
- unsigned long board_size;
- const struct ConfigDev *cd;
- unsigned int CyberKey = 0;
+ struct zorro_dev *z = NULL;
DPRINTK("ENTER\n");
- if (!(CyberKey = zorro_find(ZORRO_PROD_PHASE5_CYBERVISION64, 0, 0))) {
- DPRINTK("EXIT - zorro_find failed\n");
- return -ENXIO;
- }
-
- cd = zorro_get_board (CyberKey);
- zorro_config_board (CyberKey, 0);
- board_addr = (unsigned long)cd->cd_BoardAddr;
- board_size = (unsigned long)cd->cd_BoardSize;
- DPRINTK("board_addr=%08lx\n", board_addr);
- DPRINTK("board_size=%08lx\n", board_size);
-
- CyberBase = ioremap(board_addr, board_size);
- CyberRegs = CyberBase + 0x02000000;
- CyberMem = CyberBase + 0x01400000;
- DPRINTK("CyberBase=%08lx CyberRegs=%08lx CyberMem=%08lx\n",
- CyberBase, (long unsigned int)CyberRegs, CyberMem);
-
- CyberMem_phys = board_addr + 0x01400000;
- CyberRegs_phys = CyberMem_phys + 0x00c00000;
- DPRINTK("CyberMem=%08lx CyberRegs=%08lx\n", CyberMem,
- (long unsigned int)CyberRegs);
+ while ((z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERVISION64, z))) {
+ board_addr = z->resource.start;
+ board_size = z->resource.end-z->resource.start+1;
+ CyberMem_phys = board_addr + 0x01400000;
+ CyberRegs_phys = CyberMem_phys + 0x00c00000;
+ if (!request_mem_region(CyberRegs_phys, 0x10000, "S3 Trio64"))
+ continue;
+ if (!request_mem_region(CyberMem_phys, 0x4000000, "RAM")) {
+ release_mem_region(CyberRegs_phys, 0x10000);
+ continue;
+ }
+ strcpy(z->name, "CyberVision64 Graphics Board");
+ DPRINTK("board_addr=%08lx\n", board_addr);
+ DPRINTK("board_size=%08lx\n", board_size);
+
+ CyberBase = ioremap(board_addr, board_size);
+ CyberRegs = CyberBase + 0x02000000;
+ CyberMem = CyberBase + 0x01400000;
+ DPRINTK("CyberBase=%08lx CyberRegs=%08lx CyberMem=%08lx\n",
+ CyberBase, (long unsigned int)CyberRegs, CyberMem);
#ifdef CYBERFBDEBUG
- DPRINTK("Register state just after mapping memory\n");
- cv64_dump();
+ DPRINTK("Register state just after mapping memory\n");
+ cv64_dump();
#endif
- strcpy(fb_info.modename, cyberfb_name);
- fb_info.changevar = NULL;
- fb_info.node = -1;
- fb_info.fbops = &cyberfb_ops;
- fb_info.disp = &disp;
- fb_info.switch_con = &Cyberfb_switch;
- fb_info.updatevar = &Cyberfb_updatevar;
- fb_info.blank = &Cyberfb_blank;
-
- Cyber_init();
- /* ++Andre: set cyberfb default mode */
- if (!cyberfb_usermode) {
- cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var;
- DPRINTK("Use default cyber8 mode\n");
+ strcpy(fb_info.modename, cyberfb_name);
+ fb_info.changevar = NULL;
+ fb_info.node = -1;
+ fb_info.fbops = &cyberfb_ops;
+ fb_info.disp = &disp;
+ fb_info.switch_con = &Cyberfb_switch;
+ fb_info.updatevar = &Cyberfb_updatevar;
+ fb_info.blank = &Cyberfb_blank;
+
+ Cyber_init();
+ /* ++Andre: set cyberfb default mode */
+ if (!cyberfb_usermode) {
+ cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var;
+ DPRINTK("Use default cyber8 mode\n");
+ }
+ Cyber_decode_var(&cyberfb_default, &par);
+ Cyber_encode_var(&cyberfb_default, &par);
+
+ do_fb_set_var(&cyberfb_default, 1);
+ cyberfb_get_var(&fb_display[0].var, -1, &fb_info);
+ cyberfb_set_disp(-1, &fb_info);
+ do_install_cmap(0, &fb_info);
+
+ if (register_framebuffer(&fb_info) < 0) {
+ DPRINTK("EXIT - register_framebuffer failed\n");
+ release_mem_region(board_addr, board_size);
+ return -EINVAL;
+ }
+
+ printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
+ GET_FB_IDX(fb_info.node), fb_info.modename, CyberSize>>10);
+
+ /* TODO: This driver cannot be unloaded yet */
+ MOD_INC_USE_COUNT;
+ DPRINTK("EXIT\n");
+ return 0;
}
- Cyber_decode_var(&cyberfb_default, &par);
- Cyber_encode_var(&cyberfb_default, &par);
-
- do_fb_set_var(&cyberfb_default, 1);
- cyberfb_get_var(&fb_display[0].var, -1, &fb_info);
- cyberfb_set_disp(-1, &fb_info);
- do_install_cmap(0, &fb_info);
-
- if (register_framebuffer(&fb_info) < 0) {
- DPRINTK("EXIT - register_framebuffer failed\n");
- return -EINVAL;
- }
-
- printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
- GET_FB_IDX(fb_info.node), fb_info.modename, CyberSize>>10);
-
- /* TODO: This driver cannot be unloaded yet */
- MOD_INC_USE_COUNT;
- DPRINTK("EXIT\n");
- return 0;
+ return -ENXIO;
}
diff --git a/drivers/video/fbcon.c b/drivers/video/fbcon.c
index a78843085..02f50a497 100644
--- a/drivers/video/fbcon.c
+++ b/drivers/video/fbcon.c
@@ -237,7 +237,7 @@ static void cursor_timer_handler(unsigned long dev_addr)
fbcon_vbl_handler(0, NULL, NULL);
cursor_timer.expires = jiffies+HZ/50;
cursor_timer.data = 0;
- cursor_timer.next = cursor_timer.next = NULL;
+ cursor_timer.next = cursor_timer.prev = NULL;
add_timer(&cursor_timer);
}
diff --git a/drivers/video/fbgen.c b/drivers/video/fbgen.c
index 7cf44a5ec..4be9b41d8 100644
--- a/drivers/video/fbgen.c
+++ b/drivers/video/fbgen.c
@@ -4,7 +4,7 @@
* Created 3 Jan 1998 by Geert Uytterhoeven
*
* This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
+ * License. See the file COPYING in the main directory of this archive
* for more details.
*/
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index f6ca52705..6e409ddb4 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -432,8 +432,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
/* frame buffer memory */
start = fix.smem_start;
- len = (start & ~PAGE_MASK)+fix.smem_len;
- len = (len+~PAGE_MASK) & PAGE_MASK; /* someone's on crack. */
+ len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.smem_len);
if (off >= len) {
/* memory mapped io */
off -= len;
@@ -441,8 +440,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
if (var.accel_flags)
return -EINVAL;
start = fix.mmio_start;
- len = (start & ~PAGE_MASK)+fix.mmio_len;
- len = (len+~PAGE_MASK) & PAGE_MASK;
+ len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.mmio_len);
}
start &= PAGE_MASK;
if ((vma->vm_end - vma->vm_start + off) > len)
diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c
index 97f4e9ba8..9a7690d34 100644
--- a/drivers/video/fm2fb.c
+++ b/drivers/video/fm2fb.c
@@ -376,95 +376,99 @@ static int fm2fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
int __init fm2fb_init(void)
{
- int key, is_fm;
- const struct ConfigDev *cd = NULL;
- unsigned long board, *ptr;
+ int is_fm;
+ struct zorro_dev *z = NULL;
+ unsigned long *ptr;
int x, y;
- if (!(key = is_fm = zorro_find(ZORRO_PROD_BSC_FRAMEMASTER_II, 0, 0)) &&
- !(key = zorro_find(ZORRO_PROD_HELFRICH_RAINBOW_II, 0, 0)))
- return -ENXIO;
- cd = zorro_get_board(key);
- if (!(board = (u_long)cd->cd_BoardAddr))
- return -ENXIO;
- zorro_config_board(key, 0);
-
- /* assigning memory to kernel space */
- fm2fb_mem_phys = board;
- fm2fb_mem = ioremap(board, FRAMEMASTER_SIZE);
- fm2fb_reg_phys = fm2fb_mem_phys+FRAMEMASTER_REG;
- fm2fb_reg = (unsigned char *)(fm2fb_mem+FRAMEMASTER_REG);
-
- /* make EBU color bars on display */
- ptr = (unsigned long *)fm2fb_mem;
- for (y = 0; y < 576; y++) {
- for (x = 0; x < 96; x++) *ptr++ = 0xffffff; /* white */
- for (x = 0; x < 96; x++) *ptr++ = 0xffff00; /* yellow */
- for (x = 0; x < 96; x++) *ptr++ = 0x00ffff; /* cyan */
- for (x = 0; x < 96; x++) *ptr++ = 0x00ff00; /* green */
- for (x = 0; x < 96; x++) *ptr++ = 0xff00ff; /* magenta */
- for (x = 0; x < 96; x++) *ptr++ = 0xff0000; /* red */
- for (x = 0; x < 96; x++) *ptr++ = 0x0000ff; /* blue */
- for (x = 0; x < 96; x++) *ptr++ = 0x000000; /* black */
- }
- fm2fbcon_blank(0, NULL);
-
- if (fm2fb_mode == -1)
- fm2fb_mode = FM2FB_MODE_PAL;
-
- fb_var = fb_var_modes[fm2fb_mode];
-
- strcpy(fb_fix.id, is_fm ? "FrameMaster II" : "Rainbow II");
- fb_fix.smem_start = fm2fb_mem_phys;
- fb_fix.smem_len = FRAMEMASTER_REG;
- fb_fix.type = FB_TYPE_PACKED_PIXELS;
- fb_fix.type_aux = 0;
- fb_fix.visual = FB_VISUAL_TRUECOLOR;
- fb_fix.line_length = 768<<2;
- fb_fix.mmio_start = fm2fb_reg_phys;
- fb_fix.mmio_len = 8;
- fb_fix.accel = FB_ACCEL_NONE;
-
- disp.var = fb_var;
- disp.cmap.start = 0;
- disp.cmap.len = 0;
- disp.cmap.red = disp.cmap.green = disp.cmap.blue = disp.cmap.transp = NULL;
- disp.screen_base = (char *)fm2fb_mem;
- disp.visual = fb_fix.visual;
- disp.type = fb_fix.type;
- disp.type_aux = fb_fix.type_aux;
- disp.ypanstep = 0;
- disp.ywrapstep = 0;
- disp.line_length = fb_fix.line_length;
- disp.can_soft_blank = 1;
- disp.inverse = 0;
-#ifdef FBCON_HAS_CFB32
- disp.dispsw = &fbcon_cfb32;
- disp.dispsw_data = &fbcon_cfb32_cmap;
-#else
- disp.dispsw = &fbcon_dummy;
-#endif
- disp.scrollmode = SCROLL_YREDRAW;
-
- strcpy(fb_info.modename, fb_fix.id);
- fb_info.node = -1;
- fb_info.fbops = &fm2fb_ops;
- fb_info.disp = &disp;
- fb_info.fontname[0] = '\0';
- fb_info.changevar = NULL;
- fb_info.switch_con = &fm2fbcon_switch;
- fb_info.updatevar = &fm2fbcon_updatevar;
- fb_info.blank = &fm2fbcon_blank;
- fb_info.flags = FBINFO_FLAG_DEFAULT;
-
- fm2fb_set_var(&fb_var, -1, &fb_info);
-
- if (register_framebuffer(&fb_info) < 0)
- return -EINVAL;
+ while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
+ if (z->id == ZORRO_PROD_BSC_FRAMEMASTER_II)
+ is_fm = 1;
+ else if (z->id == ZORRO_PROD_HELFRICH_RAINBOW_II)
+ is_fm = 0;
+ else
+ continue;
+ if (!request_mem_region(z->resource.start, FRAMEMASTER_SIZE, "fm2fb"))
+ continue;
+
+ /* assigning memory to kernel space */
+ fm2fb_mem_phys = z->resource.start;
+ fm2fb_mem = ioremap(fm2fb_mem_phys, FRAMEMASTER_SIZE);
+ fm2fb_reg_phys = fm2fb_mem_phys+FRAMEMASTER_REG;
+ fm2fb_reg = (unsigned char *)(fm2fb_mem+FRAMEMASTER_REG);
+
+ /* make EBU color bars on display */
+ ptr = (unsigned long *)fm2fb_mem;
+ for (y = 0; y < 576; y++) {
+ for (x = 0; x < 96; x++) *ptr++ = 0xffffff; /* white */
+ for (x = 0; x < 96; x++) *ptr++ = 0xffff00; /* yellow */
+ for (x = 0; x < 96; x++) *ptr++ = 0x00ffff; /* cyan */
+ for (x = 0; x < 96; x++) *ptr++ = 0x00ff00; /* green */
+ for (x = 0; x < 96; x++) *ptr++ = 0xff00ff; /* magenta */
+ for (x = 0; x < 96; x++) *ptr++ = 0xff0000; /* red */
+ for (x = 0; x < 96; x++) *ptr++ = 0x0000ff; /* blue */
+ for (x = 0; x < 96; x++) *ptr++ = 0x000000; /* black */
+ }
+ fm2fbcon_blank(0, NULL);
+
+ if (fm2fb_mode == -1)
+ fm2fb_mode = FM2FB_MODE_PAL;
- printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node),
- fb_fix.id);
- return 0;
+ fb_var = fb_var_modes[fm2fb_mode];
+
+ strcpy(fb_fix.id, is_fm ? "FrameMaster II" : "Rainbow II");
+ fb_fix.smem_start = fm2fb_mem_phys;
+ fb_fix.smem_len = FRAMEMASTER_REG;
+ fb_fix.type = FB_TYPE_PACKED_PIXELS;
+ fb_fix.type_aux = 0;
+ fb_fix.visual = FB_VISUAL_TRUECOLOR;
+ fb_fix.line_length = 768<<2;
+ fb_fix.mmio_start = fm2fb_reg_phys;
+ fb_fix.mmio_len = 8;
+ fb_fix.accel = FB_ACCEL_NONE;
+
+ disp.var = fb_var;
+ disp.cmap.start = 0;
+ disp.cmap.len = 0;
+ disp.cmap.red = disp.cmap.green = disp.cmap.blue = disp.cmap.transp = NULL;
+ disp.screen_base = (char *)fm2fb_mem;
+ disp.visual = fb_fix.visual;
+ disp.type = fb_fix.type;
+ disp.type_aux = fb_fix.type_aux;
+ disp.ypanstep = 0;
+ disp.ywrapstep = 0;
+ disp.line_length = fb_fix.line_length;
+ disp.can_soft_blank = 1;
+ disp.inverse = 0;
+ #ifdef FBCON_HAS_CFB32
+ disp.dispsw = &fbcon_cfb32;
+ disp.dispsw_data = &fbcon_cfb32_cmap;
+ #else
+ disp.dispsw = &fbcon_dummy;
+ #endif
+ disp.scrollmode = SCROLL_YREDRAW;
+
+ strcpy(fb_info.modename, fb_fix.id);
+ fb_info.node = -1;
+ fb_info.fbops = &fm2fb_ops;
+ fb_info.disp = &disp;
+ fb_info.fontname[0] = '\0';
+ fb_info.changevar = NULL;
+ fb_info.switch_con = &fm2fbcon_switch;
+ fb_info.updatevar = &fm2fbcon_updatevar;
+ fb_info.blank = &fm2fbcon_blank;
+ fb_info.flags = FBINFO_FLAG_DEFAULT;
+
+ fm2fb_set_var(&fb_var, -1, &fb_info);
+
+ if (register_framebuffer(&fb_info) < 0)
+ return -EINVAL;
+
+ printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node),
+ fb_fix.id);
+ return 0;
+ }
+ return -ENXIO;
}
int __init fm2fb_setup(char *options)
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index 490ad605d..e871b6a0c 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -623,7 +623,6 @@ static int __init iga_init(struct fb_info_iga *info)
return 1;
}
-
int __init igafb_init(void)
{
struct pci_dev *pdev;
@@ -643,10 +642,10 @@ int __init igafb_init(void)
* XXX We tried to use cyber2000fb.c for IGS 2000.
* But it does not initialize the chip in JavaStation-E, alas.
*/
- pdev = pci_find_device(PCI_VENDOR_ID_INTERG,
- 0x2000, 0);
- if(pdev == NULL)
+ pdev = pci_find_device(PCI_VENDOR_ID_INTERG, 0x2000, 0);
+ if(pdev == NULL) {
return -ENXIO;
+ }
iga2000 = 1;
}
@@ -657,15 +656,18 @@ int __init igafb_init(void)
}
memset(info, 0, sizeof(struct fb_info_iga));
- info->frame_buffer = ioremap(pdev->resource[0].start, 1024*1024*2);
- if (!info->frame_buffer) {
+ if ((addr = pdev->resource[0].start) == 0) {
+ printk("igafb_init: no memory start\n", addr);
kfree(info);
return -ENXIO;
}
- addr = pdev->resource[0].start;
- if (!addr)
+ if ((info->frame_buffer = ioremap(addr, 1024*1024*2)) == 0) {
+ printk("igafb_init: can't remap %lx[2M]\n", addr);
+ kfree(info);
return -ENXIO;
+ }
+
info->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;
#ifdef __sparc__
@@ -693,8 +695,9 @@ int __init igafb_init(void)
} else {
info->io_base_phys = 0x30000000; /* XXX */
}
- info->io_base = (int) ioremap(info->io_base_phys, 0x1000);
- if (!info->io_base) {
+ if ((info->io_base = (int) ioremap(info->io_base_phys, 0x1000)) == 0) {
+ printk("igafb_init: can't remap %lx[4K]\n", info->io_base_phys);
+ iounmap(info->frame_buffer);
kfree(info);
return -ENXIO;
}
@@ -709,8 +712,9 @@ int __init igafb_init(void)
info->mmap_map = kmalloc(4 * sizeof(*info->mmap_map), GFP_ATOMIC);
if (!info->mmap_map) {
- printk("igafb_init: can't alloc mmap_map\n");
- /* XXX Here we left I/O allocated */
+ printk("igafb_init: can't alloc mmap_map\n");
+ iounmap(info->io_base);
+ iounmap(info->frame_buffer);
kfree(info);
return -ENOMEM;
}
@@ -763,7 +767,9 @@ int __init igafb_init(void)
#endif
- if (!iga_init(info)) {
+ if (!iga_init(info)) {
+ iounmap(info->io_base);
+ iounmap(info->frame_buffer);
if (info->mmap_map)
kfree(info->mmap_map);
kfree(info);
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 61ca90517..edeeae447 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -470,8 +470,7 @@ static int __init offb_init_driver(struct device_node *dp)
}
#endif /* CONFIG_FB_PLATINUM */
#ifdef CONFIG_FB_CLGEN
- if ((!strncmp(dp->name, "MacPicasso",10) ||
- (!strncmp(dp->name, "54m30",5)) {
+ if (!strncmp(dp->name, "MacPicasso",10) || !strncmp(dp->name, "54m30",5)) {
clgen_of_init(dp);
return 1;
}
diff --git a/drivers/video/platinumfb.h b/drivers/video/platinumfb.h
index d3aa5c3ef..2834fc1c3 100644
--- a/drivers/video/platinumfb.h
+++ b/drivers/video/platinumfb.h
@@ -15,7 +15,7 @@
* Created 28 Dec 1997 by Geert Uytterhoeven
*
* This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
+ * License. See the file COPYING in the main directory of this archive
* for more details.
*/
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index e3446858d..1619edaf9 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -9,7 +9,7 @@
* TODO multiple boards support
* --------------------------------------------------------------------------
* This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
+ * License. See the file COPYING in the main directory of this archive
* for more details.
*/
diff --git a/drivers/video/pm2fb.h b/drivers/video/pm2fb.h
index b3ebc5ce7..995e1990a 100644
--- a/drivers/video/pm2fb.h
+++ b/drivers/video/pm2fb.h
@@ -5,7 +5,7 @@
* $Id: pm2fb.h,v 1.21 1999/01/28 13:18:07 illo Exp $
* --------------------------------------------------------------------------
* This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
+ * License. See the file COPYING in the main directory of this archive
* for more details.
*/
diff --git a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c
index dbc6eb022..caa37b185 100644
--- a/drivers/video/retz3fb.c
+++ b/drivers/video/retz3fb.c
@@ -1423,85 +1423,93 @@ int __init retz3fb_setup(char *options)
int __init retz3fb_init(void)
{
unsigned long board_addr, board_size;
- unsigned int key;
- const struct ConfigDev *cd;
+ struct zorro_dev *z = NULL;
volatile unsigned char *regs;
struct retz3fb_par par;
struct retz3_fb_info *zinfo;
struct fb_info *fb_info;
short i;
+ int res = -ENXIO;
+
+ while ((z = zorro_find_device(ZORRO_PROD_MACROSYSTEMS_RETINA_Z3, z))) {
+ board_addr = z->resource.start;
+ board_size = z->resource.end-z->resource.start+1;
+ if (!request_mem_region(board_addr, 0x0c00000,
+ "ncr77c32blt")) {
+ continue;
+ if (!request_mem_region(board_addr+VIDEO_MEM_OFFSET,
+ 0x00400000, "RAM"))
+ release_mem_region(board_addr, 0x00c00000);
+ continue;
+ }
+ strcpy(z->name, "Retina Z3 Graphics ");
+ if (!(zinfo = kmalloc(sizeof(struct retz3_fb_info),
+ GFP_KERNEL)))
+ return -ENOMEM;
+ memset(zinfo, 0, sizeof(struct retz3_fb_info));
+
+ zinfo->base = ioremap(board_addr, board_size);
+ zinfo->regs = zinfo->base;
+ zinfo->fbmem = zinfo->base + VIDEO_MEM_OFFSET;
+ /* Get memory size - for now we asume its a 4MB board */
+ zinfo->fbsize = 0x00400000; /* 4 MB */
+ zinfo->physregs = board_addr;
+ zinfo->physfbmem = board_addr + VIDEO_MEM_OFFSET;
+
+ fb_info = fbinfo(zinfo);
- if (!(key = zorro_find(ZORRO_PROD_MACROSYSTEMS_RETINA_Z3, 0, 0)))
- return -ENXIO;
-
- if (!(zinfo = kmalloc(sizeof(struct retz3_fb_info), GFP_KERNEL)))
- return -ENOMEM;
- memset(zinfo, 0, sizeof(struct retz3_fb_info));
-
- cd = zorro_get_board (key);
- zorro_config_board (key, 0);
- board_addr = (unsigned long)cd->cd_BoardAddr;
- board_size = (unsigned long)cd->cd_BoardSize;
-
- zinfo->base = ioremap(board_addr, board_size);
- zinfo->regs = zinfo->base;
- zinfo->fbmem = zinfo->base + VIDEO_MEM_OFFSET;
- /* Get memory size - for now we asume its a 4MB board */
- zinfo->fbsize = 0x00400000; /* 4 MB */
- zinfo->physregs = board_addr;
- zinfo->physfbmem = board_addr + VIDEO_MEM_OFFSET;
-
- fb_info = fbinfo(zinfo);
-
- for (i = 0; i < 256; i++){
for (i = 0; i < 256; i++){
- zinfo->color_table[i][0] = i;
- zinfo->color_table[i][1] = i;
- zinfo->color_table[i][2] = i;
+ for (i = 0; i < 256; i++){
+ zinfo->color_table[i][0] = i;
+ zinfo->color_table[i][1] = i;
+ zinfo->color_table[i][2] = i;
+ }
}
- }
- regs = zinfo->regs;
- /* Disable hardware cursor */
- seq_w(regs, SEQ_CURSOR_Y_INDEX, 0x00);
+ regs = zinfo->regs;
+ /* Disable hardware cursor */
+ seq_w(regs, SEQ_CURSOR_Y_INDEX, 0x00);
- retz3_setcolreg (255, 56<<8, 100<<8, 160<<8, 0, fb_info);
- retz3_setcolreg (254, 0, 0, 0, 0, fb_info);
+ retz3_setcolreg (255, 56<<8, 100<<8, 160<<8, 0, fb_info);
+ retz3_setcolreg (254, 0, 0, 0, 0, fb_info);
- strcpy(fb_info->modename, retz3fb_name);
- fb_info->changevar = NULL;
- fb_info->node = -1;
- fb_info->fbops = &retz3fb_ops;
- fb_info->disp = &zinfo->disp;
- fb_info->switch_con = &z3fb_switch;
- fb_info->updatevar = &z3fb_updatevar;
- fb_info->blank = &z3fb_blank;
- fb_info->flags = FBINFO_FLAG_DEFAULT;
- strncpy(fb_info->fontname, fontname, 40);
+ strcpy(fb_info->modename, retz3fb_name);
+ fb_info->changevar = NULL;
+ fb_info->node = -1;
+ fb_info->fbops = &retz3fb_ops;
+ fb_info->disp = &zinfo->disp;
+ fb_info->switch_con = &z3fb_switch;
+ fb_info->updatevar = &z3fb_updatevar;
+ fb_info->blank = &z3fb_blank;
+ fb_info->flags = FBINFO_FLAG_DEFAULT;
+ strncpy(fb_info->fontname, fontname, 40);
- if (z3fb_mode == -1)
- retz3fb_default = retz3fb_predefined[0].var;
+ if (z3fb_mode == -1)
+ retz3fb_default = retz3fb_predefined[0].var;
- retz3_decode_var(&retz3fb_default, &par);
- retz3_encode_var(&retz3fb_default, &par);
+ retz3_decode_var(&retz3fb_default, &par);
+ retz3_encode_var(&retz3fb_default, &par);
- do_fb_set_var(fb_info, &retz3fb_default, 0);
- retz3fb_get_var(&zinfo->disp.var, -1, fb_info);
+ do_fb_set_var(fb_info, &retz3fb_default, 0);
+ retz3fb_get_var(&zinfo->disp.var, -1, fb_info);
- retz3fb_set_disp(-1, fb_info);
+ retz3fb_set_disp(-1, fb_info);
- do_install_cmap(0, fb_info);
+ do_install_cmap(0, fb_info);
- if (register_framebuffer(fb_info) < 0)
- return -EINVAL;
+ if (register_framebuffer(fb_info) < 0)
+ return -EINVAL;
- printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of video memory\n",
- GET_FB_IDX(fb_info->node), fb_info->modename,zinfo->fbsize>>10);
+ printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of "
+ "video memory\n", GET_FB_IDX(fb_info->node),
+ fb_info->modename, zinfo->fbsize>>10);
- /* TODO: This driver cannot be unloaded yet */
- MOD_INC_USE_COUNT;
+ /* TODO: This driver cannot be unloaded yet */
+ MOD_INC_USE_COUNT;
- return 0;
+ res = 0;
+ }
+ return res;
}
diff --git a/drivers/video/rivafb.c b/drivers/video/rivafb.c
index 0830468f9..c48f7a08a 100644
--- a/drivers/video/rivafb.c
+++ b/drivers/video/rivafb.c
@@ -13,7 +13,7 @@
* KGI code provided the basis for state storage, init, and mode switching.
*
* This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
+ * License. See the file COPYING in the main directory of this archive
* for more details.
*/
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 2eb7962f8..207ccaa39 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -4,7 +4,7 @@
* Created 28 Dec 1997 by Geert Uytterhoeven
*
* This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
+ * License. See the file COPYING in the main directory of this archive
* for more details.
*/
@@ -287,7 +287,8 @@ static void xxx_set_disp(const void *par, struct display *disp,
struct fbgen_hwswitch xxx_switch = {
xxx_detect, xxx_encode_fix, xxx_decode_var, xxx_encode_var, xxx_get_par,
- xxx_set_par, xxx_getcolreg, xxx_setcolreg, xxx_blank, xxx_dispsw
+ xxx_set_par, xxx_getcolreg, xxx_setcolreg, xxx_pan_display, xxx_blank,
+ xxx_set_disp
};
diff --git a/drivers/video/virgefb.c b/drivers/video/virgefb.c
index 050d34543..b4a123cd9 100644
--- a/drivers/video/virgefb.c
+++ b/drivers/video/virgefb.c
@@ -167,7 +167,6 @@ static char virgefb_name[16] = "Cybervision/3D";
#define VIRGE16_PIXCLOCK 25000 /* ++Geert: Just a guess */
-static unsigned int CyberKey = 0;
static unsigned char Cyber_colour_table [256][3];
static unsigned long CyberMem;
static unsigned long CyberSize;
@@ -1166,28 +1165,39 @@ int __init virgefb_setup(char *options)
int __init virgefb_init(void)
{
struct virgefb_par par;
- unsigned long board_addr;
- const struct ConfigDev *cd;
+ unsigned long board_addr, ramsize;
+ struct zorro_dev *z = NULL;
- if (!(CyberKey = zorro_find(ZORRO_PROD_PHASE5_CYBERVISION64_3D, 0, 0)))
- return -ENXIO;
-
- cd = zorro_get_board (CyberKey);
- zorro_config_board (CyberKey, 0);
- board_addr = (unsigned long)cd->cd_BoardAddr;
-
- /* This includes the video memory as well as the S3 register set */
- if ((unsigned long)cd->cd_BoardAddr < 0x01000000)
- {
+ while ((z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERVISION64_3D, z))) {
+ board_addr = z->resource.start;
+ if (board_addr < 0x01000000) {
+ /*
+ * Ok we got the board running in Z2 space.
+ */
+ CyberRegs_phys = (unsigned long)(board_addr + 0x003e0000);
+ CyberMem_phys = board_addr;
+ ramsize = 0x00380000;
+ } else {
+ CyberRegs_phys = board_addr + 0x05000000;
+ CyberMem_phys = board_addr + 0x04000000; /* was 0x04800000 */
+ ramsize = 0x00400000;
+ }
+ if (!request_mem_region(CyberRegs_phys, 0x10000, "S3 ViRGE"))
+ continue;
+ if (!request_mem_region(CyberMem_phys, ramsize, "RAM")) {
+ release_mem_region(CyberRegs_phys, 0x10000);
+ continue;
+ }
+ strcpy(z->name, "CyberVision64-3D Graphics Board");
+
+ if (board_addr < 0x01000000) {
/*
* Ok we got the board running in Z2 space.
*/
- CyberMem_phys = board_addr;
CyberMem = ZTWO_VADDR(CyberMem_phys);
CyberVGARegs = (unsigned long) \
ZTWO_VADDR(board_addr + 0x003c0000);
- CyberRegs_phys = (unsigned long)(board_addr + 0x003e0000);
CyberRegs = (unsigned char *)ZTWO_VADDR(CyberRegs_phys);
Cyber_register_base = (unsigned long) \
ZTWO_VADDR(board_addr + 0x003c8000);
@@ -1195,50 +1205,49 @@ int __init virgefb_init(void)
ZTWO_VADDR(board_addr + 0x003a0000);
cv3d_on_zorro2 = 1;
printk(KERN_INFO "CV3D detected running in Z2 mode.\n");
- }
- else
- {
- CyberVGARegs = (unsigned long)ioremap(board_addr +0x0c000000, 0x00010000);
- CyberRegs_phys = board_addr + 0x05000000;
- CyberMem_phys = board_addr + 0x04000000; /* was 0x04800000 */
+ } else {
+ CyberVGARegs = (unsigned long)ioremap(board_addr+0x0c000000, 0x00010000);
CyberRegs = ioremap(CyberRegs_phys, 0x00010000);
CyberMem = (unsigned long)ioremap(CyberMem_phys, 0x01000000); /* was 0x00400000 */
cv3d_on_zorro2 = 0;
printk(KERN_INFO "CV3D detected running in Z3 mode.\n");
- }
-
- fbhw = &Cyber_switch;
-
- strcpy(fb_info.modename, virgefb_name);
- fb_info.changevar = NULL;
- fb_info.node = -1;
- fb_info.fbops = &virgefb_ops;
- fb_info.disp = &disp;
- fb_info.switch_con = &Cyberfb_switch;
- fb_info.updatevar = &Cyberfb_updatevar;
- fb_info.blank = &Cyberfb_blank;
- fb_info.flags = FBINFO_FLAG_DEFAULT;
-
- fbhw->init();
- fbhw->decode_var(&virgefb_default, &par);
- fbhw->encode_var(&virgefb_default, &par);
-
- do_fb_set_var(&virgefb_default, 1);
- virgefb_get_var(&fb_display[0].var, -1, &fb_info);
- virgefb_set_disp(-1, &fb_info);
- do_install_cmap(0, &fb_info);
-
- if (register_framebuffer(&fb_info) < 0) {
+ }
+
+ fbhw = &Cyber_switch;
+
+ strcpy(fb_info.modename, virgefb_name);
+ fb_info.changevar = NULL;
+ fb_info.node = -1;
+ fb_info.fbops = &virgefb_ops;
+ fb_info.disp = &disp;
+ fb_info.switch_con = &Cyberfb_switch;
+ fb_info.updatevar = &Cyberfb_updatevar;
+ fb_info.blank = &Cyberfb_blank;
+ fb_info.flags = FBINFO_FLAG_DEFAULT;
+
+ fbhw->init();
+ fbhw->decode_var(&virgefb_default, &par);
+ fbhw->encode_var(&virgefb_default, &par);
+
+ do_fb_set_var(&virgefb_default, 1);
+ virgefb_get_var(&fb_display[0].var, -1, &fb_info);
+ virgefb_set_disp(-1, &fb_info);
+ do_install_cmap(0, &fb_info);
+
+ if (register_framebuffer(&fb_info) < 0) {
printk(KERN_ERR "virgefb.c: register_framebuffer failed\n");
return -EINVAL;
- }
+ }
- printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of video memory\n",
- GET_FB_IDX(fb_info.node), fb_info.modename, CyberSize>>10);
+ printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of "
+ "video memory\n", GET_FB_IDX(fb_info.node),
+ fb_info.modename, CyberSize>>10);
- /* TODO: This driver cannot be unloaded yet */
- MOD_INC_USE_COUNT;
- return 0;
+ /* TODO: This driver cannot be unloaded yet */
+ MOD_INC_USE_COUNT;
+ return 0;
+ }
+ return -ENODEV;
}
diff --git a/drivers/zorro/Makefile b/drivers/zorro/Makefile
index 9aa883932..a8c66ed09 100644
--- a/drivers/zorro/Makefile
+++ b/drivers/zorro/Makefile
@@ -19,10 +19,10 @@ L_TARGET := zorro.a
ifeq ($(CONFIG_MODULES),y)
O_TARGET = zorro_syms.o
OX_OBJS = zorrosyms.o
-O_OBJS = zorro.o
+O_OBJS = zorro.o names.o
L_OBJS := zorro_syms.o
else
-L_OBJS := zorro.o
+L_OBJS := zorro.o names.o
endif
ifdef CONFIG_PROC_FS
diff --git a/drivers/zorro/names.c b/drivers/zorro/names.c
new file mode 100644
index 000000000..2277bcc2b
--- /dev/null
+++ b/drivers/zorro/names.c
@@ -0,0 +1,83 @@
+/*
+ * $Id: zorro.c,v 1.1.2.1 1998/06/07 23:21:02 geert Exp $
+ *
+ * Zorro Expansion Device Names
+ *
+ * Copyright (C) 1999-2000 Geert Uytterhoeven
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/zorro.h>
+
+
+ /*
+ * Just for reference, these are the boards we have a driver for in the
+ * kernel:
+ *
+ * ZORRO_PROD_AMERISTAR_A2065
+ * ZORRO_PROD_BSC_FRAMEMASTER_II
+ * ZORRO_PROD_BSC_MULTIFACE_III
+ * ZORRO_PROD_BSC_OKTAGON_2008
+ * ZORRO_PROD_CBM_A2065_1
+ * ZORRO_PROD_CBM_A2065_2
+ * ZORRO_PROD_CBM_A4091_1
+ * ZORRO_PROD_CBM_A4091_2
+ * ZORRO_PROD_CBM_A590_A2091_1
+ * ZORRO_PROD_CBM_A590_A2091_2
+ * ZORRO_PROD_GVP_A1291
+ * ZORRO_PROD_GVP_A530_SCSI
+ * ZORRO_PROD_GVP_COMBO_030_R3_SCSI
+ * ZORRO_PROD_GVP_COMBO_030_R4_SCSI
+ * ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM
+ * ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG
+ * ZORRO_PROD_GVP_GFORCE_030_SCSI
+ * ZORRO_PROD_GVP_GFORCE_040_060
+ * ZORRO_PROD_GVP_GFORCE_040_1
+ * ZORRO_PROD_GVP_GFORCE_040_SCSI_1
+ * ZORRO_PROD_GVP_IO_EXTENDER
+ * ZORRO_PROD_GVP_SERIES_II
+ * ZORRO_PROD_HELFRICH_PICCOLO_RAM
+ * ZORRO_PROD_HELFRICH_PICCOLO_REG
+ * ZORRO_PROD_HELFRICH_RAINBOW_II
+ * ZORRO_PROD_HELFRICH_SD64_RAM
+ * ZORRO_PROD_HELFRICH_SD64_REG
+ * ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET
+ * ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA
+ * ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL
+ * ZORRO_PROD_MACROSYSTEMS_RETINA_Z3
+ * ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx
+ * ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM
+ * ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060
+ * ZORRO_PROD_PHASE5_BLIZZARD_1230_IV_1260
+ * ZORRO_PROD_PHASE5_BLIZZARD_2060
+ * ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS
+ * ZORRO_PROD_PHASE5_CYBERSTORM_MK_II
+ * ZORRO_PROD_PHASE5_CYBERVISION64
+ * ZORRO_PROD_PHASE5_CYBERVISION64_3D
+ * ZORRO_PROD_VILLAGE_TRONIC_ARIADNE
+ * ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2
+ * ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM
+ * ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG
+ * ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3
+ *
+ * And I guess these are automagically supported as well :-)
+ *
+ * ZORRO_PROD_CBM_A560_RAM
+ * ZORRO_PROD_CBM_A590_A2052_A2058_A2091
+ */
+
+void __init zorro_namedevice(struct zorro_dev *dev)
+{
+ /*
+ * Nah, we're not that stupid to put name databases in the kernel ;-)
+ * That's why we have zorroutils...
+ */
+ sprintf(dev->name, "Zorro device %08x", dev->id);
+}
+
diff --git a/drivers/zorro/proc.c b/drivers/zorro/proc.c
index cf981cf3b..8b5ada251 100644
--- a/drivers/zorro/proc.c
+++ b/drivers/zorro/proc.c
@@ -3,7 +3,7 @@
*
* Procfs interface for the Zorro bus.
*
- * Copyright (C) 1998 Geert Uytterhoeven
+ * Copyright (C) 1998-2000 Geert Uytterhoeven
*
* Heavily based on the procfs interface for the PCI bus, which is
*
@@ -46,7 +46,8 @@ proc_bus_zorro_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
{
struct inode *ino = file->f_dentry->d_inode;
struct proc_dir_entry *dp = ino->u.generic_ip;
- struct ConfigDev *cd = dp->data;
+ struct zorro_dev *dev = dp->data;
+ struct ConfigDev cd;
int pos = *ppos;
if (pos >= sizeof(struct ConfigDev))
@@ -55,7 +56,16 @@ proc_bus_zorro_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
nbytes = sizeof(struct ConfigDev);
if (pos + nbytes > sizeof(struct ConfigDev))
nbytes = sizeof(struct ConfigDev) - pos;
- if (copy_to_user(buf, cd, nbytes))
+
+ /* Construct a ConfigDev */
+ memset(&cd, 0, sizeof(cd));
+ cd.cd_Rom = dev->rom;
+ cd.cd_SlotAddr = dev->slotaddr;
+ cd.cd_SlotSize = dev->slotsize;
+ cd.cd_BoardAddr = (void *)dev->resource.start;
+ cd.cd_BoardSize = dev->resource.end-dev->resource.start+1;
+
+ if (copy_to_user(buf, &cd, nbytes))
return -EFAULT;
*ppos += nbytes;
@@ -88,20 +98,11 @@ get_zorro_dev_info(char *buf, char **start, off_t pos, int count)
int len, cnt;
for (slot = cnt = 0; slot < zorro_num_autocon && count > cnt; slot++) {
- struct ConfigDev *cd = &zorro_autocon[slot];
- u16 manuf = cd->cd_Rom.er_Manufacturer;
- u8 prod = cd->cd_Rom.er_Product;
- u8 epc;
- if (manuf == ZORRO_MANUF(ZORRO_PROD_GVP_EPC_BASE) &&
- prod == ZORRO_PROD(ZORRO_PROD_GVP_EPC_BASE)) {
- /* GVP quirk */
- u32 addr = (u32)cd->cd_BoardAddr;
- epc = (*(u16 *)ZTWO_VADDR(addr+0x8000)) & GVP_PRODMASK;
- } else
- epc = 0;
- len = sprintf(buf, "%02x\t%04x%02x%02x\t%08x\t%08x\t%02x\n",
- slot, manuf, prod, epc, (u32)cd->cd_BoardAddr,
- cd->cd_BoardSize, cd->cd_Rom.er_Type);
+ struct zorro_dev *dev = &zorro_autocon[slot];
+ len = sprintf(buf, "%02x\t%08x\t%08lx\t%08lx\t%02x\n", slot,
+ dev->id, dev->resource.start,
+ dev->resource.end-dev->resource.start+1,
+ dev->rom.er_Type);
at += len;
if (at >= pos) {
if (!*start) {
@@ -128,7 +129,7 @@ static int __init zorro_proc_attach_device(u_int slot)
return -ENOMEM;
entry->ops = &proc_bus_zorro_inode_operations;
entry->data = &zorro_autocon[slot];
- entry->size = sizeof(struct ConfigDev);
+ entry->size = sizeof(struct zorro_dev);
return 0;
}
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
index fd1b7c3ba..227677c4d 100644
--- a/drivers/zorro/zorro.c
+++ b/drivers/zorro/zorro.c
@@ -3,7 +3,7 @@
*
* Zorro Bus Services
*
- * Copyright (C) 1995-1998 Geert Uytterhoeven
+ * Copyright (C) 1995-2000 Geert Uytterhoeven
*
* 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
@@ -20,120 +20,47 @@
#include <asm/amigahw.h>
- /*
- * Expansion Devices
- */
-
-u_int zorro_num_autocon = 0;
-struct ConfigDev zorro_autocon[ZORRO_NUM_AUTO];
-static u32 zorro_autocon_parts[ZORRO_NUM_AUTO] = { 0, };
+extern void zorro_namedevice(struct zorro_dev *dev);
-
/*
- * Find the key for the next unconfigured expansion device of a specific
- * type.
- *
- * Part is a device specific number (0 <= part <= 31) to allow for the
- * independent configuration of independent parts of an expansion board.
- * Thanks to Jes Soerensen for this idea!
- *
- * Index is used to specify the first board in the autocon list
- * to be tested. It was inserted in order to solve the problem
- * with the GVP boards that use the same product code, but
- * it should help if there are other companies which use the same
- * method as GVP. Drivers for boards which are not using this
- * method do not need to think of this - just set index = 0.
- *
- * Example:
- *
- * while ((key = zorro_find(ZORRO_PROD_MY_BOARD, MY_PART, 0))) {
- * cd = zorro_get_board(key);
- * initialise_this_board;
- * zorro_config_board(key, MY_PART);
- * }
+ * Zorro Expansion Devices
*/
-u_int zorro_find(zorro_id id, u_int part, u_int index)
-{
- u16 manuf = ZORRO_MANUF(id);
- u8 prod = ZORRO_PROD(id);
- u8 epc = ZORRO_EPC(id);
- u_int key;
- const struct ConfigDev *cd;
- u32 addr;
-
- if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
- return 0;
-
- if (part > 31) {
- printk("zorro_find: bad part %d\n", part);
- return 0;
- }
-
- for (key = index+1; key <= zorro_num_autocon; key++) {
- cd = &zorro_autocon[key-1];
- addr = (u32)cd->cd_BoardAddr;
- if ((cd->cd_Rom.er_Manufacturer == manuf) &&
- (cd->cd_Rom.er_Product == prod) &&
- !(zorro_autocon_parts[key-1] & (1<<part)) &&
- (manuf != ZORRO_MANUF(ZORRO_PROD_GVP_EPC_BASE) ||
- prod != ZORRO_PROD(ZORRO_PROD_GVP_EPC_BASE) || /* GVP quirk */
- (*(u16 *)ZTWO_VADDR(addr+0x8000) & GVP_PRODMASK) == epc))
- return key;
- }
- return 0;
-}
+u_int zorro_num_autocon = 0;
+struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO];
+#if 0
/*
- * Get the board corresponding to a specific key
+ * Zorro Bus Resources
+ * Order _does_ matter! (see code below)
*/
-const struct ConfigDev *zorro_get_board(u_int key)
-{
- if ((key < 1) || (key > zorro_num_autocon)) {
- printk("zorro_get_board: bad key %d\n", key);
- return NULL;
- }
- return &zorro_autocon[key-1];
-}
-
+static struct resource zorro_res[4] = {
+ { "Zorro II exp", 0x00e80000, 0x00efffff },
+ { "Zorro II mem", 0x00200000, 0x009fffff },
+ { "Zorro III exp", 0xff000000, 0xffffffff },
+ { "Zorro III cfg", 0x40000000, 0x7fffffff }
+};
+#endif
+
/*
- * Mark a part of a board as configured
+ * Find Zorro Devices
*/
-void zorro_config_board(u_int key, u_int part)
+struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from)
{
- if ((key < 1) || (key > zorro_num_autocon))
- printk("zorro_config_board: bad key %d\n", key);
- else if (part > 31)
- printk("zorro_config_board: bad part %d\n", part);
- else if (zorro_autocon_parts[key-1] & (1<<part))
- printk("zorro_config_board: key %d part %d is already configured\n",
- key, part);
- else
- zorro_autocon_parts[key-1] |= 1<<part;
-}
-
+ struct zorro_dev *dev;
- /*
- * Mark a part of a board as unconfigured
- *
- * This function is mainly intended for the unloading of LKMs
- */
+ if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
+ return NULL;
-void zorro_unconfig_board(u_int key, u_int part)
-{
- if ((key < 1) || (key > zorro_num_autocon))
- printk("zorro_unconfig_board: bad key %d\n", key);
- else if (part > 31)
- printk("zorro_unconfig_board: bad part %d\n", part);
- else if (!(zorro_autocon_parts[key-1] & (1<<part)))
- printk("zorro_config_board: key %d part %d is not yet configured\n",
- key, part);
- else
- zorro_autocon_parts[key-1] &= ~(1<<part);
+ dev = from ? from+1 : &zorro_autocon[0];
+ for (; dev < zorro_autocon+zorro_num_autocon; dev++)
+ if (id == ZORRO_WILDCARD || id == dev->id)
+ return dev;
+ return NULL;
}
@@ -153,17 +80,16 @@ void zorro_unconfig_board(u_int key, u_int part)
u32 zorro_unused_z2ram[4] = { 0, 0, 0, 0 };
-static void __init mark_region(u32 addr, u_int size, int flag)
+static void __init mark_region(unsigned long start, unsigned long end,
+ int flag)
{
- u32 start, end;
-
- if (flag) {
- start = (addr+Z2RAM_CHUNKMASK) & ~Z2RAM_CHUNKMASK;
- end = (addr+size) & ~Z2RAM_CHUNKMASK;
- } else {
- start = addr & ~Z2RAM_CHUNKMASK;
- end = (addr+size+Z2RAM_CHUNKMASK) & ~Z2RAM_CHUNKMASK;
- }
+ if (flag)
+ start += Z2RAM_CHUNKMASK;
+ else
+ end += Z2RAM_CHUNKMASK;
+ start &= ~Z2RAM_CHUNKMASK;
+ end &= ~Z2RAM_CHUNKMASK;
+
if (end <= Z2RAM_START || start >= Z2RAM_END)
return;
start = start < Z2RAM_START ? 0x00000000 : start-Z2RAM_START;
@@ -185,27 +111,46 @@ static void __init mark_region(u32 addr, u_int size, int flag)
void __init zorro_init(void)
{
+ struct zorro_dev *dev;
u_int i;
- if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO)) {
- printk("Zorro: No Zorro bus detected\n");
+ if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
return;
- }
printk("Zorro: Probing AutoConfig expansion devices: %d device%s\n",
zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
+ /* Request the resources */
+#if 0
+ for (i = 0; i < (AMIGAHW_PRESENT(ZORRO3) ? 4 : 2); i++)
+ request_resource(&iomem_resource, &zorro_res[i]);
+#endif
+ for (i = 0; i < zorro_num_autocon; i++) {
+ dev = &zorro_autocon[i];
+ dev->id = (dev->rom.er_Manufacturer<<16) | (dev->rom.er_Product<<8);
+ if (dev->id == ZORRO_PROD_GVP_EPC_BASE) {
+ /* GVP quirk */
+ unsigned long magic = dev->resource.start+0x8000;
+ dev->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK;
+ }
+ dev->resource.name = dev->name;
+ zorro_namedevice(dev);
+ if (request_resource(&iomem_resource, &dev->resource))
+ printk("zorro_init: cannot request resource for board %d\n", i);
+ }
+
/* Mark all available Zorro II memory */
for (i = 0; i < zorro_num_autocon; i++) {
- const struct ConfigDev *cd = &zorro_autocon[i];
- if (cd->cd_Rom.er_Type & ERTF_MEMLIST)
- mark_region((u32)cd->cd_BoardAddr, cd->cd_BoardSize, 1);
+ dev = &zorro_autocon[i];
+ if (dev->rom.er_Type & ERTF_MEMLIST)
+ mark_region(dev->resource.start, dev->resource.end+1, 1);
}
/* Unmark all used Zorro II memory */
for (i = 0; i < m68k_num_memory; i++)
if (m68k_memory[i].addr < 16*1024*1024)
- mark_region(m68k_memory[i].addr, m68k_memory[i].size, 0);
+ mark_region(m68k_memory[i].addr,
+ m68k_memory[i].addr+m68k_memory[i].size, 0);
#ifdef CONFIG_PROC_FS
zorro_proc_init();
diff --git a/drivers/zorro/zorrosyms.c b/drivers/zorro/zorrosyms.c
index b08ab54df..d4ac5da87 100644
--- a/drivers/zorro/zorrosyms.c
+++ b/drivers/zorro/zorrosyms.c
@@ -3,7 +3,7 @@
*
* Zorro Bus Services -- Exported Symbols
*
- * Copyright (C) 1998 Geert Uytterhoeven
+ * Copyright (C) 1998-2000 Geert Uytterhoeven
*/
#include <linux/module.h>
@@ -12,10 +12,7 @@
/* Board configuration */
-EXPORT_SYMBOL(zorro_find);
-EXPORT_SYMBOL(zorro_get_board);
-EXPORT_SYMBOL(zorro_config_board);
-EXPORT_SYMBOL(zorro_unconfig_board);
+EXPORT_SYMBOL(zorro_find_device);
/* Z2 memory */
diff --git a/fs/Config.in b/fs/Config.in
index daad6d182..085e191cb 100644
--- a/fs/Config.in
+++ b/fs/Config.in
@@ -6,30 +6,27 @@ comment 'Filesystems'
bool 'Quota support' CONFIG_QUOTA
tristate 'Kernel automounter support' CONFIG_AUTOFS_FS
+tristate 'Kernel automounter version 4 support (also supports v3)' CONFIG_AUTOFS4_FS
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate 'ADFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_ADFS_FS
-fi
+dep_tristate 'ADFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL
+
tristate 'Amiga FFS filesystem support' CONFIG_AFFS_FS
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate 'Apple Macintosh filesystem support (EXPERIMENTAL)' CONFIG_HFS_FS
- tristate 'BFS filesystem (read only) support (EXPERIMENTAL)' CONFIG_BFS_FS
- if [ "$CONFIG_BFS_FS" != "n" ]; then
- bool ' BFS filesystem write support (DANGEROUS)' CONFIG_BFS_FS_WRITE
- fi
-fi
+
+dep_tristate 'Apple Macintosh filesystem support (EXPERIMENTAL)' CONFIG_HFS_FS $CONFIG_EXPERIMENTAL
+
+dep_tristate 'BFS filesystem (read only) support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
+dep_bool ' BFS filesystem write support (DANGEROUS)' CONFIG_BFS_FS_WRITE $CONFIG_BFS_FS
+
# msdos filesystems
tristate 'DOS FAT fs support' CONFIG_FAT_FS
dep_tristate ' MSDOS fs support' CONFIG_MSDOS_FS $CONFIG_FAT_FS
dep_tristate ' UMSDOS: Unix-like filesystem on top of standard MSDOS fs' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS
dep_tristate ' VFAT (Windows-95) fs support' CONFIG_VFAT_FS $CONFIG_FAT_FS
-
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate 'EFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_EFS_FS
-fi
+dep_tristate 'EFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_EFS_FS $CONFIG_EXPERIMENTAL
tristate 'Compressed ROM filessytem support' CONFIG_CRAMFS
+
tristate 'ISO 9660 CDROM filesystem support' CONFIG_ISO9660_FS
if [ "$CONFIG_ISO9660_FS" != "n" ]; then
bool ' Microsoft Joliet CDROM extensions' CONFIG_JOLIET
@@ -39,39 +36,35 @@ else
fi
tristate 'Minix fs support' CONFIG_MINIX_FS
+
tristate 'NTFS filesystem support (read only)' CONFIG_NTFS_FS
-if [ "$CONFIG_NTFS_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
- bool ' NTFS write support (DANGEROUS)' CONFIG_NTFS_RW
-fi
+dep_bool ' NTFS write support (DANGEROUS)' CONFIG_NTFS_RW $CONFIG_NTFS_FS $CONFIG_EXPERIMENTAL
+
tristate 'OS/2 HPFS filesystem support' CONFIG_HPFS_FS
+
bool '/proc filesystem support' CONFIG_PROC_FS
-if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
- # It compiles as a module for testing only. It should not be used
- # as a module in general. If we make this "tristate", a bunch of people
- # who don't know what they are doing turn it on and complain when it
- # breaks.
- bool '/dev/pts filesystem for Unix98 PTYs' CONFIG_DEVPTS_FS
-fi
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate 'QNX4 filesystem support (read only) (EXPERIMENTAL)' CONFIG_QNX4FS_FS
- if [ "$CONFIG_QNX4FS_FS" != "n" ]; then
- bool ' QNX4FS write support (DANGEROUS)' CONFIG_QNX4FS_RW
- fi
-fi
+
+# It compiles as a module for testing only. It should not be used
+# as a module in general. If we make this "tristate", a bunch of people
+# who don't know what they are doing turn it on and complain when it
+# breaks.
+dep_bool '/dev/pts filesystem for Unix98 PTYs' CONFIG_DEVPTS_FS $CONFIG_UNIX98_PTYS
+
+dep_tristate 'QNX4 filesystem support (read only) (EXPERIMENTAL)' CONFIG_QNX4FS_FS $CONFIG_EXPERIMENTAL
+dep_bool ' QNX4FS write support (DANGEROUS)' CONFIG_QNX4FS_RW $CONFIG_QNX4FS_FS
+
tristate 'ROM filesystem support' CONFIG_ROMFS_FS
+
tristate 'Second extended fs support' CONFIG_EXT2_FS
+
tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS
-if [ "$CONFIG_SYSV_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
- bool ' SYSV filesystem write support (DANGEROUS)' CONFIG_SYSV_FS_WRITE
-fi
+dep_bool ' SYSV filesystem write support (DANGEROUS)' CONFIG_SYSV_FS_WRITE $CONFIG_SYSV_FS $CONFIG_EXPERIMENTAL
+
tristate 'UDF filesystem support (read only)' CONFIG_UDF_FS
-if [ "$CONFIG_UDF_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
- bool ' UDF write support (DANGEROUS)' CONFIG_UDF_RW
-fi
+dep_bool ' UDF write support (DANGEROUS)' CONFIG_UDF_RW $CONFIG_UDF_FS $CONFIG_EXPERIMENTAL
+
tristate 'UFS filesystem support (read only)' CONFIG_UFS_FS
-if [ "$CONFIG_UFS_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
- bool ' UFS filesystem write support (DANGEROUS)' CONFIG_UFS_FS_WRITE
-fi
+dep_bool ' UFS filesystem write support (DANGEROUS)' CONFIG_UFS_FS_WRITE $CONFIG_UFS_FS $CONFIG_EXPERIMENTAL
if [ "$CONFIG_NET" = "y" ]; then
@@ -81,16 +74,12 @@ comment 'Network File Systems'
if [ "$CONFIG_INET" = "y" ]; then
tristate 'Coda filesystem support (advanced network fs)' CONFIG_CODA_FS
+
tristate 'NFS filesystem support' CONFIG_NFS_FS
- if [ "$CONFIG_NFS_FS" = "y" -a "$CONFIG_IP_PNP" = "y" ]; then
- bool ' Root file system on NFS' CONFIG_ROOT_NFS
- fi
+ dep_bool ' Root file system on NFS' CONFIG_ROOT_NFS $CONFIG_NFS_FS $CONFIG_IP_PNP
+
tristate 'NFS server support' CONFIG_NFSD
- if [ "$CONFIG_NFSD" != "n" ]; then
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- bool ' Provide NFSv3 server support (EXPERIMENTAL)' CONFIG_NFSD_V3
- fi
- fi
+ dep_bool ' Provide NFSv3 server support (EXPERIMENTAL)' CONFIG_NFSD_V3 $CONFIG_NFSD $CONFIG_EXPERIMENTAL
if [ "$CONFIG_NFS_FS" = "y" -o "$CONFIG_NFSD" = "y" ]; then
define_tristate CONFIG_SUNRPC y
diff --git a/fs/Makefile b/fs/Makefile
index eadd9e16c..e79d69c1b 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -18,7 +18,8 @@ O_OBJS = open.o read_write.o devices.o file_table.o buffer.o \
MOD_LIST_NAME := FS_MODULES
ALL_SUB_DIRS = coda minix ext2 fat msdos vfat proc isofs nfs umsdos ntfs \
hpfs sysv smbfs ncpfs ufs efs affs romfs autofs hfs lockd \
- nfsd nls devpts adfs partitions qnx4 udf bfs cramfs openpromfs
+ nfsd nls devpts adfs partitions qnx4 udf bfs cramfs openpromfs \
+ autofs4
SUB_DIRS := partitions
@@ -253,6 +254,14 @@ else
endif
endif
+ifeq ($(CONFIG_AUTOFS4_FS),y)
+SUB_DIRS += autofs4
+else
+ ifeq ($(CONFIG_AUTOFS4_FS),m)
+ MOD_SUB_DIRS += autofs4
+ endif
+endif
+
ifeq ($(CONFIG_ADFS_FS),y)
SUB_DIRS += adfs
else
diff --git a/fs/autofs/init.c b/fs/autofs/init.c
index a4c5184f2..5c31dc889 100644
--- a/fs/autofs/init.c
+++ b/fs/autofs/init.c
@@ -21,25 +21,18 @@ static struct file_system_type autofs_fs_type = {
NULL
};
-#ifdef MODULE
-int init_module(void)
+static int __init init_autofs_fs(void)
{
return register_filesystem(&autofs_fs_type);
}
-void cleanup_module(void)
+static void __exit exit_autofs_fs(void)
{
unregister_filesystem(&autofs_fs_type);
}
-#else /* MODULE */
-
-int __init init_autofs_fs(void)
-{
- return register_filesystem(&autofs_fs_type);
-}
-
-#endif /* !MODULE */
+module_init(init_autofs_fs)
+module_exit(exit_autofs_fs)
#ifdef DEBUG
void autofs_say(const char *name, int len)
diff --git a/fs/autofs4/.cvsignore b/fs/autofs4/.cvsignore
new file mode 100644
index 000000000..857dd22e9
--- /dev/null
+++ b/fs/autofs4/.cvsignore
@@ -0,0 +1,2 @@
+.depend
+.*.flags
diff --git a/fs/autofs4/Makefile b/fs/autofs4/Makefile
new file mode 100644
index 000000000..0095b8aed
--- /dev/null
+++ b/fs/autofs4/Makefile
@@ -0,0 +1,35 @@
+#
+# Makefile for the linux autofs-filesystem routines.
+#
+# We can build this either out of the kernel tree or the autofs tools tree.
+#
+
+O_TARGET := autofs4.o
+O_OBJS := inohash.o init.o inode.o root.o symlink.o waitq.o expire.o
+
+M_OBJS := $(O_TARGET)
+
+ifdef TOPDIR
+#
+# Part of the kernel code
+#
+include $(TOPDIR)/Rules.make
+else
+#
+# Standalone (handy for development)
+#
+include ../Makefile.rules
+
+CFLAGS += -D__KERNEL__ -DMODULE $(KFLAGS) -I../include -I$(KINCLUDE) $(MODFLAGS)
+
+all: $(O_TARGET)
+
+$(O_TARGET): $(O_OBJS)
+ $(LD) -r -o $(O_TARGET) $(O_OBJS)
+
+install: $(O_TARGET)
+ install -c $(O_TARGET) /lib/modules/`uname -r`/fs
+
+clean:
+ rm -f *.o *.s
+endif
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
new file mode 100644
index 000000000..e8487efd6
--- /dev/null
+++ b/fs/autofs4/autofs_i.h
@@ -0,0 +1,175 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ * linux/fs/autofs/autofs_i.h
+ *
+ * Copyright 1997-1998 Transmeta Corporation - All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/* Internal header file for autofs */
+
+#include <linux/auto_fs.h>
+#include <linux/list.h>
+
+/* This is the range of ioctl() numbers we claim as ours */
+#define AUTOFS_IOC_FIRST AUTOFS_IOC_READY
+#define AUTOFS_IOC_COUNT 32
+
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/wait.h>
+#include <asm/uaccess.h>
+
+/* #define DEBUG */
+
+#ifdef DEBUG
+#define DPRINTK(D) do{ printk("pid %d: ", current->pid); printk D; } while(0)
+#else
+#define DPRINTK(D) do {} while(0)
+#endif
+
+#define AUTOFS_SUPER_MAGIC 0x0187
+
+/*
+ * If the daemon returns a negative response (AUTOFS_IOC_FAIL) then the
+ * kernel will keep the negative response cached for up to the time given
+ * here, although the time can be shorter if the kernel throws the dcache
+ * entry away. This probably should be settable from user space.
+ */
+#define AUTOFS_NEGATIVE_TIMEOUT (60*HZ) /* 1 minute */
+
+/* Unified info structure. This is pointed to by both the dentry and
+ inode structures. Each file in the filesystem has an instance of this
+ structure. It holds a reference to the dentry, so dentries are never
+ flushed while the file exists. All name lookups are dealt with at the
+ dentry level, although the filesystem can interfere in the validation
+ process. Readdir is implemented by traversing the dentry lists. */
+struct autofs_info {
+ struct dentry *dentry;
+ struct inode *inode;
+
+ int flags;
+
+ struct autofs_sb_info *sbi;
+ struct list_head ino_hash;
+ unsigned long last_used;
+
+ ino_t ino;
+ mode_t mode;
+ size_t size;
+
+ void (*free)(struct autofs_info *);
+ union {
+ const char *symlink;
+ } u;
+};
+
+#define AUTOFS_INF_EXPIRING (1<<0) /* dentry is in the process of expiring */
+
+struct autofs_inohash {
+ struct list_head head;
+};
+
+struct autofs_wait_queue {
+ wait_queue_head_t queue;
+ struct autofs_wait_queue *next;
+ autofs_wqt_t wait_queue_token;
+ /* We use the following to see what we are waiting for */
+ int hash;
+ int len;
+ char *name;
+ /* This is for status reporting upon return */
+ int status;
+ int wait_ctr;
+};
+
+#define AUTOFS_ROOT_INO 1
+#define AUTOFS_FIRST_INO 2
+
+#define AUTOFS_SBI_MAGIC 0x6d4a556d
+
+struct autofs_sb_info {
+ u32 magic;
+ struct file *pipe;
+ pid_t oz_pgrp;
+ int catatonic;
+ int version;
+ unsigned long exp_timeout;
+ ino_t next_ino;
+ struct super_block *sb;
+ struct autofs_wait_queue *queues; /* Wait queue pointer */
+ struct autofs_inohash ihash;
+};
+
+static inline struct autofs_sb_info *autofs4_sbi(struct super_block *sb)
+{
+ return (struct autofs_sb_info *)(sb->u.generic_sbp);
+}
+
+static inline struct autofs_info *autofs4_dentry_ino(struct dentry *dentry)
+{
+ return (struct autofs_info *)(dentry->d_fsdata);
+}
+
+/* autofs4_oz_mode(): do we see the man behind the curtain? (The
+ processes which do manipulations for us in user space sees the raw
+ filesystem without "magic".) */
+
+static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) {
+ return sbi->catatonic || current->pgrp == sbi->oz_pgrp;
+}
+
+/* Does a dentry have some pending activity? */
+static inline int autofs4_ispending(struct dentry *dentry)
+{
+ struct autofs_info *inf = autofs4_dentry_ino(dentry);
+
+ return (dentry->d_flags & DCACHE_AUTOFS_PENDING) ||
+ (inf != NULL && inf->flags & AUTOFS_INF_EXPIRING);
+}
+
+/* Inode hash operations */
+void autofs4_init_ihash(struct autofs_inohash *);
+void autofs4_ihash_insert(struct autofs_inohash *ih, struct autofs_info *ino);
+void autofs4_ihash_delete(struct autofs_info *ino);
+void autofs4_ihash_nuke(struct autofs_inohash *ih);
+struct autofs_info *autofs4_ihash_find(struct autofs_inohash *ih, ino_t ino);
+
+struct autofs_info *autofs4_init_inf(struct autofs_sb_info *, mode_t mode);
+void autofs4_free_ino(struct autofs_info *);
+
+/* Expiration */
+int is_autofs4_dentry(struct dentry *);
+int autofs4_expire_run(struct super_block *, struct autofs_sb_info *,
+ struct autofs_packet_expire *);
+int autofs4_expire_multi(struct super_block *, struct autofs_sb_info *, int *);
+
+/* Operations structures */
+
+extern struct inode_operations autofs4_symlink_inode_operations;
+extern struct inode_operations autofs4_dir_inode_operations;
+extern struct inode_operations autofs4_root_inode_operations;
+
+/* Initializing function */
+
+struct super_block *autofs4_read_super(struct super_block *, void *,int);
+struct autofs_info *autofs4_init_ino(struct autofs_info *, struct autofs_sb_info *sbi, mode_t mode);
+
+/* Queue management functions */
+
+enum autofs_notify
+{
+ NFY_NONE,
+ NFY_MOUNT,
+ NFY_EXPIRE
+};
+
+int autofs4_wait(struct autofs_sb_info *,struct qstr *, enum autofs_notify);
+int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int);
+void autofs4_catatonic_mode(struct autofs_sb_info *);
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
new file mode 100644
index 000000000..2318b9aec
--- /dev/null
+++ b/fs/autofs4/expire.c
@@ -0,0 +1,234 @@
+/* -*- linux-c -*- --------------------------------------------------------- *
+ *
+ * linux/fs/autofs/expire.c
+ *
+ * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
+ * Copyright 1999 Jeremy Fitzhardinge <jeremy@goop.org>
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ------------------------------------------------------------------------- */
+
+#include "autofs_i.h"
+
+/*
+ * Determine if a dentry tree is in use. This is much the
+ * same as the standard is_root_busy() function, except
+ * that :-
+ * - the extra dentry reference in autofs dentries is not
+ * considered to be busy
+ * - mountpoints within the tree are not busy
+ * - it traverses across mountpoints
+ * XXX doesn't consider children of covered dentries at mountpoints
+ */
+static int is_tree_busy(struct dentry *root)
+{
+ struct dentry *this_parent;
+ struct list_head *next;
+ int count;
+
+ root = root->d_mounts;
+
+ count = root->d_count;
+ this_parent = root;
+
+ DPRINTK(("is_tree_busy: starting at %.*s/%.*s, d_count=%d\n",
+ root->d_covers->d_parent->d_name.len,
+ root->d_covers->d_parent->d_name.name,
+ root->d_name.len, root->d_name.name,
+ root->d_count));
+
+ /* Ignore autofs's extra reference */
+ if (is_autofs4_dentry(root)) {
+ DPRINTK(("is_tree_busy: autofs\n"));
+ count--;
+ }
+
+ /* Mountpoints don't count */
+ if (root->d_mounts != root ||
+ root->d_covers != root) {
+ DPRINTK(("is_tree_busy: mountpoint\n"));
+ count--;
+ }
+
+repeat:
+ next = this_parent->d_mounts->d_subdirs.next;
+resume:
+ while (next != &this_parent->d_mounts->d_subdirs) {
+ int adj = 0;
+ struct list_head *tmp = next;
+ struct dentry *dentry = list_entry(tmp, struct dentry,
+ d_child);
+
+ next = tmp->next;
+
+ dentry = dentry->d_mounts;
+
+ DPRINTK(("is_tree_busy: considering %.*s/%.*s, d_count=%d, count=%d\n",
+ this_parent->d_name.len,
+ this_parent->d_name.name,
+ dentry->d_covers->d_name.len,
+ dentry->d_covers->d_name.name,
+ dentry->d_count, count));
+
+ /* Decrement count for unused children */
+ count += (dentry->d_count - 1);
+
+ /* Mountpoints don't count */
+ if (dentry->d_mounts != dentry ||
+ dentry->d_covers != dentry) {
+ DPRINTK(("is_tree_busy: mountpoint\n"));
+ adj++;
+ }
+
+ /* Ignore autofs's extra reference */
+ if (is_autofs4_dentry(dentry)) {
+ DPRINTK(("is_tree_busy: autofs\n"));
+ adj++;
+ }
+
+ count -= adj;
+
+ if (!list_empty(&dentry->d_mounts->d_subdirs)) {
+ this_parent = dentry->d_mounts;
+ goto repeat;
+ }
+
+ /* root is busy if any leaf is busy */
+ if (dentry->d_count != adj) {
+ DPRINTK(("is_tree_busy: busy leaf (d_count=%d adj=%d)\n",
+ dentry->d_count, adj));
+ return 1;
+ }
+ }
+ /*
+ * All done at this level ... ascend and resume the search.
+ */
+ if (this_parent != root) {
+ next = this_parent->d_covers->d_child.next;
+ this_parent = this_parent->d_covers->d_parent;
+ goto resume;
+ }
+
+ DPRINTK(("is_tree_busy: count=%d\n", count));
+ return count != 0; /* remaining users? */
+}
+
+/*
+ * Find an eligible tree to time-out
+ * A tree is eligible if :-
+ * - it is unused by any user process
+ * - it has been unused for exp_timeout time
+ */
+static struct dentry *autofs4_expire(struct super_block *sb,
+ struct autofs_sb_info *sbi,
+ int do_now)
+{
+ unsigned long now = jiffies; /* snapshot of now */
+ unsigned long timeout;
+ struct dentry *root = sb->s_root;
+ struct list_head *tmp;
+
+ if (!sbi->exp_timeout || !root)
+ return NULL;
+
+ timeout = sbi->exp_timeout;
+
+ for(tmp = root->d_subdirs.next;
+ tmp != &root->d_subdirs;
+ tmp = tmp->next) {
+ struct autofs_info *ino;
+ struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
+
+ if (dentry->d_inode == NULL)
+ continue;
+
+ ino = autofs4_dentry_ino(dentry);
+
+ if (ino == NULL) {
+ /* dentry in the process of being deleted */
+ continue;
+ }
+
+ /* No point expiring a pending mount */
+ if (dentry->d_flags & DCACHE_AUTOFS_PENDING)
+ continue;
+
+ if (!do_now) {
+ /* Too young to die */
+ if (time_after(ino->last_used+timeout, now))
+ continue;
+
+ /* update last_used here :-
+ - obviously makes sense if it is in use now
+ - less obviously, prevents rapid-fire expire
+ attempts if expire fails the first time */
+ ino->last_used = now;
+ }
+
+ if (!is_tree_busy(dentry)) {
+ DPRINTK(("autofs_expire: returning %p %.*s\n",
+ dentry, dentry->d_name.len, dentry->d_name.name));
+ /* Start from here next time */
+ list_del(&root->d_subdirs);
+ list_add(&root->d_subdirs, &dentry->d_child);
+ return dentry;
+ }
+ }
+
+ return NULL;
+}
+
+/* Perform an expiry operation */
+int autofs4_expire_run(struct super_block *sb,
+ struct autofs_sb_info *sbi,
+ struct autofs_packet_expire *pkt_p)
+{
+ struct autofs_packet_expire pkt;
+ struct dentry *dentry;
+
+ memset(&pkt,0,sizeof pkt);
+
+ pkt.hdr.proto_version = sbi->version;
+ pkt.hdr.type = autofs_ptype_expire;
+
+ if ((dentry = autofs4_expire(sb, sbi, 0)) == NULL)
+ return -EAGAIN;
+
+ pkt.len = dentry->d_name.len;
+ memcpy(pkt.name, dentry->d_name.name, pkt.len);
+ pkt.name[pkt.len] = '\0';
+
+ if ( copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire)) )
+ return -EFAULT;
+
+ return 0;
+}
+
+/* Call repeatedly until it returns -EAGAIN, meaning there's nothing
+ more to be done */
+int autofs4_expire_multi(struct super_block *sb,
+ struct autofs_sb_info *sbi, int *arg)
+{
+ struct dentry *dentry;
+ int ret = -EAGAIN;
+ int do_now = 0;
+
+ if (arg && get_user(do_now, arg))
+ return -EFAULT;
+
+ if ((dentry = autofs4_expire(sb, sbi, do_now)) != NULL) {
+ struct autofs_info *de_info = autofs4_dentry_ino(dentry);
+
+ /* This is synchronous because it makes the daemon a
+ little easier */
+ de_info->flags |= AUTOFS_INF_EXPIRING;
+ ret = autofs4_wait(sbi, &dentry->d_name, NFY_EXPIRE);
+ de_info->flags &= ~AUTOFS_INF_EXPIRING;
+ }
+
+ return ret;
+}
+
diff --git a/fs/autofs4/init.c b/fs/autofs4/init.c
new file mode 100644
index 000000000..48bf60b5f
--- /dev/null
+++ b/fs/autofs4/init.c
@@ -0,0 +1,35 @@
+/* -*- linux-c -*- --------------------------------------------------------- *
+ *
+ * linux/fs/autofs/init.c
+ *
+ * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ------------------------------------------------------------------------- */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include "autofs_i.h"
+
+static struct file_system_type autofs_fs_type = {
+ "autofs",
+ 0,
+ autofs4_read_super,
+ NULL
+};
+
+static int __init init_autofs4_fs(void)
+{
+ return register_filesystem(&autofs_fs_type);
+}
+
+static void __exit exit_autofs4_fs(void)
+{
+ unregister_filesystem(&autofs_fs_type);
+}
+
+module_init(init_autofs4_fs)
+module_exit(exit_autofs4_fs)
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
new file mode 100644
index 000000000..3d3485c9d
--- /dev/null
+++ b/fs/autofs4/inode.c
@@ -0,0 +1,423 @@
+/* -*- linux-c -*- --------------------------------------------------------- *
+ *
+ * linux/fs/autofs/inode.c
+ *
+ * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ------------------------------------------------------------------------- */
+
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/file.h>
+#include <linux/locks.h>
+#include <asm/bitops.h>
+#include "autofs_i.h"
+#define __NO_VERSION__
+#include <linux/module.h>
+
+static void ino_lnkfree(struct autofs_info *ino)
+{
+ if (ino->u.symlink) {
+ kfree(ino->u.symlink);
+ ino->u.symlink = NULL;
+ }
+}
+
+struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
+ struct autofs_sb_info *sbi, mode_t mode)
+{
+ int reinit = 1;
+
+ if (ino == NULL) {
+ reinit = 0;
+ ino = kmalloc(sizeof(*ino), GFP_KERNEL);
+ }
+
+ if (ino == NULL)
+ return NULL;
+
+ ino->flags = 0;
+ ino->ino = sbi->next_ino++;
+ ino->mode = mode;
+ ino->inode = NULL;
+ ino->dentry = NULL;
+ ino->size = 0;
+
+ ino->last_used = jiffies;
+
+ ino->sbi = sbi;
+ INIT_LIST_HEAD(&ino->ino_hash);
+
+ if (reinit && ino->free)
+ (ino->free)(ino);
+
+ memset(&ino->u, 0, sizeof(ino->u));
+
+ ino->free = NULL;
+
+ if (S_ISLNK(mode))
+ ino->free = ino_lnkfree;
+
+ return ino;
+}
+
+void autofs4_free_ino(struct autofs_info *ino)
+{
+ autofs4_ihash_delete(ino);
+ if (ino->dentry) {
+ ino->dentry->d_fsdata = NULL;
+ if (ino->dentry->d_inode)
+ dput(ino->dentry);
+ ino->dentry = NULL;
+ }
+ if (ino->free)
+ (ino->free)(ino);
+ kfree(ino);
+}
+
+/*
+ * Dummy functions - do we ever actually want to do
+ * something here?
+ */
+static void autofs4_put_inode(struct inode *inode)
+{
+}
+
+static void autofs4_clear_inode(struct inode *inode)
+{
+}
+
+static void autofs4_put_super(struct super_block *sb)
+{
+ struct autofs_sb_info *sbi = autofs4_sbi(sb);
+
+ sb->u.generic_sbp = NULL;
+
+ if ( !sbi->catatonic )
+ autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */
+
+ kfree(sbi);
+
+ DPRINTK(("autofs: shutting down\n"));
+
+#ifdef MODULE
+ MOD_DEC_USE_COUNT;
+#endif
+}
+
+static void autofs4_umount_begin(struct super_block *sb)
+{
+ struct autofs_sb_info *sbi = autofs4_sbi(sb);
+
+ if (!sbi->catatonic)
+ autofs4_catatonic_mode(sbi);
+}
+
+static int autofs4_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
+static void autofs4_read_inode(struct inode *inode);
+static void autofs4_write_inode(struct inode *inode);
+
+static struct super_operations autofs4_sops = {
+ read_inode: autofs4_read_inode,
+ write_inode: autofs4_write_inode,
+ put_inode: autofs4_put_inode,
+ clear_inode: autofs4_clear_inode,
+ put_super: autofs4_put_super,
+ statfs: autofs4_statfs,
+ umount_begin: autofs4_umount_begin,
+};
+
+static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
+ pid_t *pgrp, int *minproto, int *maxproto)
+{
+ char *this_char, *value;
+
+ *uid = current->uid;
+ *gid = current->gid;
+ *pgrp = current->pgrp;
+
+ *minproto = *maxproto = AUTOFS_PROTO_VERSION;
+
+ *pipefd = -1;
+
+ if ( !options ) return 1;
+ for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
+ if ((value = strchr(this_char,'=')) != NULL)
+ *value++ = 0;
+ if (!strcmp(this_char,"fd")) {
+ if (!value || !*value)
+ return 1;
+ *pipefd = simple_strtoul(value,&value,0);
+ if (*value)
+ return 1;
+ }
+ else if (!strcmp(this_char,"uid")) {
+ if (!value || !*value)
+ return 1;
+ *uid = simple_strtoul(value,&value,0);
+ if (*value)
+ return 1;
+ }
+ else if (!strcmp(this_char,"gid")) {
+ if (!value || !*value)
+ return 1;
+ *gid = simple_strtoul(value,&value,0);
+ if (*value)
+ return 1;
+ }
+ else if (!strcmp(this_char,"pgrp")) {
+ if (!value || !*value)
+ return 1;
+ *pgrp = simple_strtoul(value,&value,0);
+ if (*value)
+ return 1;
+ }
+ else if (!strcmp(this_char,"minproto")) {
+ if (!value || !*value)
+ return 1;
+ *minproto = simple_strtoul(value,&value,0);
+ if (*value)
+ return 1;
+ }
+ else if (!strcmp(this_char,"maxproto")) {
+ if (!value || !*value)
+ return 1;
+ *maxproto = simple_strtoul(value,&value,0);
+ if (*value)
+ return 1;
+ }
+ else break;
+ }
+ return (*pipefd < 0);
+}
+
+static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi)
+{
+ struct autofs_info *ino;
+
+ ino = autofs4_init_ino(NULL, sbi, S_IFDIR | 0755);
+ if (!ino)
+ return NULL;
+
+ ino->ino = AUTOFS_ROOT_INO;
+
+ return ino;
+}
+
+struct super_block *autofs4_read_super(struct super_block *s, void *data,
+ int silent)
+{
+ struct inode * root_inode;
+ struct dentry * root;
+ struct file * pipe;
+ int pipefd;
+ struct autofs_sb_info *sbi;
+ int minproto, maxproto;
+
+ MOD_INC_USE_COUNT;
+
+ lock_super(s);
+ /* Super block already completed? */
+ if (s->s_root)
+ goto out_unlock;
+
+ sbi = (struct autofs_sb_info *) kmalloc(sizeof(*sbi), GFP_KERNEL);
+ if ( !sbi )
+ goto fail_unlock;
+ DPRINTK(("autofs: starting up, sbi = %p\n",sbi));
+
+ memset(sbi, 0, sizeof(*sbi));
+
+ s->u.generic_sbp = sbi;
+ sbi->magic = AUTOFS_SBI_MAGIC;
+ sbi->catatonic = 0;
+ sbi->exp_timeout = 0;
+ sbi->oz_pgrp = current->pgrp;
+ sbi->sb = s;
+ sbi->version = 0;
+ autofs4_init_ihash(&sbi->ihash);
+ sbi->queues = NULL;
+ sbi->next_ino = AUTOFS_FIRST_INO;
+ s->s_blocksize = 1024;
+ s->s_blocksize_bits = 10;
+ s->s_magic = AUTOFS_SUPER_MAGIC;
+ s->s_op = &autofs4_sops;
+ s->s_root = NULL;
+ unlock_super(s); /* shouldn't we keep it locked a while longer? */
+
+ /*
+ * Get the root inode and dentry, but defer checking for errors.
+ */
+ autofs4_ihash_insert(&sbi->ihash, autofs4_mkroot(sbi));
+
+ root_inode = iget(s, AUTOFS_ROOT_INO);
+ root = d_alloc_root(root_inode);
+ pipe = NULL;
+
+ /*
+ * Check whether somebody else completed the super block.
+ */
+ if (s->s_root)
+ goto out_dput;
+
+ if (!root)
+ goto fail_iput;
+
+ /* Can this call block? */
+ if (parse_options(data, &pipefd,
+ &root_inode->i_uid, &root_inode->i_gid,
+ &sbi->oz_pgrp,
+ &minproto, &maxproto)) {
+ printk("autofs: called with bogus options\n");
+ goto fail_dput;
+ }
+
+ /* Couldn't this be tested earlier? */
+ if (maxproto < AUTOFS_MIN_PROTO_VERSION ||
+ minproto > AUTOFS_PROTO_VERSION) {
+ printk("autofs: kernel does not match daemon version "
+ "daemon (%d, %d) kernel (%d, %d)\n",
+ minproto, maxproto,
+ AUTOFS_MIN_PROTO_VERSION, AUTOFS_PROTO_VERSION);
+ goto fail_dput;
+ }
+
+ sbi->version = maxproto > AUTOFS_PROTO_VERSION ? AUTOFS_PROTO_VERSION : maxproto;
+
+ DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, sbi->oz_pgrp));
+ pipe = fget(pipefd);
+ /*
+ * Check whether somebody else completed the super block.
+ */
+ if (s->s_root)
+ goto out_fput;
+
+ if ( !pipe ) {
+ printk("autofs: could not open pipe file descriptor\n");
+ goto fail_dput;
+ }
+ if ( !pipe->f_op || !pipe->f_op->write )
+ goto fail_fput;
+ sbi->pipe = pipe;
+
+ /*
+ * Success! Install the root dentry now to indicate completion.
+ */
+ s->s_root = root;
+ return s;
+
+ /*
+ * Success ... somebody else completed the super block for us.
+ */
+out_unlock:
+ unlock_super(s);
+ goto out_dec;
+out_fput:
+ if (pipe)
+ fput(pipe);
+out_dput:
+ if (root)
+ dput(root);
+ else
+ iput(root_inode);
+out_dec:
+ MOD_DEC_USE_COUNT;
+ return s;
+
+ /*
+ * Failure ... clear the s_dev slot and clean up.
+ */
+fail_fput:
+ printk("autofs: pipe file descriptor does not contain proper ops\n");
+ /*
+ * fput() can block, so we clear the super block first.
+ */
+ s->s_dev = 0;
+ fput(pipe);
+ /* fall through */
+fail_dput:
+ /*
+ * dput() can block, so we clear the super block first.
+ */
+ s->s_dev = 0;
+ dput(root);
+ goto fail_free;
+fail_iput:
+ printk("autofs: get root dentry failed\n");
+ /*
+ * iput() can block, so we clear the super block first.
+ */
+ s->s_dev = 0;
+ iput(root_inode);
+fail_free:
+ kfree(sbi);
+ goto fail_dec;
+fail_unlock:
+ unlock_super(s);
+fail_dec:
+ s->s_dev = 0;
+ MOD_DEC_USE_COUNT;
+ return NULL;
+}
+
+static int autofs4_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+{
+ struct statfs tmp;
+
+ tmp.f_type = AUTOFS_SUPER_MAGIC;
+ tmp.f_bsize = 1024;
+ tmp.f_blocks = 0;
+ tmp.f_bfree = 0;
+ tmp.f_bavail = 0;
+ tmp.f_files = 0;
+ tmp.f_ffree = 0;
+ tmp.f_namelen = NAME_MAX;
+ return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+}
+
+static void autofs4_read_inode(struct inode *inode)
+{
+ struct autofs_sb_info *sbi = autofs4_sbi(inode->i_sb);
+ struct autofs_info *inf;
+
+ inf = autofs4_ihash_find(&sbi->ihash, inode->i_ino);
+
+ if (inf == NULL || inf->inode != NULL)
+ return;
+
+ inode->i_mode = inf->mode;
+ inode->i_mtime = inode->i_ctime = inode->i_atime = CURRENT_TIME;
+ inode->i_size = inf->size;
+
+ inode->i_blocks = 0;
+ inode->i_blksize = 0;
+ inode->i_nlink = 1;
+
+ if (inode->i_sb->s_root) {
+ inode->i_uid = inode->i_sb->s_root->d_inode->i_uid;
+ inode->i_gid = inode->i_sb->s_root->d_inode->i_gid;
+ } else {
+ inode->i_uid = 0;
+ inode->i_gid = 0;
+ }
+
+ inf->inode = inode;
+
+ if (S_ISDIR(inf->mode)) {
+ inode->i_nlink = 2;
+ if (inode->i_ino == AUTOFS_ROOT_INO)
+ inode->i_op = &autofs4_root_inode_operations;
+ else
+ inode->i_op = &autofs4_dir_inode_operations;
+ } else if (S_ISLNK(inf->mode)) {
+ inode->i_op = &autofs4_symlink_inode_operations;
+ }
+}
+
+static void autofs4_write_inode(struct inode *inode)
+{
+}
diff --git a/fs/autofs4/inohash.c b/fs/autofs4/inohash.c
new file mode 100644
index 000000000..6190a55d3
--- /dev/null
+++ b/fs/autofs4/inohash.c
@@ -0,0 +1,68 @@
+/*
+ * "inohash" is a misnomer. Inodes are just stored in a single list,
+ * since this code is only ever asked for the most recently inserted
+ * inode.
+ *
+ * Copyright 1999 Jeremy Fitzhardinge <jeremy@goop.org>
+ */
+
+#include "autofs_i.h"
+
+void autofs4_init_ihash(struct autofs_inohash *ih)
+{
+ INIT_LIST_HEAD(&ih->head);
+}
+
+void autofs4_ihash_insert(struct autofs_inohash *ih,
+ struct autofs_info *ino)
+{
+ DPRINTK(("autofs_ihash_insert: adding ino %ld\n", ino->ino));
+
+ list_add(&ino->ino_hash, &ih->head);
+}
+
+void autofs4_ihash_delete(struct autofs_info *inf)
+{
+ DPRINTK(("autofs_ihash_delete: deleting ino %ld\n", inf->ino));
+
+ if (!list_empty(&inf->ino_hash))
+ list_del(&inf->ino_hash);
+}
+
+struct autofs_info *autofs4_ihash_find(struct autofs_inohash *ih,
+ ino_t inum)
+{
+ struct list_head *tmp;
+
+ for(tmp = ih->head.next;
+ tmp != &ih->head;
+ tmp = tmp->next) {
+ struct autofs_info *ino = list_entry(tmp, struct autofs_info, ino_hash);
+ if (ino->ino == inum) {
+ DPRINTK(("autofs_ihash_find: found %ld -> %p\n",
+ inum, ino));
+ return ino;
+ }
+ }
+ DPRINTK(("autofs_ihash_find: didn't find %ld\n", inum));
+ return NULL;
+}
+
+void autofs4_ihash_nuke(struct autofs_inohash *ih)
+{
+ struct list_head *tmp = ih->head.next;
+ struct list_head *next;
+
+ for(; tmp != &ih->head; tmp = next) {
+ struct autofs_info *ino;
+
+ next = tmp->next;
+
+ ino = list_entry(tmp, struct autofs_info, ino_hash);
+
+ DPRINTK(("autofs_ihash_nuke: nuking %ld\n", ino->ino));
+ autofs4_free_ino(ino);
+ }
+ INIT_LIST_HEAD(&ih->head);
+}
+
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
new file mode 100644
index 000000000..b7e4bcd0c
--- /dev/null
+++ b/fs/autofs4/root.c
@@ -0,0 +1,624 @@
+/* -*- linux-c -*- --------------------------------------------------------- *
+ *
+ * linux/fs/autofs/root.c
+ *
+ * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
+ * Copyright 1999 Jeremy Fitzhardinge <jeremy@goop.org>
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ------------------------------------------------------------------------- */
+
+#include <linux/errno.h>
+#include <linux/stat.h>
+#include <linux/param.h>
+#include "autofs_i.h"
+
+static int autofs4_dir_readdir(struct file *,void *,filldir_t);
+static struct dentry *autofs4_dir_lookup(struct inode *,struct dentry *);
+static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *);
+static int autofs4_dir_unlink(struct inode *,struct dentry *);
+static int autofs4_dir_rmdir(struct inode *,struct dentry *);
+static int autofs4_dir_mkdir(struct inode *,struct dentry *,int);
+static int autofs4_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long);
+static struct dentry *autofs4_root_lookup(struct inode *,struct dentry *);
+
+static struct file_operations autofs4_root_operations = {
+ readdir: autofs4_dir_readdir, /* readdir */
+ ioctl: autofs4_root_ioctl, /* ioctl */
+};
+
+struct inode_operations autofs4_root_inode_operations = {
+ &autofs4_root_operations, /* file operations */
+
+ lookup: autofs4_root_lookup, /* lookup */
+ unlink: autofs4_dir_unlink, /* unlink */
+ symlink: autofs4_dir_symlink, /* symlink */
+ mkdir: autofs4_dir_mkdir, /* mkdir */
+ rmdir: autofs4_dir_rmdir, /* rmdir */
+};
+
+static struct file_operations autofs4_dir_operations = {
+ readdir: autofs4_dir_readdir, /* readdir */
+};
+
+struct inode_operations autofs4_dir_inode_operations = {
+ &autofs4_dir_operations, /* file operations */
+
+ lookup: autofs4_dir_lookup, /* lookup */
+ unlink: autofs4_dir_unlink, /* unlink */
+ symlink: autofs4_dir_symlink, /* symlink */
+ mkdir: autofs4_dir_mkdir, /* mkdir */
+ rmdir: autofs4_dir_rmdir, /* rmdir */
+};
+
+static inline struct dentry *nth_child(struct dentry *dir, int nr)
+{
+ struct list_head *tmp = dir->d_subdirs.next;
+
+ while(tmp != &dir->d_subdirs) {
+ if (nr-- == 0)
+ return list_entry(tmp, struct dentry, d_child);
+ tmp = tmp->next;
+ }
+ return NULL;
+}
+
+static int autofs4_dir_readdir(struct file *filp, void *dirent,
+ filldir_t filldir)
+{
+ struct autofs_sb_info *sbi;
+ struct autofs_info *ino;
+ struct dentry *dentry = filp->f_dentry;
+ struct dentry *dent_ptr;
+ struct inode *dir = dentry->d_inode;
+ struct list_head *cursor;
+ off_t nr;
+
+ sbi = autofs4_sbi(dir->i_sb);
+ ino = autofs4_dentry_ino(dentry);
+ nr = filp->f_pos;
+
+ switch(nr)
+ {
+ case 0:
+ if (filldir(dirent, ".", 1, nr, dir->i_ino) < 0)
+ return 0;
+ filp->f_pos = ++nr;
+ /* fall through */
+ case 1:
+ if (filldir(dirent, "..", 2, nr, dentry->d_covers->d_parent->d_inode->i_ino) < 0)
+ return 0;
+ filp->f_pos = ++nr;
+ /* fall through */
+ default:
+ dent_ptr = nth_child(dentry, nr-2);
+ if (dent_ptr == NULL)
+ break;
+
+ cursor = &dent_ptr->d_child;
+
+ while(cursor != &dentry->d_subdirs) {
+ dent_ptr = list_entry(cursor, struct dentry, d_child);
+ if (dent_ptr->d_inode &&
+ filldir(dirent, dent_ptr->d_name.name, dent_ptr->d_name.len, nr,
+ dent_ptr->d_inode->i_ino) < 0)
+ return 0;
+ filp->f_pos = ++nr;
+ cursor = cursor->next;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+/* Update usage from here to top of tree, so that scan of
+ top-level directories will give a useful result */
+static void autofs4_update_usage(struct dentry *dentry)
+{
+ struct dentry *top = dentry->d_sb->s_root;
+
+ for(; dentry != top; dentry = dentry->d_parent) {
+ struct autofs_info *ino = autofs4_dentry_ino(dentry->d_covers);
+
+ if (ino) {
+ update_atime(dentry->d_inode);
+ ino->last_used = jiffies;
+ }
+ }
+}
+
+static int try_to_fill_dentry(struct dentry *dentry,
+ struct super_block *sb,
+ struct autofs_sb_info *sbi)
+{
+ struct autofs_info *de_info = autofs4_dentry_ino(dentry);
+ int status = 0;
+
+ /* Block on any pending expiry here; invalidate the dentry
+ when expiration is done to trigger mount request with a new
+ dentry */
+ if (de_info && (de_info->flags & AUTOFS_INF_EXPIRING)) {
+ DPRINTK(("try_to_fill_entry: waiting for expire %p name=%.*s, flags&PENDING=%s de_info=%p de_info->flags=%x\n",
+ dentry, dentry->d_name.len, dentry->d_name.name,
+ dentry->d_flags & DCACHE_AUTOFS_PENDING?"t":"f",
+ de_info, de_info?de_info->flags:0));
+ status = autofs4_wait(sbi, &dentry->d_name, NFY_NONE);
+
+ DPRINTK(("try_to_fill_entry: expire done status=%d\n", status));
+
+ return 0;
+ }
+
+ DPRINTK(("try_to_fill_entry: dentry=%p %.*s ino=%p\n",
+ dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode));
+
+ /* Wait for a pending mount, triggering one if there isn't one already */
+ while(dentry->d_inode == NULL) {
+ DPRINTK(("try_to_fill_entry: waiting for mount name=%.*s, de_info=%p de_info->flags=%x\n",
+ dentry->d_name.len, dentry->d_name.name,
+ de_info, de_info?de_info->flags:0));
+ status = autofs4_wait(sbi, &dentry->d_name, NFY_MOUNT);
+
+ DPRINTK(("try_to_fill_entry: mount done status=%d\n", status));
+
+ if (status && dentry->d_inode)
+ return 0; /* Try to get the kernel to invalidate this dentry */
+
+ /* Turn this into a real negative dentry? */
+ if (status == -ENOENT) {
+ dentry->d_time = jiffies + AUTOFS_NEGATIVE_TIMEOUT;
+ dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
+ return 1;
+ } else if (status) {
+ /* Return a negative dentry, but leave it "pending" */
+ return 1;
+ }
+ status = autofs4_wait(sbi, &dentry->d_name, NFY_MOUNT);
+ }
+
+ /* If this is an unused directory that isn't a mount point,
+ bitch at the daemon and fix it in user space */
+ if (S_ISDIR(dentry->d_inode->i_mode) &&
+ dentry->d_mounts == dentry &&
+ list_empty(&dentry->d_subdirs)) {
+ DPRINTK(("try_to_fill_entry: mounting existing dir\n"));
+ return autofs4_wait(sbi, &dentry->d_name, NFY_MOUNT) == 0;
+ }
+
+ /* We don't update the usages for the autofs daemon itself, this
+ is necessary for recursive autofs mounts */
+ if (!autofs4_oz_mode(sbi))
+ autofs4_update_usage(dentry);
+
+ dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
+ return 1;
+}
+
+
+/*
+ * Revalidate is called on every cache lookup. Some of those
+ * cache lookups may actually happen while the dentry is not
+ * yet completely filled in, and revalidate has to delay such
+ * lookups..
+ */
+static int autofs4_root_revalidate(struct dentry * dentry, int flags)
+{
+ struct inode * dir = dentry->d_parent->d_inode;
+ struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
+ struct autofs_info *ino;
+ int oz_mode = autofs4_oz_mode(sbi);
+
+ /* Pending dentry */
+ if (autofs4_ispending(dentry)) {
+ if (autofs4_oz_mode(sbi))
+ return 1;
+ else
+ return try_to_fill_dentry(dentry, dir->i_sb, sbi);
+ }
+
+ /* Negative dentry.. invalidate if "old" */
+ if (dentry->d_inode == NULL)
+ return (dentry->d_time - jiffies <= AUTOFS_NEGATIVE_TIMEOUT);
+
+ ino = autofs4_dentry_ino(dentry);
+
+ /* Check for a non-mountpoint directory with no contents */
+ if (S_ISDIR(dentry->d_inode->i_mode) &&
+ dentry->d_mounts == dentry &&
+ list_empty(&dentry->d_subdirs)) {
+ DPRINTK(("autofs_root_revalidate: dentry=%p %.*s, emptydir\n",
+ dentry, dentry->d_name.len, dentry->d_name.name));
+ if (autofs4_oz_mode(sbi))
+ return 1;
+ else
+ return try_to_fill_dentry(dentry, dir->i_sb, sbi);
+ }
+
+ /* Update the usage list */
+ if (!oz_mode)
+ autofs4_update_usage(dentry);
+
+ return 1;
+}
+
+static int autofs4_revalidate(struct dentry *dentry, int flags)
+{
+ struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
+
+ if (!autofs4_oz_mode(sbi))
+ autofs4_update_usage(dentry);
+
+ return 1;
+}
+
+static void autofs4_dentry_release(struct dentry *de)
+{
+ struct autofs_info *inf = autofs4_dentry_ino(de);
+
+ DPRINTK(("autofs4_dentry_release: releasing %p\n", de));
+
+ de->d_fsdata = NULL;
+ if (inf) {
+ inf->dentry = NULL;
+ inf->inode = NULL;
+
+ autofs4_free_ino(inf);
+ }
+}
+
+/* For dentries of directories in the root dir */
+static struct dentry_operations autofs4_root_dentry_operations = {
+ d_revalidate: autofs4_root_revalidate, /* d_revalidate */
+ d_release: autofs4_dentry_release,
+};
+
+/* For other dentries */
+static struct dentry_operations autofs4_dentry_operations = {
+ d_revalidate: autofs4_revalidate, /* d_revalidate */
+ d_release: autofs4_dentry_release,
+};
+
+/* Lookups in non-root dirs never find anything - if it's there, it's
+ already in the dcache */
+static struct dentry *autofs4_dir_lookup(struct inode *dir, struct dentry *dentry)
+{
+#if 0
+ DPRINTK(("autofs_dir_lookup: ignoring lookup of %.*s/%.*s\n",
+ dentry->d_parent->d_name.len, dentry->d_parent->d_name.name,
+ dentry->d_name.len, dentry->d_name.name));
+#endif
+
+ dentry->d_fsdata = NULL;
+ d_add(dentry, NULL);
+ return NULL;
+}
+
+/* Lookups in the root directory */
+static struct dentry *autofs4_root_lookup(struct inode *dir, struct dentry *dentry)
+{
+ struct autofs_sb_info *sbi;
+ int oz_mode;
+
+ DPRINTK(("autofs_root_lookup: name = %.*s\n",
+ dentry->d_name.len, dentry->d_name.name));
+
+ if (dentry->d_name.len > NAME_MAX)
+ return ERR_PTR(-ENOENT);/* File name too long to exist */
+
+ sbi = autofs4_sbi(dir->i_sb);
+
+ oz_mode = autofs4_oz_mode(sbi);
+ DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n",
+ current->pid, current->pgrp, sbi->catatonic, oz_mode));
+
+ /*
+ * Mark the dentry incomplete, but add it. This is needed so
+ * that the VFS layer knows about the dentry, and we can count
+ * on catching any lookups through the revalidate.
+ *
+ * Let all the hard work be done by the revalidate function that
+ * needs to be able to do this anyway..
+ *
+ * We need to do this before we release the directory semaphore.
+ */
+ if (dir->i_ino == AUTOFS_ROOT_INO)
+ dentry->d_op = &autofs4_root_dentry_operations;
+ else
+ dentry->d_op = &autofs4_dentry_operations;
+
+ dentry->d_flags |= DCACHE_AUTOFS_PENDING;
+ dentry->d_fsdata = NULL;
+ d_add(dentry, NULL);
+
+ if (dentry->d_op && dentry->d_op->d_revalidate) {
+ up(&dir->i_sem);
+ (dentry->d_op->d_revalidate)(dentry, 0);
+ down(&dir->i_sem);
+ }
+
+ /*
+ * If we are still pending, check if we had to handle
+ * a signal. If so we can force a restart..
+ */
+ if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
+ if (signal_pending(current))
+ return ERR_PTR(-ERESTARTNOINTR);
+ }
+
+ /*
+ * If this dentry is unhashed, then we shouldn't honour this
+ * lookup even if the dentry is positive. Returning ENOENT here
+ * doesn't do the right thing for all system calls, but it should
+ * be OK for the operations we permit from an autofs.
+ */
+ if ( dentry->d_inode && list_empty(&dentry->d_hash) )
+ return ERR_PTR(-ENOENT);
+
+ return NULL;
+}
+
+static int autofs4_dir_symlink(struct inode *dir,
+ struct dentry *dentry,
+ const char *symname)
+{
+ struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
+ struct autofs_info *ino = autofs4_dentry_ino(dentry);
+ struct inode *inode;
+ char *cp;
+
+ DPRINTK(("autofs_dir_symlink: %s <- %.*s\n", symname,
+ dentry->d_name.len, dentry->d_name.name));
+
+ if (!S_ISDIR(dir->i_mode))
+ return -ENOTDIR;
+
+ if (!autofs4_oz_mode(sbi))
+ return -EACCES;
+
+ if (dentry->d_name.len > NAME_MAX)
+ return -ENAMETOOLONG;
+
+ if (dentry->d_inode != NULL)
+ return -EEXIST;
+
+ ino = autofs4_init_ino(ino, sbi, S_IFLNK | 0555);
+ if (ino == NULL)
+ return -ENOSPC;
+
+ ino->size = strlen(symname);
+ ino->u.symlink = cp = kmalloc(ino->size + 1, GFP_KERNEL);
+
+ if (cp == NULL) {
+ kfree(ino);
+ return -ENOSPC;
+ }
+
+ strcpy(cp, symname);
+
+ autofs4_ihash_insert(&sbi->ihash, ino);
+ inode = iget(dir->i_sb,ino->ino);
+ d_instantiate(dentry, inode);
+
+ if (dir->i_ino == AUTOFS_ROOT_INO)
+ dentry->d_op = &autofs4_root_dentry_operations;
+ else
+ dentry->d_op = &autofs4_dentry_operations;
+
+ dentry->d_fsdata = ino;
+ ino->dentry = dget(dentry);
+ ino->inode = inode;
+
+ dir->i_mtime = CURRENT_TIME;
+
+ return 0;
+}
+
+/*
+ * NOTE!
+ *
+ * Normal filesystems would do a "d_delete()" to tell the VFS dcache
+ * that the file no longer exists. However, doing that means that the
+ * VFS layer can turn the dentry into a negative dentry. We don't want
+ * this, because since the unlink is probably the result of an expire.
+ * We simply d_drop it, which allows the dentry lookup to remount it
+ * if necessary.
+ *
+ * If a process is blocked on the dentry waiting for the expire to finish,
+ * it will invalidate the dentry and try to mount with a new one.
+ *
+ * Also see autofs_dir_rmdir()..
+ */
+static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
+{
+ struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
+ struct autofs_info *ino = autofs4_dentry_ino(dentry);
+
+ if (!S_ISDIR(dir->i_mode))
+ return -ENOTDIR;
+
+ if (dentry->d_inode == NULL)
+ return -ENOENT;
+
+ /* This allows root to remove symlinks */
+ if ( !autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) )
+ return -EACCES;
+
+ dput(ino->dentry);
+
+ dentry->d_inode->i_size = 0;
+ dentry->d_inode->i_nlink = 0;
+
+ dir->i_mtime = CURRENT_TIME;
+
+ DPRINTK(("autofs_dir_unlink: unlinking %p %.*s, count=%d\n",
+ dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count));
+
+ d_drop(dentry);
+
+ return 0;
+}
+
+static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
+{
+ struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
+ struct autofs_info *ino = autofs4_dentry_ino(dentry);
+
+ if (!S_ISDIR(dir->i_mode))
+ return -ENOTDIR;
+
+ if (dentry->d_inode == NULL)
+ return -ENOENT;
+
+ if (!autofs4_oz_mode(sbi))
+ return -EACCES;
+
+ if (!list_empty(&dentry->d_subdirs))
+ return -ENOTEMPTY;
+
+ dput(ino->dentry);
+
+ dentry->d_inode->i_size = 0;
+ dentry->d_inode->i_nlink = 0;
+
+ if (dir->i_nlink)
+ dir->i_nlink--;
+
+ DPRINTK(("autofs_dir_rmdir: rmdir %p %.*s, count=%d\n",
+ dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count));
+
+ d_drop(dentry);
+
+ return 0;
+}
+
+
+
+static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
+ struct autofs_info *ino = autofs4_dentry_ino(dentry);
+ struct inode *inode;
+
+ if (!S_ISDIR(dir->i_mode))
+ return -ENOTDIR;
+
+ if ( !autofs4_oz_mode(sbi) )
+ return -EACCES;
+
+ if ( dentry->d_inode != NULL )
+ return -EEXIST;
+
+ if ( dentry->d_name.len > NAME_MAX )
+ return -ENAMETOOLONG;
+
+ DPRINTK(("autofs_dir_mkdir: dentry %p, creating %.*s\n",
+ dentry, dentry->d_name.len, dentry->d_name.name));
+
+ ino = autofs4_init_ino(ino, sbi, S_IFDIR | 0555);
+ if (ino == NULL)
+ return -ENOSPC;
+
+ autofs4_ihash_insert(&sbi->ihash, ino);
+
+ inode = iget(dir->i_sb, ino->ino);
+ d_instantiate(dentry, inode);
+
+ if (dir->i_ino == AUTOFS_ROOT_INO)
+ dentry->d_op = &autofs4_root_dentry_operations;
+ else
+ dentry->d_op = &autofs4_dentry_operations;
+
+ dentry->d_fsdata = ino;
+ ino->dentry = dget(dentry);
+ ino->inode = inode;
+ dir->i_nlink++;
+ dir->i_mtime = CURRENT_TIME;
+
+ return 0;
+}
+
+/* Get/set timeout ioctl() operation */
+static inline int autofs4_get_set_timeout(struct autofs_sb_info *sbi,
+ unsigned long *p)
+{
+ int rv;
+ unsigned long ntimeout;
+
+ if ( (rv = get_user(ntimeout, p)) ||
+ (rv = put_user(sbi->exp_timeout/HZ, p)) )
+ return rv;
+
+ if ( ntimeout > ULONG_MAX/HZ )
+ sbi->exp_timeout = 0;
+ else
+ sbi->exp_timeout = ntimeout * HZ;
+
+ return 0;
+}
+
+/* Return protocol version */
+static inline int autofs4_get_protover(struct autofs_sb_info *sbi, int *p)
+{
+ return put_user(sbi->version, p);
+}
+
+/* Identify autofs_dentries - this is so we can tell if there's
+ an extra dentry refcount or not. We only hold a refcount on the
+ dentry if its non-negative (ie, d_inode != NULL)
+*/
+int is_autofs4_dentry(struct dentry *dentry)
+{
+ return dentry && dentry->d_inode &&
+ (dentry->d_op == &autofs4_root_dentry_operations ||
+ dentry->d_op == &autofs4_dentry_operations) &&
+ dentry->d_fsdata != NULL;
+}
+
+/*
+ * ioctl()'s on the root directory is the chief method for the daemon to
+ * generate kernel reactions
+ */
+static int autofs4_root_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ struct autofs_sb_info *sbi = autofs4_sbi(inode->i_sb);
+
+ DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",
+ cmd,arg,sbi,current->pgrp));
+
+ if ( _IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
+ _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT )
+ return -ENOTTY;
+
+ if ( !autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) )
+ return -EPERM;
+
+ switch(cmd) {
+ case AUTOFS_IOC_READY: /* Wait queue: go ahead and retry */
+ return autofs4_wait_release(sbi,(autofs_wqt_t)arg,0);
+ case AUTOFS_IOC_FAIL: /* Wait queue: fail with ENOENT */
+ return autofs4_wait_release(sbi,(autofs_wqt_t)arg,-ENOENT);
+ case AUTOFS_IOC_CATATONIC: /* Enter catatonic mode (daemon shutdown) */
+ autofs4_catatonic_mode(sbi);
+ return 0;
+ case AUTOFS_IOC_PROTOVER: /* Get protocol version */
+ return autofs4_get_protover(sbi, (int *)arg);
+ case AUTOFS_IOC_SETTIMEOUT:
+ return autofs4_get_set_timeout(sbi,(unsigned long *)arg);
+
+ /* return a single thing to expire */
+ case AUTOFS_IOC_EXPIRE:
+ return autofs4_expire_run(inode->i_sb,sbi,
+ (struct autofs_packet_expire *)arg);
+ /* same as above, but can send multiple expires through pipe */
+ case AUTOFS_IOC_EXPIRE_MULTI:
+ return autofs4_expire_multi(inode->i_sb, sbi, (int *)arg);
+
+ default:
+ return -ENOSYS;
+ }
+}
diff --git a/fs/autofs4/symlink.c b/fs/autofs4/symlink.c
new file mode 100644
index 000000000..b86b400cf
--- /dev/null
+++ b/fs/autofs4/symlink.c
@@ -0,0 +1,34 @@
+/* -*- linux-c -*- --------------------------------------------------------- *
+ *
+ * linux/fs/autofs/symlink.c
+ *
+ * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ------------------------------------------------------------------------- */
+
+#include "autofs_i.h"
+
+static int autofs4_readlink(struct dentry *dentry, char *buffer, int buflen)
+{
+ struct autofs_info *ino = autofs4_dentry_ino(dentry);
+
+ return vfs_readlink(dentry, buffer, buflen, ino->u.symlink);
+}
+
+static struct dentry * autofs4_follow_link(struct dentry *dentry,
+ struct dentry *base,
+ unsigned int flags)
+{
+ struct autofs_info *ino = autofs4_dentry_ino(dentry);
+
+ return vfs_follow_link(dentry, base, flags, ino->u.symlink);
+}
+
+struct inode_operations autofs4_symlink_inode_operations = {
+ readlink: autofs4_readlink,
+ follow_link: autofs4_follow_link
+};
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
new file mode 100644
index 000000000..464c940b8
--- /dev/null
+++ b/fs/autofs4/waitq.c
@@ -0,0 +1,251 @@
+/* -*- linux-c -*- --------------------------------------------------------- *
+ *
+ * linux/fs/autofs/waitq.c
+ *
+ * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * ------------------------------------------------------------------------- */
+
+#include <linux/malloc.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/file.h>
+#include "autofs_i.h"
+
+/* We make this a static variable rather than a part of the superblock; it
+ is better if we don't reassign numbers easily even across filesystems */
+static autofs_wqt_t autofs4_next_wait_queue = 1;
+
+/* These are the signals we allow interrupting a pending mount */
+#define SHUTDOWN_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT))
+
+void autofs4_catatonic_mode(struct autofs_sb_info *sbi)
+{
+ struct autofs_wait_queue *wq, *nwq;
+
+ DPRINTK(("autofs: entering catatonic mode\n"));
+
+ sbi->catatonic = 1;
+ wq = sbi->queues;
+ sbi->queues = NULL; /* Erase all wait queues */
+ while ( wq ) {
+ nwq = wq->next;
+ wq->status = -ENOENT; /* Magic is gone - report failure */
+ kfree(wq->name);
+ wq->name = NULL;
+ wake_up(&wq->queue);
+ wq = nwq;
+ }
+ if (sbi->pipe) {
+ fput(sbi->pipe); /* Close the pipe */
+ sbi->pipe = NULL;
+ }
+
+ autofs4_ihash_nuke(&sbi->ihash);
+ shrink_dcache_sb(sbi->sb);
+}
+
+static int autofs4_write(struct file *file, const void *addr, int bytes)
+{
+ unsigned long sigpipe, flags;
+ mm_segment_t fs;
+ const char *data = (const char *)addr;
+ ssize_t wr = 0;
+
+ /** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/
+
+ sigpipe = sigismember(&current->signal, SIGPIPE);
+
+ /* Save pointer to user space and point back to kernel space */
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ while (bytes &&
+ (wr = file->f_op->write(file,data,bytes,&file->f_pos)) > 0) {
+ data += wr;
+ bytes -= wr;
+ }
+
+ set_fs(fs);
+
+ /* Keep the currently executing process from receiving a
+ SIGPIPE unless it was already supposed to get one */
+ if (wr == -EPIPE && !sigpipe) {
+ spin_lock_irqsave(&current->sigmask_lock, flags);
+ sigdelset(&current->signal, SIGPIPE);
+ recalc_sigpending(current);
+ spin_unlock_irqrestore(&current->sigmask_lock, flags);
+ }
+
+ return (bytes > 0);
+}
+
+static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
+ struct autofs_wait_queue *wq,
+ enum autofs_packet_type type)
+{
+ union autofs_packet_union pkt;
+ size_t pktsz;
+
+ DPRINTK(("autofs_notify: wait id = 0x%08lx, name = %.*s, type=%d\n",
+ wq->wait_queue_token, wq->len, wq->name, type));
+
+ memset(&pkt,0,sizeof pkt); /* For security reasons */
+
+ pkt.hdr.proto_version = sbi->version;
+ pkt.hdr.type = type;
+ if (type == autofs_ptype_missing) {
+ struct autofs_packet_missing *mp = &pkt.missing;
+
+ pktsz = sizeof(*mp);
+
+ mp->wait_queue_token = wq->wait_queue_token;
+ mp->len = wq->len;
+ memcpy(mp->name, wq->name, wq->len);
+ mp->name[wq->len] = '\0';
+ } else if (type == autofs_ptype_expire_multi) {
+ struct autofs_packet_expire_multi *ep = &pkt.expire_multi;
+
+ pktsz = sizeof(*ep);
+
+ ep->wait_queue_token = wq->wait_queue_token;
+ ep->len = wq->len;
+ memcpy(ep->name, wq->name, wq->len);
+ ep->name[wq->len] = '\0';
+ } else {
+ printk("autofs_notify_daemon: bad type %d!\n", type);
+ return;
+ }
+
+ if (autofs4_write(sbi->pipe, &pkt, pktsz))
+ autofs4_catatonic_mode(sbi);
+}
+
+int autofs4_wait(struct autofs_sb_info *sbi, struct qstr *name,
+ enum autofs_notify notify)
+{
+ struct autofs_wait_queue *wq;
+ int status;
+
+ /* In catatonic mode, we don't wait for nobody */
+ if ( sbi->catatonic )
+ return -ENOENT;
+
+ /* We shouldn't be able to get here, but just in case */
+ if ( name->len > NAME_MAX )
+ return -ENOENT;
+
+ for ( wq = sbi->queues ; wq ; wq = wq->next ) {
+ if ( wq->hash == name->hash &&
+ wq->len == name->len &&
+ wq->name && !memcmp(wq->name,name->name,name->len) )
+ break;
+ }
+
+ if ( !wq ) {
+ /* Create a new wait queue */
+ wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL);
+ if ( !wq )
+ return -ENOMEM;
+
+ wq->name = kmalloc(name->len,GFP_KERNEL);
+ if ( !wq->name ) {
+ kfree(wq);
+ return -ENOMEM;
+ }
+ wq->wait_queue_token = autofs4_next_wait_queue;
+ if (++autofs4_next_wait_queue == 0)
+ autofs4_next_wait_queue = 1;
+ init_waitqueue_head(&wq->queue);
+ wq->hash = name->hash;
+ wq->len = name->len;
+ wq->status = -EINTR; /* Status return if interrupted */
+ memcpy(wq->name, name->name, name->len);
+ wq->next = sbi->queues;
+ sbi->queues = wq;
+
+ DPRINTK(("autofs_wait: new wait id = 0x%08lx, name = %.*s, nfy=%d\n",
+ wq->wait_queue_token, wq->len, wq->name, notify));
+ /* autofs4_notify_daemon() may block */
+ wq->wait_ctr = 2;
+ if (notify != NFY_NONE) {
+ autofs4_notify_daemon(sbi,wq,
+ notify == NFY_MOUNT ? autofs_ptype_missing :
+ autofs_ptype_expire_multi);
+ }
+ } else {
+ wq->wait_ctr++;
+ DPRINTK(("autofs_wait: existing wait id = 0x%08lx, name = %.*s, nfy=%d\n",
+ wq->wait_queue_token, wq->len, wq->name, notify));
+ }
+
+ /* wq->name is NULL if and only if the lock is already released */
+
+ if ( sbi->catatonic ) {
+ /* We might have slept, so check again for catatonic mode */
+ wq->status = -ENOENT;
+ if ( wq->name ) {
+ kfree(wq->name);
+ wq->name = NULL;
+ }
+ }
+
+ if ( wq->name ) {
+ /* Block all but "shutdown" signals while waiting */
+ sigset_t oldset;
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&current->sigmask_lock, irqflags);
+ oldset = current->blocked;
+ siginitsetinv(&current->blocked, SHUTDOWN_SIGS & ~oldset.sig[0]);
+ recalc_sigpending(current);
+ spin_unlock_irqrestore(&current->sigmask_lock, irqflags);
+
+ interruptible_sleep_on(&wq->queue);
+
+ spin_lock_irqsave(&current->sigmask_lock, irqflags);
+ current->blocked = oldset;
+ recalc_sigpending(current);
+ spin_unlock_irqrestore(&current->sigmask_lock, irqflags);
+ } else {
+ DPRINTK(("autofs_wait: skipped sleeping\n"));
+ }
+
+ status = wq->status;
+
+ if (--wq->wait_ctr == 0) /* Are we the last process to need status? */
+ kfree(wq);
+
+ return status;
+}
+
+
+int autofs4_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_token, int status)
+{
+ struct autofs_wait_queue *wq, **wql;
+
+ for ( wql = &sbi->queues ; (wq = *wql) ; wql = &wq->next ) {
+ if ( wq->wait_queue_token == wait_queue_token )
+ break;
+ }
+ if ( !wq )
+ return -EINVAL;
+
+ *wql = wq->next; /* Unlink from chain */
+ kfree(wq->name);
+ wq->name = NULL; /* Do not wait on this queue */
+
+ wq->status = status;
+
+ if (--wq->wait_ctr == 0) /* Is anyone still waiting for this guy? */
+ kfree(wq);
+ else
+ wake_up(&wq->queue);
+
+ return 0;
+}
+
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 0e34b95bd..47362da04 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -652,7 +652,7 @@ struct inode_operations blkdev_inode_operations = {
&def_blk_fops, /* default file operations */
};
-char * bdevname(kdev_t dev)
+const char * bdevname(kdev_t dev)
{
static char buffer[32];
const char * name = blkdevs[MAJOR(dev)].name;
diff --git a/fs/dcache.c b/fs/dcache.c
index a9a81328a..dc424305f 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -412,20 +412,18 @@ void shrink_dcache_parent(struct dentry * parent)
*/
int shrink_dcache_memory(int priority, unsigned int gfp_mask, zone_t * zone)
{
- if (gfp_mask & __GFP_IO) {
- int count = 0;
- lock_kernel();
- if (priority)
- count = dentry_stat.nr_unused / priority;
- prune_dcache(count);
- unlock_kernel();
- /* FIXME: kmem_cache_shrink here should tell us
- the number of pages freed, and it should
- work in a __GFP_DMA/__GFP_HIGHMEM behaviour
- to free only the interesting pages in
- function of the needs of the current allocation. */
- kmem_cache_shrink(dentry_cache);
- }
+ int count = 0;
+ lock_kernel();
+ if (priority)
+ count = dentry_stat.nr_unused / priority;
+ prune_dcache(count);
+ unlock_kernel();
+ /* FIXME: kmem_cache_shrink here should tell us
+ the number of pages freed, and it should
+ work in a __GFP_DMA/__GFP_HIGHMEM behaviour
+ to free only the interesting pages in
+ function of the needs of the current allocation. */
+ kmem_cache_shrink(dentry_cache);
return 0;
}
diff --git a/fs/devices.c b/fs/devices.c
index 3efb5822a..36e15475a 100644
--- a/fs/devices.c
+++ b/fs/devices.c
@@ -168,14 +168,14 @@ static struct inode_operations chrdev_inode_operations = {
* Print device name (in decimal, hexadecimal or symbolic)
* Note: returns pointer to static data!
*/
-char * kdevname(kdev_t dev)
+const char * kdevname(kdev_t dev)
{
static char buffer[32];
sprintf(buffer, "%02x:%02x", MAJOR(dev), MINOR(dev));
return buffer;
}
-char * cdevname(kdev_t dev)
+const char * cdevname(kdev_t dev)
{
static char buffer[32];
const char * name = chrdevs[MAJOR(dev)].name;
diff --git a/fs/dquot.c b/fs/dquot.c
index 1efafcf51..61dcef366 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -797,17 +797,22 @@ static inline int need_print_warning(struct dquot *dquot, int flag)
return 0;
}
-static void print_warning(struct dquot *dquot, int flag, char *fmtstr, ...)
+static void print_warning(struct dquot *dquot, int flag, const char *fmtstr)
{
- va_list args;
+ struct dentry *root;
+ char *path, *buffer;
if (!need_print_warning(dquot, flag))
return;
- va_start(args, fmtstr);
- vsprintf(quotamessage, fmtstr, args);
- va_end(args);
+ root = dquot->dq_mnt->mnt_sb->s_root;
+ dget(root);
+ buffer = (char *) __get_free_page(GFP_KERNEL);
+ path = buffer ? d_path(root, buffer, PAGE_SIZE) : "?";
+ sprintf(quotamessage, fmtstr, path, quotatypes[dquot->dq_type]);
+ free_page((unsigned long) buffer);
tty_write_message(current->tty, quotamessage);
dquot->dq_flags |= flag;
+ dput(root);
}
static inline char ignore_hardlimit(struct dquot *dquot)
@@ -817,16 +822,13 @@ static inline char ignore_hardlimit(struct dquot *dquot)
static int check_idq(struct dquot *dquot, u_long inodes)
{
- short type = dquot->dq_type;
-
if (inodes <= 0 || dquot->dq_flags & DQ_FAKE)
return QUOTA_OK;
if (dquot->dq_ihardlimit &&
(dquot->dq_curinodes + inodes) > dquot->dq_ihardlimit &&
!ignore_hardlimit(dquot)) {
- print_warning(dquot, DQ_INODES, "%s: write failed, %s file limit reached\n",
- dquot->dq_mnt->mnt_dirname, quotatypes[type]);
+ print_warning(dquot, DQ_INODES, "%s: write failed, %s file limit reached\n");
return NO_QUOTA;
}
@@ -834,17 +836,15 @@ static int check_idq(struct dquot *dquot, u_long inodes)
(dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
dquot->dq_itime && CURRENT_TIME >= dquot->dq_itime &&
!ignore_hardlimit(dquot)) {
- print_warning(dquot, DQ_INODES, "%s: warning, %s file quota exceeded too long.\n",
- dquot->dq_mnt->mnt_dirname, quotatypes[type]);
+ print_warning(dquot, DQ_INODES, "%s: warning, %s file quota exceeded too long.\n");
return NO_QUOTA;
}
if (dquot->dq_isoftlimit &&
(dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
dquot->dq_itime == 0) {
- print_warning(dquot, 0, "%s: warning, %s file quota exceeded\n",
- dquot->dq_mnt->mnt_dirname, quotatypes[type]);
- dquot->dq_itime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.inode_expire[type];
+ print_warning(dquot, 0, "%s: warning, %s file quota exceeded\n");
+ dquot->dq_itime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.inode_expire[dquot->dq_type];
}
return QUOTA_OK;
@@ -852,8 +852,6 @@ static int check_idq(struct dquot *dquot, u_long inodes)
static int check_bdq(struct dquot *dquot, u_long blocks, char prealloc)
{
- short type = dquot->dq_type;
-
if (blocks <= 0 || dquot->dq_flags & DQ_FAKE)
return QUOTA_OK;
@@ -861,8 +859,7 @@ static int check_bdq(struct dquot *dquot, u_long blocks, char prealloc)
(dquot->dq_curblocks + blocks) > dquot->dq_bhardlimit &&
!ignore_hardlimit(dquot)) {
if (!prealloc)
- print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk limit reached.\n",
- dquot->dq_mnt->mnt_dirname, quotatypes[type]);
+ print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk limit reached.\n");
return NO_QUOTA;
}
@@ -871,8 +868,7 @@ static int check_bdq(struct dquot *dquot, u_long blocks, char prealloc)
dquot->dq_btime && CURRENT_TIME >= dquot->dq_btime &&
!ignore_hardlimit(dquot)) {
if (!prealloc)
- print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk quota exceeded too long.\n",
- dquot->dq_mnt->mnt_dirname, quotatypes[type]);
+ print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk quota exceeded too long.\n");
return NO_QUOTA;
}
@@ -880,9 +876,8 @@ static int check_bdq(struct dquot *dquot, u_long blocks, char prealloc)
(dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit &&
dquot->dq_btime == 0) {
if (!prealloc) {
- print_warning(dquot, 0, "%s: warning, %s disk quota exceeded\n",
- dquot->dq_mnt->mnt_dirname, quotatypes[type]);
- dquot->dq_btime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.block_expire[type];
+ print_warning(dquot, 0, "%s: warning, %s disk quota exceeded\n");
+ dquot->dq_btime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.block_expire[dquot->dq_type];
}
else
/*
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index 57a0be62d..08136962a 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -345,18 +345,20 @@ static inline void ext2_set_de_type(struct super_block *sb,
umode_t mode) {
if (!EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
return;
- if (S_ISCHR(mode))
+ if (S_ISREG(mode))
+ de->file_type = EXT2_FT_REG_FILE;
+ else if (S_ISDIR(mode))
+ de->file_type = EXT2_FT_DIR;
+ else if (S_ISLNK(mode))
+ de->file_type = EXT2_FT_SYMLINK;
+ else if (S_ISSOCK(mode))
+ de->file_type = EXT2_FT_SOCK;
+ else if (S_ISFIFO(mode))
+ de->file_type = EXT2_FT_FIFO;
+ else if (S_ISCHR(mode))
de->file_type = EXT2_FT_CHRDEV;
else if (S_ISBLK(mode))
de->file_type = EXT2_FT_BLKDEV;
- else if (S_ISFIFO(mode))
- de->file_type = EXT2_FT_FIFO;
- else if (S_ISLNK(mode))
- de->file_type = EXT2_FT_SYMLINK;
- else if (S_ISREG(mode))
- de->file_type = EXT2_FT_REG_FILE;
- else if (S_ISDIR(mode))
- de->file_type = EXT2_FT_DIR;
}
/*
diff --git a/fs/fat/misc.c b/fs/fat/misc.c
index cd2762732..196e7aa1b 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -338,7 +338,6 @@ int date_dos2unix(unsigned short time,unsigned short date)
month < 2 ? 1 : 0)+3653);
/* days since 1.1.70 plus 80's leap day */
secs += sys_tz.tz_minuteswest*60;
- if (sys_tz.tz_dsttime) secs -= 3600;
return secs;
}
diff --git a/fs/filesystems.c b/fs/filesystems.c
index bae48e19a..10c8f8bd3 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -138,10 +138,6 @@ void __init filesystem_setup(void)
init_efs_fs();
#endif
-#ifdef CONFIG_AUTOFS_FS
- init_autofs_fs();
-#endif
-
#ifdef CONFIG_ADFS_FS
init_adfs_fs();
#endif
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h
index 377b296e8..d1e70e579 100644
--- a/fs/hpfs/hpfs_fn.h
+++ b/fs/hpfs/hpfs_fn.h
@@ -64,13 +64,13 @@ typedef void nonconst; /* What this is for ? */
extern inline time_t local_to_gmt(struct super_block *s, time_t t)
{
extern struct timezone sys_tz;
- return t + sys_tz.tz_minuteswest * 60 - (sys_tz.tz_dsttime ? 3600 : 0) +s->s_hpfs_timeshift;
+ return t + sys_tz.tz_minuteswest * 60 + s->s_hpfs_timeshift;
}
extern inline time_t gmt_to_local(struct super_block *s, time_t t)
{
extern struct timezone sys_tz;
- return t - sys_tz.tz_minuteswest * 60 + (sys_tz.tz_dsttime ? 3600 : 0) -s->s_hpfs_timeshift;
+ return t - sys_tz.tz_minuteswest * 60 - s->s_hpfs_timeshift;
}
/*
diff --git a/fs/inode.c b/fs/inode.c
index d6298d349..4145a2d91 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -398,20 +398,17 @@ void prune_icache(int goal)
int shrink_icache_memory(int priority, int gfp_mask, zone_t *zone)
{
- if (gfp_mask & __GFP_IO)
- {
- int count = 0;
+ int count = 0;
- if (priority)
- count = inodes_stat.nr_unused / priority;
- prune_icache(count);
- /* FIXME: kmem_cache_shrink here should tell us
- the number of pages freed, and it should
- work in a __GFP_DMA/__GFP_HIGHMEM behaviour
- to free only the interesting pages in
- function of the needs of the current allocation. */
- kmem_cache_shrink(inode_cachep);
- }
+ if (priority)
+ count = inodes_stat.nr_unused / priority;
+ prune_icache(count);
+ /* FIXME: kmem_cache_shrink here should tell us
+ the number of pages freed, and it should
+ work in a __GFP_DMA/__GFP_HIGHMEM behaviour
+ to free only the interesting pages in
+ function of the needs of the current allocation. */
+ kmem_cache_shrink(inode_cachep);
return 0;
}
diff --git a/fs/isofs/util.c b/fs/isofs/util.c
index a8962fc76..12cd2d304 100644
--- a/fs/isofs/util.c
+++ b/fs/isofs/util.c
@@ -114,7 +114,6 @@ int iso_date(char * p, int flag)
crtime = 0;
} else {
int monlen[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
- extern struct timezone sys_tz;
days = year * 365;
if (year > 2)
@@ -126,8 +125,6 @@ int iso_date(char * p, int flag)
days += day - 1;
crtime = ((((days * 24) + hour) * 60 + minute) * 60)
+ second;
- if (sys_tz.tz_dsttime)
- crtime -= 3600;
/* sign extend */
if (tz & 0x80)
@@ -149,7 +146,7 @@ int iso_date(char * p, int flag)
* NOTE: mkisofs in versions prior to mkisofs-1.10 had
* the sign wrong on the timezone offset. This has now
* been corrected there too, but if you are getting screwy
- * results this may be the explaination. If enough people
+ * results this may be the explanation. If enough people
* complain, a user configuration option could be added
* to add the timezone offset in with the wrong sign
* for 'compatibility' with older discs, but I cannot see how
diff --git a/fs/namei.c b/fs/namei.c
index 97f8232d4..3b0b73686 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1341,7 +1341,7 @@ asmlinkage long sys_rename(const char * oldname, const char * newname)
return error;
}
-int vfs_readlink(struct dentry *dentry, char *buffer, int buflen, char *link)
+int vfs_readlink(struct dentry *dentry, char *buffer, int buflen, const char *link)
{
u32 len;
@@ -1359,7 +1359,7 @@ out:
static inline struct dentry *
__vfs_follow_link(struct dentry *dentry, struct dentry *base,
- unsigned follow, char *link)
+ unsigned follow, const char *link)
{
struct dentry *result;
UPDATE_ATIME(dentry->d_inode);
@@ -1377,7 +1377,7 @@ fail:
struct dentry *
vfs_follow_link(struct dentry *dentry, struct dentry *base,
-unsigned int follow, char *link)
+unsigned int follow, const char *link)
{
return __vfs_follow_link(dentry,base,follow,link);
}
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index 31e414ebb..565f88c5b 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -868,6 +868,7 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode,
struct ncp_server *server = NCP_SERVER(dir);
struct ncp_entry_info finfo;
int error, result, len = dentry->d_name.len + 1;
+ int opmode;
__u8 __name[len];
PPRINTK("ncp_create_new: creating %s/%s, mode=%x\n",
@@ -886,15 +887,22 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode,
result = ncp_open_create_file_or_subdir(server, dir, __name,
OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE,
attributes, AR_READ | AR_WRITE, &finfo);
- if (!result) {
- finfo.access = O_RDWR;
- error = ncp_instantiate(dir, dentry, &finfo);
- } else {
- if (result == 0x87) error = -ENAMETOOLONG;
- DPRINTK("ncp_create: %s/%s failed\n",
- dentry->d_parent->d_name.name, dentry->d_name.name);
+ opmode = O_RDWR;
+ if (result) {
+ result = ncp_open_create_file_or_subdir(server, dir, __name,
+ OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE,
+ attributes, AR_WRITE, &finfo);
+ if (result) {
+ if (result == 0x87)
+ error = -ENAMETOOLONG;
+ DPRINTK("ncp_create: %s/%s failed\n",
+ dentry->d_parent->d_name.name, dentry->d_name.name);
+ goto out;
+ }
+ opmode = O_WRONLY;
}
-
+ finfo.access = opmode;
+ error = ncp_instantiate(dir, dentry, &finfo);
out:
return error;
}
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index 98fd9f23e..5e28516bf 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -36,9 +36,8 @@ static int ncp_fsync(struct file *file, struct dentry *dentry)
*/
int ncp_make_open(struct inode *inode, int right)
{
- int error, result;
+ int error;
int access;
- struct ncp_entry_info finfo;
error = -EINVAL;
if (!inode) {
@@ -53,6 +52,9 @@ int ncp_make_open(struct inode *inode, int right)
error = -EACCES;
lock_super(inode->i_sb);
if (!NCP_FINFO(inode)->opened) {
+ struct ncp_entry_info finfo;
+ int result;
+
finfo.i.dirEntNum = NCP_FINFO(inode)->dirEntNum;
finfo.i.volNumber = NCP_FINFO(inode)->volNumber;
/* tries max. rights */
@@ -62,10 +64,21 @@ int ncp_make_open(struct inode *inode, int right)
0, AR_READ | AR_WRITE, &finfo);
if (!result)
goto update;
- finfo.access = O_RDONLY;
- result = ncp_open_create_file_or_subdir(NCP_SERVER(inode),
+ /* RDWR did not succeeded, try readonly or writeonly as requested */
+ switch (right) {
+ case O_RDONLY:
+ finfo.access = O_RDONLY;
+ result = ncp_open_create_file_or_subdir(NCP_SERVER(inode),
NULL, NULL, OC_MODE_OPEN,
0, AR_READ, &finfo);
+ break;
+ case O_WRONLY:
+ finfo.access = O_WRONLY;
+ result = ncp_open_create_file_or_subdir(NCP_SERVER(inode),
+ NULL, NULL, OC_MODE_OPEN,
+ 0, AR_WRITE, &finfo);
+ break;
+ }
if (result) {
PPRINTK("ncp_make_open: failed, result=%d\n", result);
goto out_unlock;
@@ -130,7 +143,7 @@ ncp_file_read(struct file *file, char *buf, size_t count, loff_t *ppos)
error = ncp_make_open(inode, O_RDONLY);
if (error) {
- printk(KERN_ERR "ncp_file_read: open failed, error=%d\n", error);
+ DPRINTK(KERN_ERR "ncp_file_read: open failed, error=%d\n", error);
goto out;
}
@@ -208,9 +221,9 @@ ncp_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
errno = 0;
if (!count)
goto out;
- errno = ncp_make_open(inode, O_RDWR);
+ errno = ncp_make_open(inode, O_WRONLY);
if (errno) {
- printk(KERN_ERR "ncp_file_write: open failed, error=%d\n", errno);
+ DPRINTK(KERN_ERR "ncp_file_write: open failed, error=%d\n", errno);
return errno;
}
pos = *ppos;
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index eca5ddf15..84b9e5643 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -683,7 +683,7 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
DPRINTK("ncpfs: trying to change size to %ld\n",
attr->ia_size);
- if ((result = ncp_make_open(inode, O_RDWR)) < 0) {
+ if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
return -EACCES;
}
ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index 6cf94831f..4f7a1d253 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -330,6 +330,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
default:
return -EINVAL;
}
+ /* locking needs both read and write access */
if ((result = ncp_make_open(inode, O_RDWR)) != 0)
{
return result;
diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c
index 806c05d6e..752ae1e1e 100644
--- a/fs/ncpfs/mmap.c
+++ b/fs/ncpfs/mmap.c
@@ -92,17 +92,9 @@ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area,
return page;
}
-struct vm_operations_struct ncp_file_mmap =
+static struct vm_operations_struct ncp_file_mmap =
{
- NULL, /* open */
- NULL, /* close */
- NULL, /* unmap */
- NULL, /* protect */
- NULL, /* sync */
- NULL, /* advise */
- ncp_file_mmap_nopage, /* nopage */
- NULL, /* wppage */
- NULL /* swapout */
+ nopage: ncp_file_mmap_nopage,
};
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 9f58b4171..09a16b302 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -416,7 +416,9 @@ wait_on_write_request(struct nfs_wreq *req)
int
nfs_writepage(struct dentry * dentry, struct page *page)
{
- return nfs_writepage_sync(dentry, dentry->d_inode, page, 0, PAGE_SIZE);
+ int result = nfs_writepage_sync(dentry, dentry->d_inode, page, 0, PAGE_SIZE);
+ if ( result == PAGE_SIZE) return 0;
+ return result;
}
/*
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index e0636f635..3b9927c7a 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -494,7 +494,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
error = nfserr_perm;
if (!rqstp->rq_secure && EX_SECURE(exp)) {
printk(KERN_WARNING
- "nfsd: request from insecure port (%08lx:%d)!\n",
+ "nfsd: request from insecure port (%08x:%d)!\n",
ntohl(rqstp->rq_addr.sin_addr.s_addr),
ntohs(rqstp->rq_addr.sin_port));
goto out;
diff --git a/fs/open.c b/fs/open.c
index 82260bd5d..8aa828088 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -306,11 +306,12 @@ asmlinkage long sys_access(const char * filename, int mode)
struct dentry * dentry;
int old_fsuid, old_fsgid;
kernel_cap_t old_cap;
- int res = -EINVAL;
+ int res;
+
+ if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
+ return -EINVAL;
lock_kernel();
- if (mode != (mode & S_IRWXO)) /* where's F_OK, X_OK, W_OK, R_OK? */
- goto out;
old_fsuid = current->fsuid;
old_fsgid = current->fsgid;
old_cap = current->cap_effective;
@@ -337,7 +338,7 @@ asmlinkage long sys_access(const char * filename, int mode)
current->fsuid = old_fsuid;
current->fsgid = old_fsgid;
current->cap_effective = old_cap;
-out:
+
unlock_kernel();
return res;
}
diff --git a/fs/partitions/Config.in b/fs/partitions/Config.in
index 57706a744..6974e1a2d 100644
--- a/fs/partitions/Config.in
+++ b/fs/partitions/Config.in
@@ -21,7 +21,9 @@ if [ "$CONFIG_PARTITION_ADVANCED" = "y" ]; then
bool ' Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION
bool ' Unixware slices support' CONFIG_UNIXWARE_DISKLABEL
fi
- bool ' Ultrix partition table support' CONFIG_ULTRIX_PARTITION
+ bool 'SGI partition support' CONFIG_SGI_PARTITION
+ bool 'Ultrix partition table support' CONFIG_ULTRIX_PARTITION
+ bool 'Sun partition tables support' CONFIG_SUN_PARTITION
else
if [ "$ARCH" = "alpha" ]; then
define_bool CONFIG_OSF_PARTITION y
@@ -30,7 +32,8 @@ else
define_bool CONFIG_MAC_PARTITION y
fi
if [ "$CONFIG_AMIGA" != "y" -a "$CONFIG_ATARI" != "y" -a \
- "$CONFIG_MAC" != "y" ]; then
+ "$CONFIG_MAC" != "y" -a "$CONFIG_SGI_IP22" != "y" -a \
+ "$CONFIG_SGI_IP27" != "y" ]; then
define_bool CONFIG_MSDOS_PARTITION y
fi
if [ "$CONFIG_AMIGA" = "y" ]; then
@@ -47,15 +50,13 @@ else
if [ "$CONFIG_ATARI" = "y" ]; then
define_bool CONFIG_ATARI_PARTITION y
fi
- bool 'Ultrix partition table support' CONFIG_ULTRIX_PARTITION
-fi
-if [ "$CONFIG_SGI_IP22" != "y" -a "$CONFIG_SGI_IP27" != "y" ]; then
- bool 'SGI partition support' CONFIG_SGI_PARTITION
-else
- define_bool CONFIG_SGI_PARTITION y
-fi
-if [ "$ARCH" != "sparc" -a "$ARCH" != "sparc64" ]; then
- bool 'Sun partition tables support' CONFIG_SUN_PARTITION
-else
- define_bool CONFIG_SUN_PARTITION y
+ if [ "$CONFIG_SGI_IP22" = "y" -o "$CONFIG_SGI_IP27" = "y" ]; then
+ define_bool CONFIG_SGI_PARTITION y
+ fi
+ if [ "$CONFIG_DECSTATION" = "y" ]; then
+ define_bool CONFIG_ULTRIX_PARTITION y
+ fi
+ if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
+ define_bool CONFIG_SUN_PARTITION y
+ fi
fi
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index ec0bd3a4b..d9c4c11de 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -277,7 +277,6 @@ static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor
void register_disk(struct gendisk *gdev, kdev_t dev, unsigned minors,
struct block_device_operations *ops, long size)
{
- unsigned first = (unsigned)dev;
if (!gdev)
return;
grok_partitions(gdev, MINOR(dev)>>gdev->minor_shift, minors, size);
diff --git a/fs/partitions/sgi.c b/fs/partitions/sgi.c
index 8ae97eca0..db9c1ae39 100644
--- a/fs/partitions/sgi.c
+++ b/fs/partitions/sgi.c
@@ -44,15 +44,15 @@ int sgi_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, in
struct sgi_partition *p;
if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {
- printk("Dev %s: unable to read partition table\n", kdevname(dev));
+ printk(KERN_WARNING "Dev %s: unable to read partition table\n", kdevname(dev));
return -1;
}
label = (struct sgi_disklabel *) bh->b_data;
p = &label->partitions[0];
magic = label->magic_mushroom;
if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) {
- printk("Dev %s SGI disklabel: bad magic %08x\n",
- kdevname(dev), magic);
+ /*printk("Dev %s SGI disklabel: bad magic %08x\n",
+ kdevname(dev), magic);*/
brelse(bh);
return 0;
}
@@ -62,7 +62,7 @@ int sgi_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, in
csum += be32_to_cpu(cs);
}
if(csum) {
- printk("Dev %s SGI disklabel: csum bad, label corrupted\n",
+ printk(KERN_WARNING "Dev %s SGI disklabel: csum bad, label corrupted\n",
kdevname(dev));
brelse(bh);
return 0;
diff --git a/fs/partitions/sun.c b/fs/partitions/sun.c
index 5d82a70c6..5f31cde4b 100644
--- a/fs/partitions/sun.c
+++ b/fs/partitions/sun.c
@@ -48,15 +48,15 @@ int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, in
unsigned long spc;
if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {
- printk("Dev %s: unable to read partition table\n",
+ printk(KERN_WARNING "Dev %s: unable to read partition table\n",
kdevname(dev));
return -1;
}
label = (struct sun_disklabel *) bh->b_data;
p = label->partitions;
if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {
- printk("Dev %s Sun disklabel: bad magic %04x\n",
- kdevname(dev), be16_to_cpu(label->magic));
+/* printk(KERN_INFO "Dev %s Sun disklabel: bad magic %04x\n",
+ kdevname(dev), be16_to_cpu(label->magic)); */
brelse(bh);
return 0;
}
diff --git a/fs/partitions/ultrix.c b/fs/partitions/ultrix.c
index 1de4d04b0..654a4fbd1 100644
--- a/fs/partitions/ultrix.c
+++ b/fs/partitions/ultrix.c
@@ -13,11 +13,11 @@
#include <linux/blk.h>
#include "check.h"
-#include "ultrix.h"
-int ultrix_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, int first_part_minor)
+static int ultrix_partition(struct gendisk *hd, kdev_t dev,
+ unsigned long first_sector, int curren_minor)
{
- int i;
+ int i, minor = current_minor;
struct buffer_head *bh;
struct ultrix_disklabel {
s32 pt_magic; /* magic no. indicating part. info exits */
@@ -28,6 +28,12 @@ int ultrix_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector,
} pt_part[8];
} *label;
+#define PT_MAGIC 0x032957 /* Partition magic number */
+#define PT_VALID 1 /* Indicates if struct is valid */
+
+#define SBLOCK ((unsigned long)((16384 - sizeof(struct ultrix_disklabel)) \
+ /get_ptable_blocksize(dev)))
+
bh = bread (dev, SBLOCK, get_ptable_blocksize(dev));
if (!bh) {
printk (" unable to read block 0x%lx\n", SBLOCK);
@@ -38,14 +44,12 @@ int ultrix_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector,
+ get_ptable_blocksize(dev)
- sizeof(struct ultrix_disklabel));
- if (le32_to_cpu(label->pt_magic) == PT_MAGIC &&
- le32_to_cpu(label->pt_valid == PT_VALID)) {
- for (i=0; i<8; i++, first_part_minor++)
- if (le32_to_cpu(label->pt_part[i].pi_nblocks))
- add_gd_partition(hd, first_part_minor,
- le32_to_cpu(label->pt_part[i].pi_blkoff),
- le32_to_cpu(label->pt_part[i].pi_nblocks));
-
+ if (label->pt_magic == PT_MAGIC && label->pt_valid == PT_VALID) {
+ for (i=0; i<8; i++, minor++)
+ if (label->pt_part[i].pi_nblocks)
+ add_gd_partition(hd, minor,
+ label->pt_part[i].pi_blkoff,
+ label->pt_part[i].pi_nblocks);
brelse(bh);
printk ("\n");
return 1;
@@ -54,4 +58,3 @@ int ultrix_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector,
return 0;
}
}
-
diff --git a/fs/partitions/ultrix.h b/fs/partitions/ultrix.h
index b2d24fdfd..385a32590 100644
--- a/fs/partitions/ultrix.h
+++ b/fs/partitions/ultrix.h
@@ -2,12 +2,8 @@
* fs/partitions/ultrix.h
*/
-#define PT_MAGIC 0x032957 /* Partition magic number */
-#define PT_VALID 1 /* Indicates if struct is valid */
+static int ultrix_partition(struct gendisk *hd, kdev_t dev,
+ unsigned long first_sector);
-#define SBLOCK ((unsigned long)((16384 - sizeof(struct ultrix_disklabel)) \
- /get_ptable_blocksize(dev)))
-
-int ultrix_partition(struct gendisk *hd, kdev_t dev,
- unsigned long first_sector, int first_part_minor);
+#define SGI_LABEL_MAGIC 0x0be5a941
diff --git a/fs/select.c b/fs/select.c
index 674cfdaa2..b664d3e81 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -8,6 +8,10 @@
* COFF/ELF binary emulation. If the process has the STICKY_TIMEOUTS
* flag set in its personality we do *not* modify the given timeout
* parameter to reflect time remaining.
+ *
+ * 24 January 2000
+ * Changed sys_poll()/do_poll() to use PAGE_SIZE chunk-based allocation
+ * of fds to overcome nfds < 16390 descriptors limit (Tigran Aivazian).
*/
#include <linux/malloc.h>
@@ -328,39 +332,48 @@ out_nofds:
return ret;
}
-static int do_poll(unsigned int nfds, struct pollfd *fds, poll_table *wait,
- long timeout)
+#define POLLFD_PER_PAGE ((PAGE_SIZE) / sizeof(struct pollfd))
+
+static void do_pollfd(struct pollfd * fdp, poll_table * wait, int *count)
+{
+ int fd;
+ unsigned int mask;
+
+ mask = 0;
+ fd = fdp->fd;
+ if (fd >= 0) {
+ struct file * file = fget(fd);
+ mask = POLLNVAL;
+ if (file != NULL) {
+ mask = DEFAULT_POLLMASK;
+ if (file->f_op && file->f_op->poll)
+ mask = file->f_op->poll(file, wait);
+ mask &= fdp->events | POLLERR | POLLHUP;
+ fput(file);
+ }
+ if (mask) {
+ wait = NULL;
+ (*count)++;
+ }
+ }
+ fdp->revents = mask;
+}
+
+static int do_poll(unsigned int nfds, unsigned int nchunks, unsigned int nleft,
+ struct pollfd *fds[], poll_table *wait, long timeout)
{
int count = 0;
for (;;) {
- unsigned int j;
- struct pollfd * fdpnt;
+ unsigned int i, j;
set_current_state(TASK_INTERRUPTIBLE);
- for (fdpnt = fds, j = 0; j < nfds; j++, fdpnt++) {
- int fd;
- unsigned int mask;
-
- mask = 0;
- fd = fdpnt->fd;
- if (fd >= 0) {
- struct file * file = fget(fd);
- mask = POLLNVAL;
- if (file != NULL) {
- mask = DEFAULT_POLLMASK;
- if (file->f_op && file->f_op->poll)
- mask = file->f_op->poll(file, wait);
- mask &= fdpnt->events | POLLERR | POLLHUP;
- fput(file);
- }
- if (mask) {
- wait = NULL;
- count++;
- }
- }
- fdpnt->revents = mask;
- }
+ for (i=0; i < nchunks; i++)
+ for (j = 0; j < POLLFD_PER_PAGE; j++)
+ do_pollfd(fds[i] + j, wait, &count);
+ if (nleft)
+ for (j = 0; j < nleft; j++)
+ do_pollfd(fds[nchunks] + j, wait, &count);
wait = NULL;
if (count || !timeout || signal_pending(current))
@@ -373,18 +386,17 @@ static int do_poll(unsigned int nfds, struct pollfd *fds, poll_table *wait,
asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout)
{
- int i, fdcount, err, size;
- struct pollfd * fds, *fds1;
+ int i, j, fdcount, err;
+ struct pollfd **fds;
poll_table *wait_table = NULL, *wait = NULL;
+ int nchunks, nleft;
- lock_kernel();
/* Do a sanity check on nfds ... */
- err = -EINVAL;
if (nfds > current->files->max_fds)
- goto out;
+ return -EINVAL;
if (timeout) {
- /* Carefula about overflow in the intermediate values */
+ /* Careful about overflow in the intermediate values */
if ((unsigned long) timeout < MAX_SCHEDULE_TIMEOUT / HZ)
timeout = (unsigned long)(timeout*HZ+999)/1000+1;
else /* Negative or overflow */
@@ -402,32 +414,62 @@ asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout)
wait = wait_table;
}
- size = nfds * sizeof(struct pollfd);
- fds = (struct pollfd *) kmalloc(size, GFP_KERNEL);
- if (!fds)
+ fds = (struct pollfd **)kmalloc(
+ (1 + (nfds - 1) / POLLFD_PER_PAGE) * sizeof(struct pollfd *),
+ GFP_KERNEL);
+ if (fds == NULL)
goto out;
+ nchunks = 0;
+ nleft = nfds;
+ while (nleft > POLLFD_PER_PAGE) { /* allocate complete PAGE_SIZE chunks */
+ fds[nchunks] = (struct pollfd *)__get_free_page(GFP_KERNEL);
+ if (fds[nchunks] == NULL)
+ goto out_fds;
+ nchunks++;
+ nleft -= POLLFD_PER_PAGE;
+ }
+ if (nleft) { /* allocate last PAGE_SIZE chunk, only nleft elements used */
+ fds[nchunks] = (struct pollfd *)__get_free_page(GFP_KERNEL);
+ if (fds[nchunks] == NULL)
+ goto out_fds;
+ }
+
err = -EFAULT;
- if (copy_from_user(fds, ufds, size))
- goto out_fds;
+ for (i=0; i < nchunks; i++)
+ if (copy_from_user(fds[i], ufds + i*POLLFD_PER_PAGE, PAGE_SIZE))
+ goto out_fds1;
+ if (nleft) {
+ if (copy_from_user(fds[nchunks], ufds + nchunks*POLLFD_PER_PAGE,
+ nleft * sizeof(struct pollfd)))
+ goto out_fds1;
+ }
- fdcount = do_poll(nfds, fds, wait, timeout);
+ lock_kernel();
+ fdcount = do_poll(nfds, nchunks, nleft, fds, wait, timeout);
+ unlock_kernel();
/* OK, now copy the revents fields back to user space. */
- fds1 = fds;
- for(i=0; i < (int)nfds; i++, ufds++, fds1++) {
- __put_user(fds1->revents, &ufds->revents);
- }
+ for(i=0; i < nchunks; i++)
+ for (j=0; j < POLLFD_PER_PAGE; j++, ufds++)
+ __put_user((fds[i] + j)->revents, &ufds->revents);
+ if (nleft)
+ for (j=0; j < nleft; j++, ufds++)
+ __put_user((fds[nchunks] + j)->revents, &ufds->revents);
err = fdcount;
if (!fdcount && signal_pending(current))
err = -EINTR;
+out_fds1:
+ if (nleft)
+ free_page((unsigned long)(fds[nchunks]));
out_fds:
+ for (i=0; i < nchunks; i++)
+ free_page((unsigned long)(fds[i]));
kfree(fds);
out:
if (wait)
free_wait(wait_table);
- unlock_kernel();
return err;
}
diff --git a/fs/super.c b/fs/super.c
index 889938116..71b38fd46 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -302,16 +302,22 @@ static struct proc_nfs_info {
int get_filesystem_info( char *buf )
{
- struct vfsmount *tmp = vfsmntlist;
+ struct vfsmount *tmp;
struct proc_fs_info *fs_infop;
struct proc_nfs_info *nfs_infop;
struct nfs_server *nfss;
int len = 0;
+ char *path,*buffer = (char *) __get_free_page(GFP_KERNEL);
- while ( tmp && len < PAGE_SIZE - 160)
- {
+ if (!buffer) return 0;
+ for (tmp = vfsmntlist; tmp && len < PAGE_SIZE - 160;
+ tmp = tmp->mnt_next) {
+ path = d_path(tmp->mnt_sb->s_root, buffer, PAGE_SIZE);
+ if (!path)
+ continue;
len += sprintf( buf + len, "%s %s %s %s",
- tmp->mnt_devname, tmp->mnt_dirname, tmp->mnt_sb->s_type->name,
+ tmp->mnt_devname, path,
+ tmp->mnt_sb->s_type->name,
tmp->mnt_flags & MS_RDONLY ? "ro" : "rw" );
for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
if (tmp->mnt_flags & fs_infop->flag) {
@@ -365,9 +371,9 @@ int get_filesystem_info( char *buf )
nfss->hostname);
}
len += sprintf( buf + len, " 0 0\n" );
- tmp = tmp->mnt_next;
}
+ free_page((unsigned long) buffer);
return len;
}
@@ -681,7 +687,7 @@ static struct block_device *do_umount(kdev_t dev, int unmount_root, int flags)
shrink_dcache_sb(sb);
fsync_dev(dev);
- if (dev==ROOT_DEV && !unmount_root) {
+ if (sb == current->fs->root->d_sb && !unmount_root) {
/*
* Special case for "unmounting" root ...
* we just try to remount it readonly.
@@ -1214,6 +1220,113 @@ void __init mount_root(void)
}
+static void chroot_fs_refs(struct dentry *old_root,
+ struct dentry *new_root)
+{
+ struct task_struct *p;
+
+ read_lock(&tasklist_lock);
+ for_each_task(p) {
+ if (!p->fs) continue;
+ if (p->fs->root == old_root) {
+ dput(old_root);
+ p->fs->root = dget(new_root);
+ printk(KERN_DEBUG "chroot_fs_refs: changed root of "
+ "process %d\n",p->pid);
+ }
+ if (p->fs->pwd == old_root) {
+ dput(old_root);
+ p->fs->pwd = dget(new_root);
+ printk(KERN_DEBUG "chroot_fs_refs: changed cwd of "
+ "process %d\n",p->pid);
+ }
+ }
+ read_unlock(&tasklist_lock);
+}
+
+
+/*
+ * Moves the current root to put_root, and sets root/cwd of all processes
+ * which had them on the old root to new_root.
+ *
+ * Note:
+ * - we don't move root/cwd if they are not at the root (reason: if something
+ * cared enough to change them, it's probably wrong to force them elsewhere)
+ * - it's okay to pick a root that isn't the root of a file system, e.g.
+ * /nfs/my_root where /nfs is the mount point. Better avoid creating
+ * unreachable mount points this way, though.
+ */
+
+asmlinkage long sys_pivot_root(const char *new_root, const char *put_old)
+{
+ struct dentry *root = current->fs->root;
+ struct dentry *d_new_root, *d_put_old, *covered;
+ struct dentry *root_dev_root, *new_root_dev_root;
+ struct dentry *walk, *next;
+ int error;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ lock_kernel();
+ d_new_root = namei(new_root);
+ if (IS_ERR(d_new_root)) {
+ error = PTR_ERR(d_new_root);
+ goto out0;
+ }
+ d_put_old = namei(put_old);
+ if (IS_ERR(d_put_old)) {
+ error = PTR_ERR(d_put_old);
+ goto out1;
+ }
+ down(&mount_sem);
+ if (!d_new_root->d_inode || !d_put_old->d_inode) {
+ error = -ENOENT;
+ goto out2;
+ }
+ if (!S_ISDIR(d_new_root->d_inode->i_mode) ||
+ !S_ISDIR(d_put_old->d_inode->i_mode)) {
+ error = -ENOTDIR;
+ goto out2;
+ }
+ error = -EBUSY;
+ if (d_new_root->d_sb == root->d_sb || d_put_old->d_sb == root->d_sb)
+ goto out2; /* loop */
+ if (d_put_old != d_put_old->d_covers)
+ goto out2; /* mount point is busy */
+ error = -EINVAL;
+ walk = d_put_old; /* make sure we can reach put_old from new_root */
+ for (;;) {
+ next = walk->d_covers->d_parent;
+ if (next == walk)
+ goto out2;
+ if (next == d_new_root)
+ break;
+ walk = next;
+ }
+
+ new_root_dev_root = d_new_root->d_sb->s_root;
+ covered = new_root_dev_root->d_covers;
+ new_root_dev_root->d_covers = new_root_dev_root;
+ dput(covered);
+ covered->d_mounts = covered;
+
+ root_dev_root = root->d_sb->s_root;
+ root_dev_root->d_covers = dget(d_put_old);
+ d_put_old->d_mounts = root_dev_root;
+ chroot_fs_refs(root,d_new_root);
+ error = 0;
+out2:
+ up(&mount_sem);
+ dput(d_put_old);
+out1:
+ dput(d_new_root);
+out0:
+ unlock_kernel();
+ return error;
+}
+
+
#ifdef CONFIG_BLK_DEV_INITRD
int __init change_root(kdev_t new_root_dev,const char *put_old)
@@ -1272,7 +1385,7 @@ int __init change_root(kdev_t new_root_dev,const char *put_old)
}
return 0;
}
- printk(KERN_ERR "error %d\n",PTR_ERR(bdev));
+ printk(KERN_ERR "error %ld\n",PTR_ERR(bdev));
return error;
}
remove_vfsmnt(old_root_dev);
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
index 7b7d065ff..916683186 100644
--- a/fs/udf/dir.c
+++ b/fs/udf/dir.c
@@ -67,13 +67,13 @@ static struct file_operations udf_dir_operations = {
struct inode_operations udf_dir_inode_operations = {
&udf_dir_operations,
-#ifdef CONFIG_UDF_RW
+#if CONFIG_UDF_RW == 1
udf_create, /* create */
#else
NULL, /* create */
#endif
udf_lookup, /* lookup */
-#ifdef CONFIG_UDF_RW
+#if CONFIG_UDF_RW == 1
udf_link, /* link */
udf_unlink, /* unlink */
udf_symlink, /* symlink */
@@ -139,7 +139,7 @@ int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
if ( filp->f_pos == 0 )
{
- if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino) < 0)
+ if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino))
return 0;
}
@@ -161,7 +161,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
char *nameptr;
Uint16 liu;
Uint8 lfi;
- loff_t size = (UDF_I_EXT0OFFS(dir) + dir->i_size) >> 2;
+ loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
struct buffer_head * bh = NULL;
lb_addr bloc, eloc;
Uint32 extoffset, elen, offset;
@@ -170,7 +170,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
return 1;
if (nf_pos == 0)
- nf_pos = (UDF_I_EXT0OFFS(dir) >> 2);
+ nf_pos = (udf_ext0_offset(dir) >> 2);
fibh.soffset = fibh.eoffset = (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
@@ -251,7 +251,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
if (!lfi) /* parent directory */
{
- if (filldir(dirent, "..", 2, filp->f_pos, filp->f_dentry->d_parent->d_inode->i_ino) < 0)
+ if (filldir(dirent, "..", 2, filp->f_pos, filp->f_dentry->d_parent->d_inode->i_ino))
{
if (fibh.sbh != fibh.ebh)
udf_release_data(fibh.ebh);
@@ -264,7 +264,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
{
if ((flen = udf_get_filename(nameptr, fname, lfi)))
{
- if (filldir(dirent, fname, flen, filp->f_pos, iblock) < 0)
+ if (filldir(dirent, fname, flen, filp->f_pos, iblock))
{
if (fibh.sbh != fibh.ebh)
udf_release_data(fibh.ebh);
diff --git a/fs/udf/directory.c b/fs/udf/directory.c
index b8a94e8f5..84c97ee9d 100644
--- a/fs/udf/directory.c
+++ b/fs/udf/directory.c
@@ -213,8 +213,8 @@ udf_get_fileident(void * buffer, int bufsize, int * offset)
#ifdef __KERNEL__
udf_debug("0x%x != TID_FILE_IDENT_DESC\n",
le16_to_cpu(fi->descTag.tagIdent));
- udf_debug("offset: %u sizeof: %u bufsize: %u\n",
- *offset, sizeof(struct FileIdentDesc), bufsize);
+ udf_debug("offset: %u sizeof: %lu bufsize: %u\n",
+ *offset, (unsigned long)sizeof(struct FileIdentDesc), bufsize);
#endif
return NULL;
}
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 81cddaa3f..8ea44d2a8 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -43,94 +43,6 @@
#include "udf_i.h"
#include "udf_sb.h"
-static loff_t udf_file_llseek(struct file *, loff_t, int);
-static ssize_t udf_file_read_adinicb (struct file *, char *, size_t, loff_t *);
-static ssize_t udf_file_write (struct file *, const char *, size_t, loff_t *);
-static int udf_open_file(struct inode *, struct file *);
-static int udf_release_file(struct inode *, struct file *);
-
-static struct file_operations udf_file_operations = {
- udf_file_llseek, /* llseek */
- generic_file_read, /* read */
- udf_file_write, /* write */
- NULL, /* readdir */
- NULL, /* poll */
- udf_ioctl, /* ioctl */
- generic_file_mmap, /* mmap */
- udf_open_file, /* open */
- NULL, /* flush */
- udf_release_file, /* release */
- udf_sync_file, /* fsync */
- NULL, /* fasync */
- NULL /* lock */
-};
-
-struct inode_operations udf_file_inode_operations = {
- &udf_file_operations,
- NULL, /* create */
- NULL, /* lookup */
- NULL, /* link */
- NULL, /* unlink */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- NULL, /* readlink */
- NULL, /* follow_link */
- udf_get_block, /* get_block */
- block_read_full_page, /* readpage */
- block_write_full_page, /* writepage */
-#ifdef CONFIG_UDF_RW
- udf_truncate, /* truncate */
-#else
- NULL, /* truncate */
-#endif
- NULL, /* permission */
- NULL /* revalidate */
-};
-
-static struct file_operations udf_file_operations_adinicb = {
- udf_file_llseek, /* llseek */
- udf_file_read_adinicb,/* read */
- udf_file_write, /* write */
- NULL, /* readdir */
- NULL, /* poll */
- udf_ioctl, /* ioctl */
- NULL, /* mmap */
- NULL, /* open */
- NULL, /* flush */
- udf_release_file, /* release */
- udf_sync_file, /* fsync */
- NULL, /* fasync */
- NULL /* lock */
-};
-
-struct inode_operations udf_file_inode_operations_adinicb = {
- &udf_file_operations_adinicb,
- NULL, /* create */
- NULL, /* lookup */
- NULL, /* link */
- NULL, /* unlink */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- NULL, /* readlink */
- NULL, /* follow_link */
- udf_get_block, /* get_block */
- block_read_full_page, /* readpage */
- block_write_full_page, /* writepage */
-#ifdef CONFIG_UDF_RW
- udf_truncate, /* truncate */
-#else
- NULL, /* truncate */
-#endif
- NULL, /* permission */
- NULL /* revalidate */
-};
-
/*
* Make sure the offset never goes beyond the 32-bit mark..
*/
@@ -181,104 +93,93 @@ static ssize_t udf_file_write(struct file * file, const char * buf,
{
ssize_t retval;
struct inode *inode = file->f_dentry->d_inode;
- remove_suid(inode);
-
- if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
- {
- int i, err;
- struct buffer_head *bh;
-
- if ((bh = udf_expand_adinicb(inode, &i, 0, &err)))
- udf_release_data(bh);
- else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
- return err;
- }
retval = generic_file_write(file, buf, count, ppos, block_write_partial_page);
if (retval > 0)
{
+ remove_suid(inode);
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
UDF_I_UCTIME(inode) = UDF_I_UMTIME(inode) = CURRENT_UTIME;
+ mark_inode_dirty(inode);
}
- mark_inode_dirty(inode);
return retval;
}
-/*
- * udf_file_read
- *
- * PURPOSE
- * Read from an open file.
- *
- * DESCRIPTION
- * Optional - sys_read() will return -EINVAL if this routine is not
- * available.
- *
- * Refer to sys_read() in fs/read_write.c
- * sys_read() -> .
- *
- * Note that you can use generic_file_read() instead, which requires that
- * udf_readpage() be available, but you can use generic_readpage(), which
- * requires that udf_block_map() be available. Reading will then be done by
- * memory-mapping the file a page at a time. This is not suitable for
- * devices that don't handle read-ahead [example: CD-R/RW that may have
- * blank sectors that shouldn't be read].
- *
- * Refer to generic_file_read() in mm/filemap.c and to generic_readpage()
- * in fs/buffer.c
- *
- * Block devices can use block_read() instead. Refer to fs/block_dev.c
- *
- * PRE-CONDITIONS
- * inode Pointer to inode to read from (never NULL).
- * filp Pointer to file to read from (never NULL).
- * buf Point to read buffer (validated).
- * bufsize Size of read buffer.
- *
- * POST-CONDITIONS
- * <return> Bytes read (>=0) or an error code (<0) that
- * sys_read() will return.
- *
- * HISTORY
- * July 1, 1997 - Andrew E. Mileski
- * Written, tested, and released.
- */
-static ssize_t udf_file_read_adinicb(struct file * filp, char * buf,
- size_t bufsize, loff_t * loff)
+int udf_write_partial_page_adinicb(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf)
{
- struct inode *inode = filp->f_dentry->d_inode;
- loff_t size, left, pos;
- Uint32 block;
- struct buffer_head *bh = NULL;
+ struct inode *inode = file->f_dentry->d_inode;
+ int err = 0, block;
+ struct buffer_head *bh;
+ unsigned long kaddr = 0;
+
+ if (!PageLocked(page))
+ BUG();
+ if (offset < 0 || offset >= (inode->i_sb->s_blocksize - udf_file_entry_alloc_offset(inode)))
+ BUG();
+ if (bytes+offset < 0 || bytes+offset > (inode->i_sb->s_blocksize - udf_file_entry_alloc_offset(inode)))
+ BUG();
+
+ kaddr = kmap(page);
+ block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
+ bh = getblk (inode->i_dev, block, inode->i_sb->s_blocksize);
+ if (!buffer_uptodate(bh))
+ {
+ ll_rw_block (READ, 1, &bh);
+ wait_on_buffer(bh);
+ }
+ err = copy_from_user((char *)kaddr + offset, buf, bytes);
+ memcpy(bh->b_data + udf_file_entry_alloc_offset(inode) + offset,
+ (char *)kaddr + offset, bytes);
+ mark_buffer_dirty(bh, 0);
+ brelse(bh);
+ kunmap(page);
+ SetPageUptodate(page);
+ return bytes;
+}
+
+static ssize_t udf_file_write_adinicb(struct file * file, const char * buf,
+ size_t count, loff_t *ppos)
+{
+ ssize_t retval;
+ struct inode *inode = file->f_dentry->d_inode;
+ int err, pos;
- size = inode->i_size;
- if (*loff > size)
- left = 0;
+ if (file->f_flags & O_APPEND)
+ pos = inode->i_size;
else
- left = size - *loff;
- if (left > bufsize)
- left = bufsize;
-
- if (left <= 0)
- return 0;
-
- pos = *loff + UDF_I_EXT0OFFS(inode);
- block = udf_block_map(inode, 0);
- if (!(bh = udf_tread(inode->i_sb,
- udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0),
- inode->i_sb->s_blocksize)))
+ pos = *ppos;
+
+ if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
+ pos + count))
{
- return 0;
+ udf_expand_file_adinicb(file, pos + count, &err);
+ if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
+ {
+ udf_debug("udf_expand_adinicb: err=%d\n", err);
+ return err;
+ }
+ else
+ return udf_file_write(file, buf, count, ppos);
}
- if (!copy_to_user(buf, bh->b_data + pos, left))
- *loff += left;
else
- left = -EFAULT;
+ {
+ if (pos + count > inode->i_size)
+ UDF_I_LENALLOC(inode) = pos + count;
+ else
+ UDF_I_LENALLOC(inode) = inode->i_size;
+ }
- udf_release_data(bh);
+ retval = generic_file_write(file, buf, count, ppos, udf_write_partial_page_adinicb);
- return left;
+ if (retval > 0)
+ {
+ remove_suid(inode);
+ inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+ UDF_I_UCTIME(inode) = UDF_I_UMTIME(inode) = CURRENT_UTIME;
+ mark_inode_dirty(inode);
+ }
+ return retval;
}
/*
@@ -435,3 +336,85 @@ static int udf_open_file(struct inode * inode, struct file * filp)
return -EFBIG;
return 0;
}
+
+static struct file_operations udf_file_operations = {
+ udf_file_llseek, /* llseek */
+ generic_file_read, /* read */
+ udf_file_write, /* write */
+ NULL, /* readdir */
+ NULL, /* poll */
+ udf_ioctl, /* ioctl */
+ generic_file_mmap, /* mmap */
+ udf_open_file, /* open */
+ NULL, /* flush */
+ udf_release_file, /* release */
+ udf_sync_file, /* fsync */
+ NULL, /* fasync */
+ NULL /* lock */
+};
+
+struct inode_operations udf_file_inode_operations = {
+ &udf_file_operations,
+ NULL, /* create */
+ NULL, /* lookup */
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ NULL, /* readlink */
+ NULL, /* follow_link */
+ udf_get_block, /* get_block */
+ block_read_full_page, /* readpage */
+ block_write_full_page, /* writepage */
+#if CONFIG_UDF_RW == 1
+ udf_truncate, /* truncate */
+#else
+ NULL, /* truncate */
+#endif
+ NULL, /* permission */
+ NULL /* revalidate */
+};
+
+static struct file_operations udf_file_operations_adinicb = {
+ udf_file_llseek, /* llseek */
+ generic_file_read, /* read */
+ udf_file_write_adinicb, /* write */
+ NULL, /* readdir */
+ NULL, /* poll */
+ udf_ioctl, /* ioctl */
+ NULL, /* mmap */
+ NULL, /* open */
+ NULL, /* flush */
+ udf_release_file, /* release */
+ udf_sync_file_adinicb, /* fsync */
+ NULL, /* fasync */
+ NULL /* lock */
+};
+
+struct inode_operations udf_file_inode_operations_adinicb = {
+ &udf_file_operations_adinicb,
+ NULL, /* create */
+ NULL, /* lookup */
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ NULL, /* readlink */
+ NULL, /* follow_link */
+ udf_get_block, /* get_block */
+ udf_readpage_adinicb, /* readpage */
+ udf_writepage_adinicb, /* writepage */
+#if CONFIG_UDF_RW == 1
+ udf_truncate_adinicb, /* truncate */
+#else
+ NULL, /* truncate */
+#endif
+ NULL, /* permission */
+ NULL /* revalidate */
+};
diff --git a/fs/udf/fsync.c b/fs/udf/fsync.c
index 3e2b95c19..b5c10c91b 100644
--- a/fs/udf/fsync.c
+++ b/fs/udf/fsync.c
@@ -15,18 +15,18 @@
* ftp://prep.ai.mit.edu/pub/gnu/GPL
* Each contributing author retains all rights to their own work.
*
- * (C) 1999 Ben Fennema
- * (C) 1999 Stelias Computing Inc
+ * (C) 1999-2000 Ben Fennema
+ * (C) 1999-2000 Stelias Computing Inc
*
* HISTORY
*
* 05/22/99 blf Created.
- *
*/
#include "udfdecl.h"
#include <linux/fs.h>
+#include <linux/locks.h>
#include <linux/udf_fs.h>
#include "udf_i.h"
@@ -40,10 +40,21 @@ static int sync_extent_block (struct inode * inode, Uint32 block, int wait)
if (!bh)
return 0;
if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
- brelse (bh);
- return -1;
+ /* There can be a parallell read(2) that started read-I/O
+ on the buffer so we can't assume that there's been
+ an I/O error without first waiting I/O completation. */
+ wait_on_buffer(bh);
+ if (!buffer_uptodate(bh))
+ {
+ brelse (bh);
+ return -1;
+ }
}
if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
+ if (wait)
+ /* when we return from fsync all the blocks
+ must be _just_ stored on disk */
+ wait_on_buffer(bh);
brelse (bh);
return 0;
}
@@ -89,8 +100,7 @@ int udf_sync_file(struct file * file, struct dentry *dentry)
int wait, err = 0;
struct inode *inode = dentry->d_inode;
- if ((S_ISLNK(inode->i_mode) && !(inode->i_blocks)) ||
- UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
+ if (S_ISLNK(inode->i_mode) && !(inode->i_blocks))
{
/*
* Don't sync fast links! or ICB_FLAG_AD_IN_ICB
@@ -108,3 +118,8 @@ skip:
err |= udf_sync_inode (inode);
return err ? -EIO : 0;
}
+
+int udf_sync_file_adinicb(struct file * file, struct dentry *dentry)
+{
+ return udf_sync_inode(dentry->d_inode) ? -EIO : 0;
+}
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index 32f60fef5..8badac9d9 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -15,7 +15,7 @@
* ftp://prep.ai.mit.edu/pub/gnu/GPL
* Each contributing author retains all rights to their own work.
*
- * (C) 1998-1999 Ben Fennema
+ * (C) 1998-2000 Ben Fennema
*
* HISTORY
*
@@ -148,16 +148,7 @@ struct inode * udf_new_inode (const struct inode *dir, int mode, int * err)
inode->i_size = 0;
UDF_I_LENEATTR(inode) = 0;
UDF_I_LENALLOC(inode) = 0;
- UDF_I_EXT0LOC(inode) = UDF_I_LOCATION(inode);
- UDF_I_EXT0LEN(inode) = 0;
-#if 1
- UDF_I_EXT0OFFS(inode) = sizeof(struct FileEntry);
UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_IN_ICB;
-#else
- UDF_I_EXT0OFFS(inode) = 0;
- UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
-#endif
-
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
UDF_I_UMTIME(inode) = UDF_I_UATIME(inode) = UDF_I_UCTIME(inode) = CURRENT_UTIME;
inode->i_op = NULL;
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index e2e12df8e..2ea1f980b 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -16,8 +16,8 @@
* Each contributing author retains all rights to their own work.
*
* (C) 1998 Dave Boynton
- * (C) 1998-1999 Ben Fennema
- * (C) 1999 Stelias Computing Inc
+ * (C) 1998-2000 Ben Fennema
+ * (C) 1999-2000 Stelias Computing Inc
*
* HISTORY
*
@@ -31,7 +31,6 @@
* 03/07/99 rewrote udf_block_map (again)
* New funcs, inode_bmap, udf_next_aext
* 04/19/99 Support for writing device EA's for major/minor #
- *
*/
#include "udfdecl.h"
@@ -58,8 +57,6 @@ static void udf_update_extents(struct inode *,
long_ad [EXTENT_MERGE_SIZE], int, int,
lb_addr, Uint32, struct buffer_head **);
-static DECLARE_MUTEX(read_semaphore);
-
/*
* udf_put_inode
*
@@ -99,56 +96,14 @@ void udf_delete_inode(struct inode * inode)
{
inode->i_size = 0;
if (inode->i_blocks)
- udf_truncate(inode);
+ inode->i_op->truncate(inode);
udf_free_inode(inode);
}
void udf_discard_prealloc(struct inode * inode)
{
-#ifdef UDF_PREALLOCATE
- lb_addr bloc, eloc;
- Uint32 extoffset, elen, nelen, offset, adsize = 0;
- struct buffer_head *bh = NULL;
-
- if ((inode->i_size > 0) &&
- (inode_bmap(inode, (inode->i_size-1) >> inode->i_sb->s_blocksize_bits,
- &bloc, &extoffset, &eloc, &elen, &offset, &bh) ==
- EXTENT_RECORDED_ALLOCATED))
- {
- if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
- adsize = sizeof(short_ad);
- else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
- adsize = sizeof(long_ad);
- else
- {
- udf_release_data(bh);
- return;
- }
-
- nelen = (EXTENT_RECORDED_ALLOCATED << 30) |
- ((((elen - 1) & ~(inode->i_sb->s_blocksize - 1)) |
- ((inode->i_size - 1) & (inode->i_sb->s_blocksize - 1))) + 1);
-
- if (nelen != ((EXTENT_RECORDED_ALLOCATED << 30) | elen))
- {
- extoffset -= adsize;
- udf_write_aext(inode, bloc, &extoffset, eloc, nelen, &bh, 1);
- }
-
- if (udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 0) ==
- EXTENT_NOT_RECORDED_ALLOCATED)
- {
- udf_free_blocks(inode, eloc, 0, elen >> inode->i_sb->s_blocksize_bits);
- memset(&eloc, 0x00, sizeof(lb_addr));
- udf_write_aext(inode, bloc, &extoffset, eloc, 0, &bh, 1);
- UDF_I_LENALLOC(inode) -= adsize;
- udf_write_inode(inode);
- }
- udf_release_data(bh);
- }
- else if (bh)
- udf_release_data(bh);
-#endif
+ if (inode->i_size && UDF_I_ALLOCTYPE(inode) != ICB_FLAG_AD_IN_ICB)
+ udf_trunc(inode);
}
static int udf_alloc_block(struct inode *inode, Uint16 partition,
@@ -162,108 +117,138 @@ static int udf_alloc_block(struct inode *inode, Uint16 partition,
return result;
}
-struct buffer_head * udf_expand_adinicb(struct inode *inode, int *block, int isdir, int *err)
+void udf_expand_file_adinicb(struct file * filp, int newsize, int * err)
{
- if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
- {
- long_ad newad;
- int newblock;
- struct buffer_head *sbh = NULL, *dbh = NULL;
+ struct inode * inode = filp->f_dentry->d_inode;
+ struct buffer_head *bh = NULL;
+ struct page *page;
+ unsigned long kaddr = 0;
- if (!UDF_I_LENALLOC(inode))
- {
- UDF_I_EXT0OFFS(inode) = 0;
- UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
- mark_inode_dirty(inode);
- if (inode->i_op == &udf_file_inode_operations_adinicb)
- inode->i_op = &udf_file_inode_operations;
- return NULL;
- }
+ if (!UDF_I_LENALLOC(inode))
+ {
+ UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
+ mark_inode_dirty(inode);
+ inode->i_op = &udf_file_inode_operations;
+ filp->f_op = inode->i_op->default_file_ops;
+ return;
+ }
- /* alloc block, and copy data to it */
- *block = udf_alloc_block(inode,
- UDF_I_LOCATION(inode).partitionReferenceNum,
- UDF_I_LOCATION(inode).logicalBlockNum, err);
+ bh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize);
+ if (!bh)
+ return;
+ page = grab_cache_page(&inode->i_data, 0);
+ if (!PageLocked(page))
+ BUG();
+ if (!Page_Uptodate(page))
+ {
+ kaddr = kmap(page);
+ memset((char *)kaddr + UDF_I_LENALLOC(inode), 0x00,
+ PAGE_CACHE_SIZE - UDF_I_LENALLOC(inode));
+ memcpy((char *)kaddr, bh->b_data + udf_file_entry_alloc_offset(inode),
+ UDF_I_LENALLOC(inode));
+ kunmap(page);
+ }
+ memset(bh->b_data + udf_file_entry_alloc_offset(inode),
+ 0, UDF_I_LENALLOC(inode));
+ UDF_I_LENALLOC(inode) = 0;
+ UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
+ inode->i_blocks = inode->i_sb->s_blocksize / 512;
+ mark_buffer_dirty(bh, 1);
+ udf_release_data(bh);
- if (!(*block))
- return NULL;
- newblock = udf_get_pblock(inode->i_sb, *block,
- UDF_I_LOCATION(inode).partitionReferenceNum, 0);
- if (!newblock)
- return NULL;
- sbh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize);
- if (!sbh)
- return NULL;
- dbh = udf_tread(inode->i_sb, newblock, inode->i_sb->s_blocksize);
- if (!dbh)
- return NULL;
-
- if (isdir)
- {
- struct udf_fileident_bh sfibh, dfibh;
- loff_t f_pos = UDF_I_EXT0OFFS(inode) >> 2;
- loff_t size = (UDF_I_EXT0OFFS(inode) + inode->i_size) >> 2;
- struct FileIdentDesc cfi, *sfi, *dfi;
-
- sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
- sfibh.sbh = sfibh.ebh = sbh;
- dfibh.soffset = dfibh.eoffset = 0;
- dfibh.sbh = dfibh.ebh = dbh;
- while ( (f_pos < size) )
- {
- sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL);
- if (!sfi)
- {
- udf_release_data(sbh);
- udf_release_data(dbh);
- return NULL;
- }
- sfi->descTag.tagLocation = *block;
- dfibh.soffset = dfibh.eoffset;
- dfibh.eoffset += (sfibh.eoffset - sfibh.soffset);
- dfi = (struct FileIdentDesc *)(dbh->b_data + dfibh.soffset);
- if (udf_write_fi(sfi, dfi, &dfibh, sfi->impUse,
- sfi->fileIdent + sfi->lengthOfImpUse))
- {
- udf_release_data(sbh);
- udf_release_data(dbh);
- return NULL;
- }
- }
- }
- else
- {
- memcpy(dbh->b_data, sbh->b_data + udf_file_entry_alloc_offset(inode),
- UDF_I_LENALLOC(inode));
- }
- mark_buffer_dirty(dbh, 1);
+ block_write_full_page(filp->f_dentry, page);
+ UnlockPage(page);
+ page_cache_release(page);
- memset(sbh->b_data + udf_file_entry_alloc_offset(inode),
- 0, UDF_I_LENALLOC(inode));
+ mark_inode_dirty(inode);
+ inode->i_version ++;
+ inode->i_op = &udf_file_inode_operations;
+ filp->f_op = inode->i_op->default_file_ops;
+}
- memset(&newad, 0x00, sizeof(long_ad));
- newad.extLength = UDF_I_EXT0LEN(inode) = inode->i_size;
- newad.extLocation.logicalBlockNum = *block;
- newad.extLocation.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
- UDF_I_EXT0LOC(inode) = newad.extLocation;
- /* UniqueID stuff */
+struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err)
+{
+ long_ad newad;
+ int newblock;
+ struct buffer_head *sbh = NULL, *dbh = NULL;
- memcpy(sbh->b_data + udf_file_entry_alloc_offset(inode),
- &newad, sizeof(newad));
+ struct udf_fileident_bh sfibh, dfibh;
+ loff_t f_pos = udf_ext0_offset(inode) >> 2;
+ int size = (udf_ext0_offset(inode) + inode->i_size) >> 2;
+ struct FileIdentDesc cfi, *sfi, *dfi;
- UDF_I_LENALLOC(inode) = sizeof(newad);
- UDF_I_EXT0OFFS(inode) = 0;
+ if (!inode->i_size)
+ {
UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
- inode->i_blocks += inode->i_sb->s_blocksize / 512;
- udf_release_data(sbh);
mark_inode_dirty(inode);
- inode->i_version ++;
- if (inode->i_op == &udf_file_inode_operations_adinicb)
- inode->i_op = &udf_file_inode_operations;
- return dbh;
+ return NULL;
}
- else
+
+ /* alloc block, and copy data to it */
+ *block = udf_alloc_block(inode,
+ UDF_I_LOCATION(inode).partitionReferenceNum,
+ UDF_I_LOCATION(inode).logicalBlockNum, err);
+
+ if (!(*block))
+ return NULL;
+ newblock = udf_get_pblock(inode->i_sb, *block,
+ UDF_I_LOCATION(inode).partitionReferenceNum, 0);
+ if (!newblock)
return NULL;
+ sbh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize);
+ if (!sbh)
+ return NULL;
+ dbh = udf_tread(inode->i_sb, newblock, inode->i_sb->s_blocksize);
+ if (!dbh)
+ return NULL;
+
+ sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
+ sfibh.sbh = sfibh.ebh = sbh;
+ dfibh.soffset = dfibh.eoffset = 0;
+ dfibh.sbh = dfibh.ebh = dbh;
+ while ( (f_pos < size) )
+ {
+ sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL);
+ if (!sfi)
+ {
+ udf_release_data(sbh);
+ udf_release_data(dbh);
+ return NULL;
+ }
+ sfi->descTag.tagLocation = *block;
+ dfibh.soffset = dfibh.eoffset;
+ dfibh.eoffset += (sfibh.eoffset - sfibh.soffset);
+ dfi = (struct FileIdentDesc *)(dbh->b_data + dfibh.soffset);
+ if (udf_write_fi(sfi, dfi, &dfibh, sfi->impUse,
+ sfi->fileIdent + sfi->lengthOfImpUse))
+ {
+ udf_release_data(sbh);
+ udf_release_data(dbh);
+ return NULL;
+ }
+ }
+ mark_buffer_dirty(dbh, 1);
+
+ memset(sbh->b_data + udf_file_entry_alloc_offset(inode),
+ 0, UDF_I_LENALLOC(inode));
+
+ memset(&newad, 0x00, sizeof(long_ad));
+ newad.extLength = inode->i_size;
+ newad.extLocation.logicalBlockNum = *block;
+ newad.extLocation.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
+ /* UniqueID stuff */
+
+ memcpy(sbh->b_data + udf_file_entry_alloc_offset(inode),
+ &newad, sizeof(newad));
+
+ UDF_I_LENALLOC(inode) = sizeof(newad);
+ UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
+ inode->i_blocks = inode->i_sb->s_blocksize / 512;
+ mark_buffer_dirty(sbh, 1);
+ udf_release_data(sbh);
+ mark_inode_dirty(inode);
+ inode->i_version ++;
+ return dbh;
}
struct buffer_head * udf_getblk(struct inode * inode, long block,
@@ -282,6 +267,8 @@ struct buffer_head * udf_getblk(struct inode * inode, long block,
bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->s_blocksize);
if (buffer_new(&dummy))
{
+ if (!buffer_uptodate(bh))
+ wait_on_buffer(bh);
memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
mark_buffer_uptodate(bh, 1);
mark_buffer_dirty(bh, 1);
@@ -310,6 +297,8 @@ int udf_get_block(struct inode *inode, long block, struct buffer_head *bh_result
}
err = -EIO;
+ new = 0;
+ bh = NULL;
lock_kernel();
@@ -479,7 +468,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
}
/* if the current extent is not recorded but allocated, get the
- block in the extent corresponding to the requested block */
+ block in the extent corresponding to the requested block */
if ((laarr[c].extLength >> 30) == EXTENT_NOT_RECORDED_ALLOCATED)
newblocknum = laarr[c].extLocation.logicalBlockNum + offset;
else /* otherwise, allocate a new block */
@@ -522,12 +511,6 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
udf_release_data(pbh);
- if (pextoffset == udf_file_entry_alloc_offset(inode))
- {
- UDF_I_EXT0LEN(inode) = laarr[0].extLength;
- UDF_I_EXT0LOC(inode) = laarr[0].extLocation;
- }
-
if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum,
UDF_I_LOCATION(inode).partitionReferenceNum, 0)))
{
@@ -541,11 +524,9 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
inode->i_ctime = CURRENT_TIME;
UDF_I_UCTIME(inode) = CURRENT_UTIME;
inode->i_blocks += inode->i_sb->s_blocksize / 512;
-#if 0
- if (IS_SYNC(inode) || UDF_I_OSYNC(inode))
+ if (IS_SYNC(inode))
udf_sync_inode(inode);
else
-#endif
mark_inode_dirty(inode);
return result;
}
@@ -830,9 +811,16 @@ struct buffer_head * udf_bread(struct inode * inode, int block,
*
* 12/19/98 dgb Updated to fix size problems.
*/
+
void
udf_read_inode(struct inode *inode)
{
+ memset(&UDF_I_LOCATION(inode), 0xFF, sizeof(lb_addr));
+}
+
+void
+__udf_read_inode(struct inode *inode)
+{
struct buffer_head *bh = NULL;
struct FileEntry *fe;
Uint16 ident;
@@ -851,17 +839,9 @@ udf_read_inode(struct inode *inode)
* i_op = NULL;
*/
- inode->i_blksize = inode->i_sb->s_blocksize;
+ inode->i_blksize = PAGE_SIZE;
inode->i_version = 1;
- UDF_I_EXT0LEN(inode)=0;
- UDF_I_EXT0LOC(inode).logicalBlockNum = 0xFFFFFFFF;
- UDF_I_EXT0LOC(inode).partitionReferenceNum = 0xFFFF;
- UDF_I_EXT0OFFS(inode)=0;
- UDF_I_ALLOCTYPE(inode)=0;
-
- memcpy(&UDF_I_LOCATION(inode), &UDF_SB_LOCATION(inode->i_sb), sizeof(lb_addr));
-
bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident);
if (!bh)
@@ -904,11 +884,11 @@ udf_read_inode(struct inode *inode)
if (ident == TID_FILE_ENTRY ||
ident == TID_EXTENDED_FILE_ENTRY)
{
- memcpy(&UDF_SB_LOCATION(inode->i_sb), &loc, sizeof(lb_addr));
+ memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(lb_addr));
udf_release_data(bh);
udf_release_data(ibh);
udf_release_data(nbh);
- udf_read_inode(inode);
+ __udf_read_inode(inode);
return;
}
else
@@ -957,11 +937,11 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
else /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */
UDF_I_STRAT4096(inode) = 1;
- inode->i_uid = udf_convert_uid(le32_to_cpu(fe->uid));
- if ( !inode->i_uid ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
+ inode->i_uid = le32_to_cpu(fe->uid);
+ if ( inode->i_uid == -1 ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
- inode->i_gid = udf_convert_gid(le32_to_cpu(fe->gid));
- if ( !inode->i_gid ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
+ inode->i_gid = le32_to_cpu(fe->gid);
+ if ( inode->i_gid == -1 ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
if (!inode->i_nlink)
@@ -976,12 +956,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
inode->i_mode = udf_convert_permissions(fe);
inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask;
-#ifdef UDF_PREALLOCATE
-#if 0
- UDF_I_PREALLOC_BLOCK(inode) = 0;
- UDF_I_PREALLOC_COUNT(inode) = 0;
-#endif
-#endif
UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
@@ -1074,58 +1048,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
alen = offset + UDF_I_LENALLOC(inode);
}
- switch (UDF_I_ALLOCTYPE(inode))
- {
- case ICB_FLAG_AD_SHORT:
- {
- short_ad * sa;
-
- sa = udf_get_fileshortad(fe, alen, &offset, 1);
- if (sa)
- {
- UDF_I_EXT0LEN(inode) = le32_to_cpu(sa->extLength);
- UDF_I_EXT0LOC(inode).logicalBlockNum = le32_to_cpu(sa->extPosition);
- UDF_I_EXT0LOC(inode).partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
- }
- break;
- }
- case ICB_FLAG_AD_LONG:
- {
- long_ad * la;
-
- la = udf_get_filelongad(fe, alen, &offset, 1);
- if (la)
- {
- UDF_I_EXT0LEN(inode) = le32_to_cpu(la->extLength);
- UDF_I_EXT0LOC(inode).logicalBlockNum = le32_to_cpu(la->extLocation.logicalBlockNum);
- UDF_I_EXT0LOC(inode).partitionReferenceNum = le16_to_cpu(la->extLocation.partitionReferenceNum);
- }
- break;
- }
- case ICB_FLAG_AD_EXTENDED:
- {
- extent_ad * ext;
-
- ext = udf_get_fileextent(fe, alen, &offset);
- if ( (ext) && (ext->extLength) )
- {
- UDF_I_EXT0LEN(inode) = le32_to_cpu(ext->extLength);
-#if 0
- UDF_I_EXT0LOC(inode) = ext->extLocation;
-#endif
- }
- break;
- }
- case ICB_FLAG_AD_IN_ICB: /* short directories */
- {
- UDF_I_EXT0LEN(inode) = le32_to_cpu(fe->lengthAllocDescs);
- UDF_I_EXT0LOC(inode) = UDF_I_LOCATION(inode);
- UDF_I_EXT0OFFS(inode) = sizeof(struct FileEntry) +
- le32_to_cpu(fe->lengthExtendedAttr);
- break;
- }
- } /* end switch ad_type */
-
switch (fe->icbTag.fileType)
{
case FILE_TYPE_DIRECTORY:
@@ -1162,7 +1084,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
}
case FILE_TYPE_SYMLINK:
{
- /* untested! */
inode->i_op = &udf_symlink_inode_operations;
inode->i_mode = S_IFLNK|S_IRWXUGO;
break;
@@ -1184,7 +1105,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
if (dsea)
{
- init_special_inode(inode, inode->i_mode,
+ init_special_inode(inode, inode->i_mode,
((le32_to_cpu(dsea->majorDeviceIdent)) << 8) |
(le32_to_cpu(dsea->minorDeviceIdent) & 0xFF));
/* Developer ID ??? */
@@ -1440,19 +1361,11 @@ udf_iget(struct super_block *sb, lb_addr ino)
block = udf_get_lb_pblock(sb, ino, 0);
- down(&read_semaphore); /* serialize access to UDF_SB_LOCATION() */
- /* This is really icky.. should fix -- blf */
-
- /* put the location where udf_read_inode can find it */
- memcpy(&UDF_SB_LOCATION(sb), &ino, sizeof(lb_addr));
-
/* Get the inode */
inode = iget(sb, block);
/* calls udf_read_inode() ! */
- up(&read_semaphore);
-
if (!inode)
{
printk(KERN_ERR "udf: iget() failed\n");
@@ -1463,6 +1376,12 @@ udf_iget(struct super_block *sb, lb_addr ino)
iput(inode);
return NULL;
}
+ else if (UDF_I_LOCATION(inode).logicalBlockNum == 0xFFFFFFFF &&
+ UDF_I_LOCATION(inode).partitionReferenceNum == 0xFFFF)
+ {
+ memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(lb_addr));
+ __udf_read_inode(inode);
+ }
if ( ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum) )
{
@@ -1732,6 +1651,14 @@ int udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
}
break;
}
+ case ICB_FLAG_AD_IN_ICB:
+ {
+ *bloc = *eloc = UDF_I_LOCATION(inode);
+ *elen = UDF_I_LENALLOC(inode);
+ *extoffset = udf_file_entry_alloc_offset(inode);
+ etype = EXTENT_RECORDED_ALLOCATED;
+ break;
+ }
default:
{
udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode));
@@ -1741,7 +1668,8 @@ int udf_next_aext(struct inode *inode, lb_addr *bloc, int *extoffset,
if (*elen)
return etype;
- udf_debug("Empty Extent!\n");
+ udf_debug("Empty Extent, inode=%ld, alloctype=%d, elen=%d, etype=%d, extoffset=%d\n",
+ inode->i_ino, UDF_I_ALLOCTYPE(inode), *elen, etype, *extoffset);
if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
*extoffset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
@@ -1974,26 +1902,22 @@ int inode_bmap(struct inode *inode, int block, lb_addr *bloc, Uint32 *extoffset,
return -1;
}
+ *extoffset = udf_file_entry_alloc_offset(inode);
+ *elen = 0;
b_off = block << inode->i_sb->s_blocksize_bits;
*bloc = UDF_I_LOCATION(inode);
- *eloc = UDF_I_EXT0LOC(inode);
- *elen = UDF_I_EXT0LEN(inode) & UDF_EXTENT_LENGTH_MASK;
- *extoffset = udf_file_entry_alloc_offset(inode);
- if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
- *extoffset += sizeof(short_ad);
- else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
- *extoffset += sizeof(long_ad);
- etype = UDF_I_EXT0LEN(inode) >> 30;
- while (lbcount + *elen <= b_off)
+ do
{
lbcount += *elen;
+
if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1)
{
*offset = (b_off - lbcount) >> inode->i_sb->s_blocksize_bits;
return -1;
}
- }
+ } while (lbcount + *elen <= b_off);
+
*offset = (b_off - lbcount) >> inode->i_sb->s_blocksize_bits;
return etype;
@@ -2029,3 +1953,58 @@ long udf_block_map(struct inode *inode, long block)
unlock_kernel();
return ret;
}
+
+int udf_readpage_adinicb (struct dentry *dentry, struct page * page)
+{
+ struct inode *inode = dentry->d_inode;
+
+ struct buffer_head *bh;
+ int block;
+ unsigned long kaddr = 0;
+
+ if (!PageLocked(page))
+ PAGE_BUG(page);
+
+ kaddr = kmap(page);
+ memset((char *)kaddr, 0, PAGE_CACHE_SIZE);
+ block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
+ bh = getblk (inode->i_dev, block, inode->i_sb->s_blocksize);
+ ll_rw_block (READ, 1, &bh);
+ wait_on_buffer(bh);
+ memcpy((char *)kaddr, bh->b_data + udf_ext0_offset(inode),
+ inode->i_size);
+ brelse(bh);
+ SetPageUptodate(page);
+ kunmap(page);
+ UnlockPage(page);
+ return 0;
+}
+
+int udf_writepage_adinicb (struct dentry *dentry, struct page *page)
+{
+ struct inode *inode = dentry->d_inode;
+
+ struct buffer_head *bh;
+ int block;
+ unsigned long kaddr = 0;
+
+ if (!PageLocked(page))
+ BUG();
+
+ kaddr = kmap(page);
+ block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
+ bh = getblk (inode->i_dev, block, inode->i_sb->s_blocksize);
+ if (!buffer_uptodate(bh))
+ {
+ ll_rw_block (READ, 1, &bh);
+ wait_on_buffer(bh);
+ }
+ memcpy(bh->b_data + udf_ext0_offset(inode), (char *)kaddr,
+ inode->i_size);
+ ll_rw_block (WRITE, 1, &bh);
+ wait_on_buffer(bh);
+ brelse(bh);
+ SetPageUptodate(page);
+ kunmap(page);
+ return 0;
+}
diff --git a/fs/udf/lowlevel.c b/fs/udf/lowlevel.c
index dee98ad71..d8993254e 100644
--- a/fs/udf/lowlevel.c
+++ b/fs/udf/lowlevel.c
@@ -15,7 +15,7 @@
* ftp://prep.ai.mit.edu/pub/gnu/GPL
* Each contributing author retains all rights to their own work.
*
- * (C) 1999 Ben Fennema
+ * (C) 1999-2000 Ben Fennema
*
* HISTORY
*
@@ -47,16 +47,21 @@ udf_get_last_session(struct super_block *sb)
vol_desc_start=0;
ms_info.addr_format=CDROM_LBA;
- i=ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info);
+ i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info);
+
#define WE_OBEY_THE_WRITTEN_STANDARDS 1
- if (i == 0) {
+
+ if (i == 0)
+ {
udf_debug("XA disk: %s, vol_desc_start=%d\n",
(ms_info.xa_flag ? "yes" : "no"), ms_info.addr.lba);
#if WE_OBEY_THE_WRITTEN_STANDARDS
if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */
#endif
vol_desc_start = ms_info.addr.lba;
- } else {
+ }
+ else
+ {
udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i);
}
return vol_desc_start;
@@ -86,17 +91,20 @@ udf_get_last_block(struct super_block *sb, int *flags)
lblock = 0;
ret = ioctl_by_bdev(bdev, BLKGETSIZE, (unsigned long) &lblock);
- if (!ret && lblock != 0x7FFFFFFF) {
- /* Hard Disk */
+ if (!ret && lblock != 0x7FFFFFFF) /* Hard Disk */
+ {
if (mult)
lblock *= mult;
else if (div)
lblock /= div;
- } else {
- /* CDROM */
+ }
+ else /* CDROM */
+ {
ret = ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock);
}
+
if (!ret && lblock)
return lblock - 1;
- return 0;
+ else
+ return 0;
}
diff --git a/fs/udf/misc.c b/fs/udf/misc.c
index 0b2068015..834727ae8 100644
--- a/fs/udf/misc.c
+++ b/fs/udf/misc.c
@@ -16,8 +16,8 @@
* Each contributing author retains all rights to their own work.
*
* (C) 1998 Dave Boynton
- * (C) 1998-1999 Ben Fennema
- * (C) 1999 Stelias Computing Inc
+ * (C) 1998-2000 Ben Fennema
+ * (C) 1999-2000 Stelias Computing Inc
*
* HISTORY
*
@@ -64,20 +64,6 @@ udf64_high32(Uint64 indat)
return indat >> 32;
}
-uid_t udf_convert_uid(int uidin)
-{
- if ( uidin == -1 )
- return 0;
- return uidin;
-}
-
-gid_t udf_convert_gid(int gidin)
-{
- if ( gidin == -1 )
- return 0;
- return gidin;
-}
-
#if defined(__linux__) && defined(__KERNEL__)
extern struct buffer_head *
@@ -138,7 +124,6 @@ udf_add_extendedattr(struct inode * inode, Uint32 size, Uint32 type,
if (UDF_I_LENALLOC(inode))
{
memmove(&ad[size], ad, UDF_I_LENALLOC(inode));
- UDF_I_EXT0OFFS(inode) += size;
}
if (UDF_I_LENEATTR(inode))
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index ebf344832..1f54833e4 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -15,14 +15,13 @@
* ftp://prep.ai.mit.edu/pub/gnu/GPL
* Each contributing author retains all rights to their own work.
*
- * (C) 1998-1999 Ben Fennema
- * (C) 1999 Stelias Computing Inc
+ * (C) 1998-2000 Ben Fennema
+ * (C) 1999-2000 Stelias Computing Inc
*
* HISTORY
*
- * 12/12/98 blf Created. Split out the lookup code from dir.c
- * 04/19/99 blf link, mknod, symlink support
- *
+ * 12/12/98 blf Created. Split out the lookup code from dir.c
+ * 04/19/99 blf link, mknod, symlink support
*/
#include "udfdecl.h"
@@ -153,7 +152,7 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
char *nameptr;
Uint8 lfi;
Uint16 liu;
- loff_t size = (UDF_I_EXT0OFFS(dir) + dir->i_size) >> 2;
+ loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
lb_addr bloc, eloc;
Uint32 extoffset, elen, offset;
struct buffer_head *bh = NULL;
@@ -161,7 +160,7 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
if (!dir)
return NULL;
- f_pos = (UDF_I_EXT0OFFS(dir) >> 2);
+ f_pos = (udf_ext0_offset(dir) >> 2);
fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
@@ -297,6 +296,9 @@ udf_lookup(struct inode *dir, struct dentry *dentry)
struct FileIdentDesc cfi, *fi;
struct udf_fileident_bh fibh;
+ if (dentry->d_name.len > UDF_NAME_LEN)
+ return ERR_PTR(-ENAMETOOLONG);
+
#ifdef UDF_RECOVERY
/* temporary shorthand for specifying files by inode number */
if (!strncmp(dentry->d_name.name, ".B=", 3) )
@@ -336,7 +338,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
loff_t f_pos;
int flen;
char *nameptr;
- loff_t size = (UDF_I_EXT0OFFS(dir) + dir->i_size) >> 2;
+ loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
int nfidlen;
Uint8 lfi;
Uint16 liu;
@@ -370,7 +372,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
nfidlen = (sizeof(struct FileIdentDesc) + 0 + namelen + 3) & ~3;
- f_pos = (UDF_I_EXT0OFFS(dir) >> 2);
+ f_pos = (udf_ext0_offset(dir) >> 2);
fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
@@ -473,13 +475,13 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
{
udf_release_data(bh);
bh = NULL;
- fibh->soffset -= UDF_I_EXT0OFFS(dir);
- fibh->eoffset -= UDF_I_EXT0OFFS(dir);
- f_pos -= (UDF_I_EXT0OFFS(dir) >> 2);
+ fibh->soffset -= udf_ext0_offset(dir);
+ fibh->eoffset -= udf_ext0_offset(dir);
+ f_pos -= (udf_ext0_offset(dir) >> 2);
if (fibh->sbh != fibh->ebh)
udf_release_data(fibh->ebh);
udf_release_data(fibh->sbh);
- if (!(fibh->sbh = fibh->ebh = udf_expand_adinicb(dir, &block, 1, err)))
+ if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err)))
return NULL;
bloc = UDF_I_LOCATION(dir);
extoffset = udf_file_entry_alloc_offset(dir);
@@ -640,7 +642,7 @@ int udf_create(struct inode *dir, struct dentry *dentry, int mode)
if (!inode)
return err;
- inode->i_op = &udf_file_inode_operations;
+ inode->i_op = &udf_file_inode_operations_adinicb;
inode->i_mode = mode;
mark_inode_dirty(inode);
@@ -682,6 +684,7 @@ int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev)
goto out;
inode->i_uid = current->fsuid;
+ init_special_inode(inode, mode, rdev);
inode->i_mode = mode;
inode->i_op = NULL;
if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err)))
@@ -702,7 +705,6 @@ int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev)
mark_inode_dirty(dir);
dir->i_version = ++event;
}
- init_special_inode(inode, mode, rdev);
mark_inode_dirty(inode);
if (fibh.sbh != fibh.ebh)
@@ -734,19 +736,9 @@ int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
inode->i_op = &udf_dir_inode_operations;
inode->i_size = (sizeof(struct FileIdentDesc) + 3) & ~3;
- if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
- {
- UDF_I_EXT0LEN(inode) = inode->i_size;
- UDF_I_EXT0LOC(inode) = UDF_I_LOCATION(inode);
- UDF_I_LENALLOC(inode) = inode->i_size;
- loc = UDF_I_LOCATION(inode).logicalBlockNum;
- fibh.sbh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize);
- }
- else
- {
- fibh.sbh = udf_bread (inode, 0, 1, &err);
- loc = UDF_I_EXT0LOC(inode).logicalBlockNum;
- }
+ UDF_I_LENALLOC(inode) = inode->i_size;
+ loc = UDF_I_LOCATION(inode).logicalBlockNum;
+ fibh.sbh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize);
if (!fibh.sbh)
{
@@ -809,13 +801,13 @@ static int empty_dir(struct inode *dir)
struct FileIdentDesc *fi, cfi;
struct udf_fileident_bh fibh;
loff_t f_pos;
- loff_t size = (UDF_I_EXT0OFFS(dir) + dir->i_size) >> 2;
+ loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
int block;
lb_addr bloc, eloc;
Uint32 extoffset, elen, offset;
struct buffer_head *bh = NULL;
- f_pos = (UDF_I_EXT0OFFS(dir) >> 2);
+ f_pos = (udf_ext0_offset(dir) >> 2);
fibh.soffset = fibh.eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
@@ -1170,7 +1162,7 @@ int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
}
if (S_ISDIR(old_inode->i_mode))
{
- Uint32 offset = UDF_I_EXT0OFFS(old_inode);
+ Uint32 offset = udf_ext0_offset(old_inode);
if (new_inode)
{
@@ -1203,6 +1195,14 @@ int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
new_dir->i_version = ++event;
/*
+ * Like most other Unix systems, set the ctime for inodes on a
+ * rename.
+ */
+ old_inode->i_ctime = CURRENT_TIME;
+ UDF_I_UCTIME(old_inode) = CURRENT_UTIME;
+ mark_inode_dirty(old_inode);
+
+ /*
* ok, that's it
*/
ncfi.fileVersionNum = ocfi.fileVersionNum;
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
index ecfabb849..658d2220e 100644
--- a/fs/udf/partition.c
+++ b/fs/udf/partition.c
@@ -30,161 +30,204 @@
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/udf_fs.h>
+#include <linux/malloc.h>
-extern Uint32 udf_get_pblock(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
+inline Uint32 udf_get_pblock(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
{
- Uint16 ident;
-
if (partition >= UDF_SB_NUMPARTS(sb))
{
udf_debug("block=%d, partition=%d, offset=%d: invalid partition\n",
block, partition, offset);
return 0xFFFFFFFF;
}
- switch (UDF_SB_PARTTYPE(sb, partition))
+ if (UDF_SB_PARTFUNC(sb, partition))
+ return UDF_SB_PARTFUNC(sb, partition)(sb, block, partition, offset);
+ else
+ return UDF_SB_PARTROOT(sb, partition) + block + offset;
+}
+
+Uint32 udf_get_pblock_virt15(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
+{
+ struct buffer_head *bh = NULL;
+ Uint32 newblock;
+ Uint32 index;
+ Uint32 loc;
+
+ index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(Uint32);
+
+ if (block > UDF_SB_TYPEVIRT(sb,partition).s_num_entries)
{
- case UDF_TYPE1_MAP15:
- {
- return UDF_SB_PARTROOT(sb, partition) + block + offset;
- }
- case UDF_VIRTUAL_MAP15:
- case UDF_VIRTUAL_MAP20:
- {
- struct buffer_head *bh = NULL;
- Uint32 newblock;
- Uint32 index;
- Uint32 loc;
+ udf_debug("Trying to access block beyond end of VAT (%d max %d)\n",
+ block, UDF_SB_TYPEVIRT(sb,partition).s_num_entries);
+ return 0xFFFFFFFF;
+ }
- index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(Uint32);
+ if (block >= index)
+ {
+ block -= index;
+ newblock = 1 + (block / (sb->s_blocksize / sizeof(Uint32)));
+ index = block % (sb->s_blocksize / sizeof(Uint32));
+ }
+ else
+ {
+ newblock = 0;
+ index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(Uint32) + block;
+ }
+ loc = udf_locked_block_map(UDF_SB_VAT(sb), newblock);
- if (block > UDF_SB_TYPEVIRT(sb,partition).s_num_entries)
- {
- udf_debug("Trying to access block beyond end of VAT (%d max %d)\n",
- block, UDF_SB_TYPEVIRT(sb,partition).s_num_entries);
- return 0xFFFFFFFF;
- }
+ if (!(bh = bread(sb->s_dev, loc, sb->s_blocksize)))
+ {
+ udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%d,%d) VAT: %d[%d]\n",
+ sb, block, partition, loc, index);
+ return 0xFFFFFFFF;
+ }
- if (block >= index)
- {
- block -= index;
- newblock = 1 + (block / (sb->s_blocksize / sizeof(Uint32)));
- index = block % (sb->s_blocksize / sizeof(Uint32));
- }
- else
- {
- newblock = 0;
- index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(Uint32) + block;
- }
+ loc = le32_to_cpu(((Uint32 *)bh->b_data)[index]);
- loc = udf_locked_block_map(UDF_SB_VAT(sb), newblock);
+ udf_release_data(bh);
- if (!(bh = bread(sb->s_dev, loc, sb->s_blocksize)))
- {
- udf_debug("get_pblock(UDF_VIRTUAL_MAP:%p,%d,%d) VAT: %d[%d]\n",
- sb, block, partition, loc, index);
- return 0xFFFFFFFF;
- }
+ if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition)
+ {
+ udf_debug("recursive call to udf_get_pblock!\n");
+ return 0xFFFFFFFF;
+ }
- loc = le32_to_cpu(((Uint32 *)bh->b_data)[index]);
+ return udf_get_pblock(sb, loc, UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum, offset);
+}
- udf_release_data(bh);
+inline Uint32 udf_get_pblock_virt20(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
+{
+ return udf_get_pblock_virt15(sb, block, partition, offset);
+}
- if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition)
- {
- udf_debug("recursive call to udf_get_pblock!\n");
- return 0xFFFFFFFF;
- }
+Uint32 udf_get_pblock_spar15(struct super_block *sb, Uint32 block, Uint16 partition, Uint32 offset)
+{
+ Uint32 packet = (block + offset) >> UDF_SB_TYPESPAR(sb,partition).s_spar_pshift;
+ Uint32 index = 0;
- return udf_get_pblock(sb, loc, UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum, offset);
- }
- case UDF_SPARABLE_MAP15:
- {
- Uint32 newblock = UDF_SB_PARTROOT(sb, partition) + block + offset;
- Uint32 spartable = UDF_SB_TYPESPAR(sb, partition).s_spar_loc;
- Uint32 plength = UDF_SB_TYPESPAR(sb,partition).s_spar_plen;
- Uint32 packet = (block + offset) & (~(plength-1));
- struct buffer_head *bh = NULL;
- struct SparingTable *st;
- SparingEntry *se;
+ if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 8)
+ index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap8[packet];
+ else if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 16)
+ index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap16[packet];
+ else if (UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize == 32)
+ index = UDF_SB_TYPESPAR(sb,partition).s_spar_remap.s_spar_remap32[packet];
- bh = udf_read_tagged(sb, spartable, spartable, &ident);
+ if (index == ((1 << UDF_SB_TYPESPAR(sb,partition).s_spar_indexsize)-1))
+ return UDF_SB_PARTROOT(sb,partition) + block + offset;
- if (!bh)
- {
- printk(KERN_ERR "udf: udf_read_tagged(%p,%d,%d)\n",
- sb, spartable, spartable);
- return 0xFFFFFFFF;
- }
+ packet = UDF_SB_TYPESPAR(sb,partition).s_spar_map[index];
+ return packet + ((block + offset) & ((1 << UDF_SB_TYPESPAR(sb,partition).s_spar_pshift)-1));
+}
+
+void udf_fill_spartable(struct super_block *sb, struct udf_sparing_data *sdata, int partlen)
+{
+ Uint16 ident;
+ Uint32 spartable;
+ int i;
+ struct buffer_head *bh;
+ struct SparingTable *st;
+
+ for (i=0; i<4; i++)
+ {
+ if (!(spartable = sdata->s_spar_loc[i]))
+ continue;
+
+ bh = udf_read_tagged(sb, spartable, spartable, &ident);
+
+ if (!bh)
+ {
+ sdata->s_spar_loc[i] = 0;
+ continue;
+ }
+ if (ident == 0)
+ {
st = (struct SparingTable *)bh->b_data;
- if (ident == 0)
+ if (!strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)))
{
- if (!strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)))
- {
- Uint16 rtl = le16_to_cpu(st->reallocationTableLen);
- Uint16 index;
+ SparingEntry *se;
+ Uint16 rtl = le16_to_cpu(st->reallocationTableLen);
+ int index;
- /* If the sparing table span multiple blocks, find out which block we are on */
-
- se = &(st->mapEntry[0]);
+ if (!sdata->s_spar_map)
+ {
+ int num = 1, mapsize;
+ sdata->s_spar_indexsize = 8;
+ while (rtl*sizeof(Uint32) >= (1 << sdata->s_spar_indexsize))
+ {
+ num ++;
+ sdata->s_spar_indexsize <<= 1;
+ }
+ mapsize = (rtl * sizeof(Uint32)) +
+ ((partlen/(1 << sdata->s_spar_pshift)) * sizeof(Uint8) * num);
+ sdata->s_spar_map = kmalloc(mapsize, GFP_KERNEL);
+ sdata->s_spar_remap.s_spar_remap32 = &sdata->s_spar_map[rtl];
+ memset(sdata->s_spar_map, 0xFF, mapsize);
+ }
- if (rtl * sizeof(SparingEntry) + sizeof(struct SparingTable) > sb->s_blocksize)
+ index = sizeof(struct SparingTable);
+ for (i=0; i<rtl; i++)
+ {
+ if (index > sb->s_blocksize)
{
- index = (sb->s_blocksize - sizeof(struct SparingTable)) / sizeof(SparingEntry);
- if (le32_to_cpu(se[index-1].origLocation) == packet)
+ udf_release_data(bh);
+ bh = udf_tread(sb, ++spartable, sb->s_blocksize);
+ if (!bh)
{
- udf_release_data(bh);
- return le32_to_cpu(se[index].mappedLocation) | (newblock & (plength-1));
+ sdata->s_spar_loc[i] = 0;
+ continue;
}
- else if (le32_to_cpu(se[index-1].origLocation) < packet)
+ index = 0;
+ }
+ se = (SparingEntry *)&(bh->b_data[index]);
+ index += sizeof(SparingEntry);
+
+ if (sdata->s_spar_map[i] == 0xFFFFFFFF)
+ sdata->s_spar_map[i] = le32_to_cpu(se->mappedLocation);
+ else if (sdata->s_spar_map[i] != le32_to_cpu(se->mappedLocation))
+ {
+ udf_debug("Found conflicting Sparing Data (%d vs %d for entry %d)\n",
+ sdata->s_spar_map[i], le32_to_cpu(se->mappedLocation), i);
+ }
+
+ if (le32_to_cpu(se->origLocation) < 0xFFFFFFF0)
+ {
+ int packet = le32_to_cpu(se->origLocation) >> sdata->s_spar_pshift;
+ if (sdata->s_spar_indexsize == 8)
{
- do
+ if (sdata->s_spar_remap.s_spar_remap8[packet] == 0xFF)
+ sdata->s_spar_remap.s_spar_remap8[packet] = i;
+ else if (sdata->s_spar_remap.s_spar_remap8[packet] != i)
{
- udf_release_data(bh);
- bh = udf_tread(sb, spartable, sb->s_blocksize);
- if (!bh)
- return 0xFFFFFFFF;
- se = (SparingEntry *)bh->b_data;
- spartable ++;
- rtl -= index;
- index = sb->s_blocksize / sizeof(SparingEntry);
-
- if (le32_to_cpu(se[index].origLocation) == packet)
- {
- udf_release_data(bh);
- return le32_to_cpu(se[index].mappedLocation) | (newblock & (plength-1));
- }
- } while (rtl * sizeof(SparingEntry) > sb->s_blocksize &&
- le32_to_cpu(se[index-1].origLocation) < packet);
+ udf_debug("Found conflicting Sparing Data (%d vs %d)\n",
+ sdata->s_spar_remap.s_spar_remap8[packet], i);
+ }
}
- }
-
- for (index=0; index<rtl; index++)
- {
- if (le32_to_cpu(se[index].origLocation) == packet)
+ else if (sdata->s_spar_indexsize == 16)
{
- udf_release_data(bh);
- return le32_to_cpu(se[index].mappedLocation) | (newblock & (plength-1));
+ if (sdata->s_spar_remap.s_spar_remap16[packet] == 0xFFFF)
+ sdata->s_spar_remap.s_spar_remap16[packet] = i;
+ else if (sdata->s_spar_remap.s_spar_remap16[packet] != i)
+ {
+ udf_debug("Found conflicting Sparing Data (%d vs %d)\n",
+ sdata->s_spar_remap.s_spar_remap16[packet], i);
+ }
}
- else if (le32_to_cpu(se[index].origLocation) > packet)
+ else if (sdata->s_spar_indexsize == 32)
{
- udf_release_data(bh);
- return newblock;
+ if (sdata->s_spar_remap.s_spar_remap32[packet] == 0xFFFFFFFF)
+ sdata->s_spar_remap.s_spar_remap32[packet] = i;
+ else if (sdata->s_spar_remap.s_spar_remap32[packet] != i)
+ {
+ udf_debug("Found conflicting Sparing Data (%d vs %d)\n",
+ sdata->s_spar_remap.s_spar_remap32[packet], i);
+ }
}
}
-
- udf_release_data(bh);
- return newblock;
}
}
- udf_release_data(bh);
}
+ udf_release_data(bh);
}
- return 0xFFFFFFFF;
-}
-
-extern Uint32 udf_get_lb_pblock(struct super_block *sb, lb_addr loc, Uint32 offset)
-{
- return udf_get_pblock(sb, loc.logicalBlockNum, loc.partitionReferenceNum, offset);
}
diff --git a/fs/udf/super.c b/fs/udf/super.c
index aba702b57..272b9eacb 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -26,7 +26,8 @@
* Each contributing author retains all rights to their own work.
*
* (C) 1998 Dave Boynton
- * (C) 1998-1999 Ben Fennema
+ * (C) 1998-2000 Ben Fennema
+ * (C) 2000 Stelias Computing Inc
*
* HISTORY
*
@@ -91,29 +92,27 @@ static void udf_load_partdesc(struct super_block *, struct buffer_head *);
static void udf_open_lvid(struct super_block *);
static void udf_close_lvid(struct super_block *);
static unsigned int udf_count_free(struct super_block *);
-
-/* version specific functions */
static int udf_statfs(struct super_block *, struct statfs *, int);
/* UDF filesystem type */
static struct file_system_type udf_fstype = {
- "udf", /* name */
+ "udf", /* name */
FS_REQUIRES_DEV, /* fs_flags */
udf_read_super, /* read_super */
- NULL /* next */
+ NULL /* next */
};
/* Superblock operations */
static struct super_operations udf_sb_ops =
{
udf_read_inode, /* read_inode */
-#ifdef CONFIG_UDF_RW
+#if CONFIG_UDF_RW == 1
udf_write_inode, /* write_inode */
#else
NULL, /* write_inode */
#endif
udf_put_inode, /* put_inode */
-#ifdef CONFIG_UDF_RW
+#if CONFIG_UDF_RW == 1
udf_delete_inode, /* delete_inode */
#else
NULL, /* delete_inode */
@@ -130,7 +129,6 @@ static struct super_operations udf_sb_ops =
struct udf_options
{
unsigned char novrs;
- unsigned char utf8;
unsigned int blocksize;
unsigned int session;
unsigned int lastblock;
@@ -143,7 +141,6 @@ struct udf_options
mode_t umask;
gid_t gid;
uid_t uid;
- char *iocharset;
};
#if defined(MODULE)
@@ -194,8 +191,8 @@ int __init init_udf_fs(void)
if ( size < sizeof(struct udf_sb_info) )
{
printk(KERN_ERR "udf: Danger! Kernel was compiled without enough room for udf_sb_info\n");
- printk(KERN_ERR "udf: Kernel has room for %u bytes, udf needs %u\n",
- size, sizeof(struct udf_sb_info));
+ printk(KERN_ERR "udf: Kernel has room for %u bytes, udf needs %lu\n",
+ size, (unsigned long)sizeof(struct udf_sb_info));
return 0;
}
}
@@ -217,8 +214,6 @@ int __init init_udf_fs(void)
* unhide Show otherwise hidden files.
* undelete Show deleted files in lists.
* strict Set strict conformance (unused)
- * utf8 (unused)
- * iocharset (unused)
*
* The remaining are for debugging and disaster recovery:
*
@@ -267,7 +262,6 @@ udf_parse_options(char *options, struct udf_options *uopt)
uopt->volume = 0xFFFFFFFF;
uopt->rootdir = 0xFFFFFFFF;
uopt->fileset = 0xFFFFFFFF;
- uopt->iocharset = NULL;
if (!options)
return 1;
@@ -280,8 +274,6 @@ udf_parse_options(char *options, struct udf_options *uopt)
*(val++) = 0;
if (!strcmp(opt, "novrs") && !val)
uopt->novrs = 1;
- else if (!strcmp(opt, "utf8") && !val)
- uopt->utf8 = 1;
else if (!strcmp(opt, "bs") && val)
uopt->blocksize = simple_strtoul(val, NULL, 0);
else if (!strcmp(opt, "unhide") && !val)
@@ -310,15 +302,6 @@ udf_parse_options(char *options, struct udf_options *uopt)
uopt->fileset = simple_strtoul(val, NULL, 0);
else if (!strcmp(opt, "rootdir") && val)
uopt->rootdir = simple_strtoul(val, NULL, 0);
- else if (!strcmp(opt, "iocharset") && val)
- {
- uopt->iocharset = val;
- while (*val && *val != ',')
- val ++;
- if (val == uopt->iocharset)
- return 0;
- *val = 0;
- }
else if (val)
{
printk(KERN_ERR "udf: bad mount option \"%s=%s\"\n",
@@ -344,7 +327,6 @@ udf_remount_fs(struct super_block *sb, int *flags, char *options)
uopt.uid = UDF_SB(sb)->s_uid ;
uopt.gid = UDF_SB(sb)->s_gid ;
uopt.umask = UDF_SB(sb)->s_umask ;
- uopt.utf8 = UDF_SB(sb)->s_utf8 ;
if ( !udf_parse_options(options, &uopt) )
return -EINVAL;
@@ -353,7 +335,6 @@ udf_remount_fs(struct super_block *sb, int *flags, char *options)
UDF_SB(sb)->s_uid = uopt.uid;
UDF_SB(sb)->s_gid = uopt.gid;
UDF_SB(sb)->s_umask = uopt.umask;
- UDF_SB(sb)->s_utf8 = uopt.utf8;
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
return 0;
@@ -841,6 +822,9 @@ udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
UDF_SB_PARTROOT(sb,i) = le32_to_cpu(p->partitionStartingLocation) + UDF_SB_SESSION(sb);
UDF_SB_PARTMAPS(sb)[i].s_uspace_bitmap = 0xFFFFFFFF;
+ if (UDF_SB_PARTTYPE(sb,i) == UDF_SPARABLE_MAP15)
+ udf_fill_spartable(sb, &UDF_SB_TYPESPAR(sb,i), UDF_SB_PARTLEN(sb,i));
+
if (!strcmp(p->partitionContents.ident, PARTITION_CONTENTS_NSR02) ||
!strcmp(p->partitionContents.ident, PARTITION_CONTENTS_NSR03))
{
@@ -882,7 +866,7 @@ static int
udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, lb_addr *fileset)
{
struct LogicalVolDesc *lvd;
- int i, offset;
+ int i, j, offset;
Uint8 type;
lvd = (struct LogicalVolDesc *)bh->b_data;
@@ -902,6 +886,7 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, lb_addr *fi
UDF_SB_PARTTYPE(sb,i) = UDF_TYPE1_MAP15;
UDF_SB_PARTVSN(sb,i) = le16_to_cpu(gpm1->volSeqNum);
UDF_SB_PARTNUM(sb,i) = le16_to_cpu(gpm1->partitionNum);
+ UDF_SB_PARTFUNC(sb,i) = NULL;
}
else if (type == 2)
{
@@ -909,16 +894,29 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, lb_addr *fi
if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL)))
{
if (le16_to_cpu(((Uint16 *)upm2->partIdent.identSuffix)[0]) == 0x0150)
+ {
UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP15;
+ UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt15;
+ }
else if (le16_to_cpu(((Uint16 *)upm2->partIdent.identSuffix)[0]) == 0x0200)
+ {
UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP20;
+ UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt20;
+ }
}
else if (!strncmp(upm2->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE)))
{
+ int plen;
+
struct SparablePartitionMap *spm = (struct SparablePartitionMap *)&(lvd->partitionMaps[offset]);
UDF_SB_PARTTYPE(sb,i) = UDF_SPARABLE_MAP15;
- UDF_SB_TYPESPAR(sb,i).s_spar_plen = le16_to_cpu(spm->packetLength);
- UDF_SB_TYPESPAR(sb,i).s_spar_loc = le32_to_cpu(spm->locSparingTable[0]);
+ plen = le16_to_cpu(spm->packetLength);
+ UDF_SB_TYPESPAR(sb,i).s_spar_pshift = 0;
+ while (plen >>= 1)
+ UDF_SB_TYPESPAR(sb,i).s_spar_pshift ++;
+ for (j=0; j<spm->numSparingTables; j++)
+ UDF_SB_TYPESPAR(sb,i).s_spar_loc[j] = le32_to_cpu(spm->locSparingTable[j]);
+ UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_spar15;
}
else
{
@@ -1190,7 +1188,7 @@ udf_load_partition(struct super_block *sb, lb_addr *fileset)
if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP15)
{
- UDF_SB_TYPEVIRT(sb,i).s_start_offset = UDF_I_EXT0OFFS(UDF_SB_VAT(sb));
+ UDF_SB_TYPEVIRT(sb,i).s_start_offset = udf_ext0_offset(UDF_SB_VAT(sb));
UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - 36) >> 2;
}
else if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP20)
@@ -1201,8 +1199,8 @@ udf_load_partition(struct super_block *sb, lb_addr *fileset)
pos = udf_block_map(UDF_SB_VAT(sb), 0);
bh = bread(sb->s_dev, pos, sb->s_blocksize);
UDF_SB_TYPEVIRT(sb,i).s_start_offset =
- le16_to_cpu(((struct VirtualAllocationTable20 *)bh->b_data + UDF_I_EXT0OFFS(UDF_SB_VAT(sb)))->lengthHeader) +
- UDF_I_EXT0OFFS(UDF_SB_VAT(sb));
+ le16_to_cpu(((struct VirtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) +
+ udf_ext0_offset(UDF_SB_VAT(sb));
UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size -
UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2;
udf_release_data(bh);
@@ -1218,7 +1216,7 @@ udf_load_partition(struct super_block *sb, lb_addr *fileset)
static void udf_open_lvid(struct super_block *sb)
{
-#ifdef CONFIG_UDF_RW
+#if CONFIG_UDF_RW == 1
if (UDF_SB_LVIDBH(sb))
{
int i;
@@ -1247,7 +1245,7 @@ static void udf_open_lvid(struct super_block *sb)
static void udf_close_lvid(struct super_block *sb)
{
-#ifdef CONFIG_UDF_RW
+#if CONFIG_UDF_RW == 1
if (UDF_SB_LVIDBH(sb) &&
UDF_SB_LVID(sb)->integrityType == INTEGRITY_TYPE_OPEN)
{
@@ -1301,10 +1299,9 @@ udf_read_super(struct super_block *sb, void *options, int silent)
int i;
uopt.flags = 0;
- uopt.uid = 0;
- uopt.gid = 0;
+ uopt.uid = -1;
+ uopt.gid = -1;
uopt.umask = 0;
- uopt.utf8 = 0;
/* Lock the module in memory (if applicable) */
MOD_INC_USE_COUNT;
@@ -1328,7 +1325,6 @@ udf_read_super(struct super_block *sb, void *options, int silent)
UDF_SB(sb)->s_uid = uopt.uid;
UDF_SB(sb)->s_gid = uopt.gid;
UDF_SB(sb)->s_umask = uopt.umask;
- UDF_SB(sb)->s_utf8 = uopt.utf8;
/* Set the block size for all transfers */
if (!udf_set_blocksize(sb, uopt.blocksize))
@@ -1356,20 +1352,6 @@ udf_read_super(struct super_block *sb, void *options, int silent)
goto error_out;
}
- UDF_SB_CHARSET(sb) = NULL;
-
-#ifdef CONFIG_NLS
- if (uopt.utf8 == 0)
- {
- char *p = uopt.iocharset ? uopt.iocharset : "iso8859-1";
- UDF_SB_CHARSET(sb) = load_nls(p);
- if (!UDF_SB_CHARSET(sb))
- if (uopt.iocharset)
- goto error_out;
- UDF_SB_CHARSET(sb) = load_nls_default();
- }
-#endif
-
/* Fill in the rest of the superblock */
sb->s_op = &udf_sb_ops;
sb->dq_op = NULL;
@@ -1405,7 +1387,8 @@ udf_read_super(struct super_block *sb, void *options, int silent)
{
timestamp ts;
udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb), 0);
- udf_info("Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
+ udf_info("UDF %s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
+ UDFFS_VERSION, UDFFS_DATE,
UDF_SB_VOLIDENT(sb), ts.year, ts.month, ts.day, ts.hour, ts.minute,
ts.typeAndTimezone);
}
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
index 63ebb5713..6e5dd233a 100644
--- a/fs/udf/symlink.c
+++ b/fs/udf/symlink.c
@@ -15,7 +15,7 @@
* ftp://prep.ai.mit.edu/pub/gnu/GPL
* Each contributing author retains all rights to their own work.
*
- * (C) 1998-1999 Ben Fennema
+ * (C) 1998-2000 Ben Fennema
* (C) 1999 Stelias Computing Inc
*
* HISTORY
@@ -39,14 +39,17 @@
static void udf_pc_to_char(char *from, int fromlen, char *to)
{
struct PathComponent *pc;
- int elen = 0, len = 0;
+ int elen = 0;
char *p = to;
- while (elen < fromlen) {
+ while (elen < fromlen)
+ {
pc = (struct PathComponent *)(from + elen);
- switch (pc->componentType) {
+ switch (pc->componentType)
+ {
case 1:
- if (pc->lengthComponentIdent == 0) {
+ if (pc->lengthComponentIdent == 0)
+ {
p = to;
*p++ = '/';
}
@@ -61,17 +64,16 @@ static void udf_pc_to_char(char *from, int fromlen, char *to)
/* that would be . - just ignore */
break;
case 5:
- memcpy(p+len, pc->componentIdent,
- pc->lengthComponentIdent);
+ memcpy(p, pc->componentIdent, pc->lengthComponentIdent);
p += pc->lengthComponentIdent;
*p++ = '/';
}
elen += sizeof(struct PathComponent) + pc->lengthComponentIdent;
}
-
- if (p>to+1) {
+ if (p > to+1)
p[-1] = '\0';
- }
+ else
+ p[0] = '\0';
}
static int udf_symlink_filler(struct dentry * dentry, struct page *page)
@@ -79,20 +81,20 @@ static int udf_symlink_filler(struct dentry * dentry, struct page *page)
struct inode *inode = dentry->d_inode;
struct buffer_head *bh = NULL;
char *symlink;
- int err;
-
- char *p = (char*)kmap(page);
+ int err = -EIO;
+ char *p = (char *)kmap(page);
- err = -EIO;
- if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB) {
- bh = udf_tread(inode->i_sb, inode->i_ino,
- inode->i_sb->s_blocksize);
+ if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
+ {
+ bh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize);
if (!bh)
goto out;
symlink = bh->b_data + udf_file_entry_alloc_offset(inode);
- } else {
+ }
+ else
+ {
bh = bread(inode->i_dev, udf_block_map(inode, 0),
inode->i_sb->s_blocksize);
@@ -104,6 +106,7 @@ static int udf_symlink_filler(struct dentry * dentry, struct page *page)
udf_pc_to_char(symlink, inode->i_size, p);
udf_release_data(bh);
+
SetPageUptodate(page);
kunmap(page);
UnlockPage(page);
@@ -112,14 +115,29 @@ out:
SetPageError(page);
kunmap(page);
UnlockPage(page);
- return -EIO;
+ return err;
}
/*
* symlinks can't do much...
*/
struct inode_operations udf_symlink_inode_operations = {
- readlink: page_readlink,
- follow_link: page_follow_link,
- readpage: udf_symlink_filler,
+ NULL, /* no file-operations */
+ NULL, /* create */
+ NULL, /* lookup */
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ page_readlink, /* readlink */
+ page_follow_link, /* follow_link */
+ NULL, /* get_block */
+ udf_symlink_filler, /* readpage */
+ NULL, /* writepage */
+ NULL, /* truncate */
+ NULL, /* permission */
+ NULL /* revalidate */
};
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
index 1bf6e4cee..4054da721 100644
--- a/fs/udf/truncate.c
+++ b/fs/udf/truncate.c
@@ -15,7 +15,7 @@
* ftp://prep.ai.mit.edu/pub/gnu/GPL
* Each contributing author retains all rights to their own work.
*
- * (C) 1999 Ben Fennema
+ * (C) 1999-2000 Ben Fennema
* (C) 1999 Stelias Computing Inc
*
* HISTORY
@@ -33,32 +33,29 @@
#include "udf_sb.h"
static void extent_trunc(struct inode * inode, lb_addr bloc, int *extoffset,
- lb_addr eloc, Uint32 elen, struct buffer_head **bh, Uint32 offset)
+ lb_addr eloc, Uint8 etype, Uint32 elen, struct buffer_head **bh, Uint32 offset)
{
lb_addr neloc = { 0, 0 };
- int nelen = 0;
+ int nelen = 0;
int blocks = inode->i_sb->s_blocksize / 512;
int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
if (offset)
{
- nelen = ((offset - 1) << inode->i_sb->s_blocksize_bits) +
- (inode->i_size & (inode->i_sb->s_blocksize - 1));
+ nelen = (etype << 30) |
+ (((offset - 1) << inode->i_sb->s_blocksize_bits) +
+ (inode->i_size & (inode->i_sb->s_blocksize - 1)));
neloc = eloc;
}
-
- inode->i_blocks -= (blocks * (last_block - offset));
+ if (etype == EXTENT_RECORDED_ALLOCATED)
+ inode->i_blocks -= (blocks * (last_block - offset));
udf_write_aext(inode, bloc, extoffset, neloc, nelen, bh, 1);
- if (!memcmp(&UDF_I_EXT0LOC(inode), &eloc, sizeof(lb_addr)))
- {
- UDF_I_EXT0LOC(inode) = neloc;
- UDF_I_EXT0LEN(inode) = nelen;
- }
mark_inode_dirty(inode);
- udf_free_blocks(inode, eloc, offset, last_block - offset);
+ if (etype != EXTENT_NOT_RECORDED_NOT_ALLOCATED)
+ udf_free_blocks(inode, eloc, offset, last_block - offset);
}
-static void trunc(struct inode * inode)
+void udf_trunc(struct inode * inode)
{
lb_addr bloc, eloc, neloc = { 0, 0 };
Uint32 extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc;
@@ -77,7 +74,7 @@ static void trunc(struct inode * inode)
if ((etype = inode_bmap(inode, first_block, &bloc, &extoffset, &eloc, &elen, &offset, &bh)) != -1)
{
extoffset -= adsize;
- extent_trunc(inode, bloc, &extoffset, eloc, elen, &bh, offset);
+ extent_trunc(inode, bloc, &extoffset, eloc, etype, elen, &bh, offset);
if (offset)
lenalloc = extoffset;
@@ -124,10 +121,8 @@ static void trunc(struct inode * inode)
else
lelen = 1;
}
- else if (etype != EXTENT_NOT_RECORDED_NOT_ALLOCATED)
- extent_trunc(inode, bloc, &extoffset, eloc, elen, &bh, 0);
else
- udf_write_aext(inode, bloc, &extoffset, neloc, nelen, &bh, 1);
+ extent_trunc(inode, bloc, &extoffset, eloc, etype, elen, &bh, 0);
}
if (lelen)
@@ -151,8 +146,6 @@ static void trunc(struct inode * inode)
}
else if (inode->i_size)
{
- lb_addr e0loc = UDF_I_LOCATION(inode);
- Uint32 ext0offset = udf_file_entry_alloc_offset(inode);
char tetype;
if (offset)
@@ -164,8 +157,6 @@ static void trunc(struct inode * inode)
extoffset -= adsize;
elen = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) |
(elen + (offset << inode->i_sb->s_blocksize_bits));
- if (ext0offset == extoffset && !memcmp(&e0loc, &bloc, sizeof(lb_addr)))
- UDF_I_EXT0LEN(inode) = elen;
udf_write_aext(inode, bloc, &extoffset, eloc, elen, &bh, 0);
}
else
@@ -176,18 +167,11 @@ static void trunc(struct inode * inode)
elen = (EXTENT_RECORDED_ALLOCATED << 30) |
((elen + inode->i_sb->s_blocksize - 1) &
~(inode->i_sb->s_blocksize - 1));
- if (ext0offset == extoffset && !memcmp(&e0loc, &bloc, sizeof(lb_addr)))
- UDF_I_EXT0LEN(inode) = elen;
udf_write_aext(inode, bloc, &extoffset, eloc, elen, &bh, 1);
}
memset(&eloc, 0x00, sizeof(lb_addr));
elen = (EXTENT_NOT_RECORDED_NOT_ALLOCATED << 30) |
(offset << inode->i_sb->s_blocksize_bits);
- if (ext0offset == extoffset && !memcmp(&e0loc, &bloc, sizeof(lb_addr)))
- {
- UDF_I_EXT0LOC(inode) = eloc;
- UDF_I_EXT0LEN(inode) = elen;
- }
udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
}
}
@@ -204,12 +188,7 @@ void udf_truncate(struct inode * inode)
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return;
- if (!UDF_I_EXT0OFFS(inode))
- {
- udf_discard_prealloc(inode);
-
- trunc(inode);
- }
+ udf_trunc(inode);
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
mark_inode_dirty(inode);
@@ -223,6 +202,8 @@ void udf_truncate_adinicb(struct inode * inode)
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return;
+ UDF_I_LENALLOC(inode) = inode->i_size;
+
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
mark_inode_dirty(inode);
}
diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h
index 8b9038296..4d1f64c85 100644
--- a/fs/udf/udf_i.h
+++ b/fs/udf/udf_i.h
@@ -1,11 +1,8 @@
#ifndef __LINUX_UDF_I_H
#define __LINUX_UDF_I_H
-#define UDF_I(X) (&((X)->u.udf_i))
+#define UDF_I(X) (&((X)->u.udf_i))
-#define UDF_I_EXT0LOC(X) ( UDF_I(X)->i_ext0Location )
-#define UDF_I_EXT0LEN(X) ( UDF_I(X)->i_ext0Length )
-#define UDF_I_EXT0OFFS(X) ( UDF_I(X)->i_ext0Offset )
#define UDF_I_LOCATION(X) ( UDF_I(X)->i_location )
#define UDF_I_LENEATTR(X) ( UDF_I(X)->i_lenEAttr )
#define UDF_I_LENALLOC(X) ( UDF_I(X)->i_lenAlloc )
@@ -13,8 +10,6 @@
#define UDF_I_ALLOCTYPE(X) ( UDF_I(X)->i_alloc_type )
#define UDF_I_EXTENDED_FE(X)( UDF_I(X)->i_extended_fe )
#define UDF_I_STRAT4096(X) ( UDF_I(X)->i_strat_4096 )
-#define UDF_I_PREALLOC_COUNT(X) ( UDF_I(X)->i_prealloc_count )
-#define UDF_I_PREALLOC_BLOCK(X) ( UDF_I(X)->i_prealloc_block )
#define UDF_I_NEXT_ALLOC_BLOCK(X) ( UDF_I(X)->i_next_alloc_block )
#define UDF_I_NEXT_ALLOC_GOAL(X) ( UDF_I(X)->i_next_alloc_goal )
#define UDF_I_UATIME(X) ( UDF_I(X)->i_uatime )
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 310ba4aef..5fab514bc 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -24,6 +24,7 @@
{\
UDF_SB_NUMPARTS(X) = Y;\
UDF_SB_PARTMAPS(X) = kmalloc(sizeof(struct udf_part_map) * Y, GFP_KERNEL);\
+ memset(UDF_SB_PARTMAPS(X), 0x00, sizeof(struct udf_part_map) * Y);\
}
#define IS_STRICT(X) ( UDF_SB(X)->s_flags & UDF_FLAG_STRICT )
@@ -43,9 +44,7 @@
#define UDF_SB_RECORDTIME(X) ( UDF_SB(X)->s_recordtime )
#define UDF_SB_VOLIDENT(X) ( UDF_SB(X)->s_volident )
#define UDF_SB_PARTMAPS(X) ( UDF_SB(X)->s_partmaps )
-#define UDF_SB_LOCATION(X) ( UDF_SB(X)->s_location )
#define UDF_SB_SERIALNUM(X) ( UDF_SB(X)->s_serialnum )
-#define UDF_SB_CHARSET(X) ( UDF_SB(X)->s_nls_iocharset )
#define UDF_SB_VAT(X) ( UDF_SB(X)->s_vat )
#define UDF_SB_BLOCK_BITMAP_NUMBER(X,Y) ( UDF_SB(X)->s_block_bitmap_number[Y] )
@@ -59,5 +58,6 @@
#define UDF_SB_PARTNUM(X,Y) ( UDF_SB_PARTMAPS(X)[Y].s_partition_num )
#define UDF_SB_TYPESPAR(X,Y) ( UDF_SB_PARTMAPS(X)[Y].s_type_specific.s_sparing )
#define UDF_SB_TYPEVIRT(X,Y) ( UDF_SB_PARTMAPS(X)[Y].s_type_specific.s_virtual )
+#define UDF_SB_PARTFUNC(X,Y) ( UDF_SB_PARTMAPS(X)[Y].s_partition_func )
#endif /* __LINUX_UDF_SB_H */
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index f50ca705c..171cd0d75 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -1,7 +1,7 @@
#ifndef __UDF_DECL_H
#define __UDF_DECL_H
-#define UDF_VERSION_NOTICE "v0.8.9.4"
+#define UDF_VERSION_NOTICE "v0.9.0"
#include <linux/udf_167.h>
#include <linux/udf_udf.h>
@@ -39,6 +39,12 @@
sizeof(struct ExtendedFileEntry) :\
sizeof(struct FileEntry)) + UDF_I_LENEATTR(inode))
+#define udf_ext0_offset(inode)\
+ (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB ?\
+ udf_file_entry_alloc_offset(inode) : 0)
+
+#define udf_get_lb_pblock(sb,loc,offset) udf_get_pblock((sb), (loc).logicalBlockNum, (loc).partitionReferenceNum, (offset))
+
#else
#include <sys/types.h>
@@ -128,9 +134,12 @@ extern int udf_ioctl(struct inode *, struct file *, unsigned int, unsigned long)
/* inode.c */
extern struct inode *udf_iget(struct super_block *, lb_addr);
extern int udf_sync_inode(struct inode *);
-extern struct buffer_head * udf_expand_adinicb(struct inode *, int *, int, int *);
+extern void udf_expand_file_adinicb(struct file *, int, int *);
+extern struct buffer_head * udf_expand_dir_adinicb(struct inode *, int *, int *);
extern struct buffer_head * udf_getblk(struct inode *, long, int, int *);
extern int udf_get_block(struct inode *, long, struct buffer_head *, int);
+extern int udf_readpage_adinicb (struct dentry *, struct page *);
+extern int udf_writepage_adinicb (struct dentry *, struct page *);
extern struct buffer_head * udf_bread(struct inode *, int, int, int *);
extern void udf_read_inode(struct inode *);
extern void udf_put_inode(struct inode *);
@@ -163,7 +172,10 @@ extern unsigned int udf_get_last_block(struct super_block *, int *);
/* partition.c */
extern Uint32 udf_get_pblock(struct super_block *, Uint32, Uint16, Uint32);
-extern Uint32 udf_get_lb_pblock(struct super_block *, lb_addr, Uint32);
+extern Uint32 udf_get_pblock_virt15(struct super_block *, Uint32, Uint16, Uint32);
+extern Uint32 udf_get_pblock_virt20(struct super_block *, Uint32, Uint16, Uint32);
+extern Uint32 udf_get_pblock_spar15(struct super_block *, Uint32, Uint16, Uint32);
+extern void udf_fill_spartable(struct super_block *, struct udf_sparing_data *, int);
/* unicode.c */
extern int udf_get_filename(Uint8 *, Uint8 *, int);
@@ -173,6 +185,7 @@ extern void udf_free_inode(struct inode *);
extern struct inode * udf_new_inode (const struct inode *, int, int *);
/* truncate.c */
+extern void udf_trunc(struct inode *);
extern void udf_truncate(struct inode *);
extern void udf_truncate_adinicb(struct inode *);
@@ -181,6 +194,7 @@ extern void udf_free_blocks(const struct inode *, lb_addr, Uint32, Uint32);
extern int udf_alloc_blocks(const struct inode *, Uint16, Uint32, Uint32);
extern int udf_new_block(const struct inode *, Uint16, Uint32, int *);
extern int udf_sync_file(struct file *, struct dentry *);
+extern int udf_sync_file_adinicb(struct file *, struct dentry *);
/* directory.c */
extern Uint8 * udf_filead_read(struct inode *, Uint8 *, Uint8, lb_addr, int *, int *, struct buffer_head **, int *);
@@ -207,8 +221,6 @@ extern int udf_UTF8toCS0(dstring *, struct ustr *, int);
extern Uint16 udf_crc(Uint8 *, Uint32, Uint16);
/* misc.c */
-extern uid_t udf_convert_uid(int);
-extern gid_t udf_convert_gid(int);
extern Uint32 udf64_low32(Uint64);
extern Uint32 udf64_high32(Uint64);
extern void udf_update_tag(char *, int);
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c
index 3fa925f6b..b2a9e3462 100644
--- a/fs/udf/udftime.c
+++ b/fs/udf/udftime.c
@@ -139,7 +139,7 @@ udf_time_to_stamp(timestamp *dest, time_t tv_sec, long tv_usec)
gettimeofday(&tv, &sys_tz);
#endif
- offset = (-sys_tz.tz_minuteswest + (sys_tz.tz_dsttime ? 60 : 0));
+ offset = (-sys_tz.tz_minuteswest);
if (!dest)
return NULL;
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c
index 6cf63164d..29801728d 100644
--- a/fs/udf/unicode.c
+++ b/fs/udf/unicode.c
@@ -38,24 +38,24 @@ int udf_ustr_to_dchars(Uint8 *dest, const struct ustr *src, int strlen)
{
if ( (!dest) || (!src) || (!strlen) || (src->u_len > strlen) )
return 0;
- memcpy(dest+1, src->u_name, src->u_len-1);
+ memcpy(dest+1, src->u_name, src->u_len);
dest[0] = src->u_cmpID;
- return src->u_len;
+ return src->u_len + 1;
}
int udf_ustr_to_char(Uint8 *dest, const struct ustr *src, int strlen)
{
if ( (!dest) || (!src) || (!strlen) || (src->u_len >= strlen) )
return 0;
- memcpy(dest, src->u_name, src->u_len-1);
- return src->u_len - 1;
+ memcpy(dest, src->u_name, src->u_len);
+ return src->u_len;
}
int udf_ustr_to_dstring(dstring *dest, const struct ustr *src, int dlength)
{
if ( udf_ustr_to_dchars(dest, src, dlength-1) )
{
- dest[dlength-1] = src->u_len;
+ dest[dlength-1] = src->u_len + 1;
return dlength;
}
else
@@ -69,8 +69,8 @@ int udf_dchars_to_ustr(struct ustr *dest, const Uint8 *src, int strlen)
memset(dest, 0, sizeof(struct ustr));
memcpy(dest->u_name, src+1, strlen-1);
dest->u_cmpID = src[0];
- dest->u_len = strlen;
- return strlen;
+ dest->u_len = strlen-1;
+ return strlen-1;
}
int udf_char_to_ustr(struct ustr *dest, const Uint8 *src, int strlen)
@@ -80,8 +80,8 @@ int udf_char_to_ustr(struct ustr *dest, const Uint8 *src, int strlen)
memset(dest, 0, sizeof(struct ustr));
memcpy(dest->u_name, src, strlen);
dest->u_cmpID = 0x08;
- dest->u_len = strlen + 1;
- return strlen + 1;
+ dest->u_len = strlen;
+ return strlen;
}
@@ -182,38 +182,21 @@ int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i)
/* Expand OSTA compressed Unicode to Unicode */
c = ocu[i++];
if (cmp_id == 16)
- {
c = (c << 8) | ocu[i++];
-#ifdef __KERNEL__
- if (c & 0xFF00)
- udf_debug("cmd_id == 16 (0x%2x%2x)\n",
- ((c >> 8) & 0xFF), (c & 0xFF));
-#endif
- }
/* Compress Unicode to UTF-8 */
if (c < 0x80U)
utf_o->u_name[utf_o->u_len++] = (Uint8)c;
- else if (c < 0x800U) {
+ else if (c < 0x800U)
+ {
utf_o->u_name[utf_o->u_len++] = (Uint8)(0xc0 | (c >> 6));
utf_o->u_name[utf_o->u_len++] = (Uint8)(0x80 | (c & 0x3f));
-#ifdef __KERNEL__
- udf_debug("(0x%2x%2x) -> (%2x) (%2x)\n",
- ((c >> 8) & 0xFF), (c & 0xFF),
- utf_o->u_name[utf_o->u_len-2],
- utf_o->u_name[utf_o->u_len-1]);
-#endif
- } else {
+ }
+ else
+ {
utf_o->u_name[utf_o->u_len++] = (Uint8)(0xe0 | (c >> 12));
utf_o->u_name[utf_o->u_len++] = (Uint8)(0x80 | ((c >> 6) & 0x3f));
utf_o->u_name[utf_o->u_len++] = (Uint8)(0x80 | (c & 0x3f));
-#ifdef __KERNEL__
- udf_debug("(0x%2x%2x) -> (%2x) (%2x) (%2x)\n",
- ((c >> 8) & 0xFF), (c & 0xFF),
- utf_o->u_name[utf_o->u_len-3],
- utf_o->u_name[utf_o->u_len-2],
- utf_o->u_name[utf_o->u_len-1]);
-#endif
}
}
utf_o->u_cmpID=8;
@@ -259,34 +242,49 @@ int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length)
try_again:
utf_char = 0U;
utf_cnt = 0U;
- for (i = 0U; i < utf->u_len; i++) {
- c = (unsigned)utf->u_name[i];
+ for (i = 0U; i < utf->u_len; i++)
+ {
+ c = (Uint8)utf->u_name[i];
/* Complete a multi-byte UTF-8 character */
- if (utf_cnt) {
+ if (utf_cnt)
+ {
utf_char = (utf_char << 6) | (c & 0x3fU);
if (--utf_cnt)
continue;
- } else {
+ }
+ else
+ {
/* Check for a multi-byte UTF-8 character */
- if (c & 0x80U) {
+ if (c & 0x80U)
+ {
/* Start a multi-byte UTF-8 character */
- if ((c & 0xe0U) == 0xc0U) {
+ if ((c & 0xe0U) == 0xc0U)
+ {
utf_char = c & 0x1fU;
utf_cnt = 1;
- } else if ((c & 0xf0U) == 0xe0U) {
+ }
+ else if ((c & 0xf0U) == 0xe0U)
+ {
utf_char = c & 0x0fU;
utf_cnt = 2;
- } else if ((c & 0xf8U) == 0xf0U) {
+ }
+ else if ((c & 0xf8U) == 0xf0U)
+ {
utf_char = c & 0x07U;
utf_cnt = 3;
- } else if ((c & 0xfcU) == 0xf8U) {
+ }
+ else if ((c & 0xfcU) == 0xf8U)
+ {
utf_char = c & 0x03U;
utf_cnt = 4;
- } else if ((c & 0xfeU) == 0xfcU) {
+ }
+ else if ((c & 0xfeU) == 0xfcU)
+ {
utf_char = c & 0x01U;
utf_cnt = 5;
- } else
+ }
+ else
goto error_out;
continue;
} else
@@ -295,8 +293,10 @@ try_again:
}
/* Choose no compression if necessary */
- if (utf_char > max_val) {
- if ( 0xffU == max_val ) {
+ if (utf_char > max_val)
+ {
+ if ( 0xffU == max_val )
+ {
max_val = 0xffffU;
ocu[0] = (Uint8)0x10U;
goto try_again;
@@ -305,11 +305,15 @@ try_again:
}
if (max_val == 0xffffU)
+ {
ocu[++u_len] = (Uint8)(utf_char >> 8);
+ }
ocu[++u_len] = (Uint8)(utf_char & 0xffU);
}
- if (utf_cnt) {
+
+ if (utf_cnt)
+ {
error_out:
#ifdef __KERNEL__
printk(KERN_ERR "udf: bad UTF-8 character\n");
@@ -317,8 +321,8 @@ error_out:
return 0;
}
- ocu[length - 1] = (Uint8)u_len;
- return u_len;
+ ocu[length - 1] = (Uint8)u_len + 1;
+ return u_len + 1;
}
#ifdef __KERNEL__
diff --git a/include/asm-alpha/ioctls.h b/include/asm-alpha/ioctls.h
index 2a065c5b6..4c96cdd35 100644
--- a/include/asm-alpha/ioctls.h
+++ b/include/asm-alpha/ioctls.h
@@ -61,6 +61,9 @@
# define TIOCM_DSR 0x100
# define TIOCM_CD TIOCM_CAR
# define TIOCM_RI TIOCM_RNG
+# define TIOCM_OUT1 0x2000
+# define TIOCM_OUT2 0x4000
+# define TIOCM_LOOP 0x8000
#define TIOCGSOFTCAR 0x5419
#define TIOCSSOFTCAR 0x541A
diff --git a/include/asm-alpha/parport.h b/include/asm-alpha/parport.h
index e9b590ee1..bc6b79597 100644
--- a/include/asm-alpha/parport.h
+++ b/include/asm-alpha/parport.h
@@ -39,16 +39,16 @@ parport_pc_init(int *io, int *io_hi, int *irq, int *dma)
do {
if (!*io_hi) *io_hi = 0x400 + *io;
if (parport_pc_probe_port(*(io++), *(io_hi++),
- *(irq++), *(dma++)))
+ *(irq++), *(dma++), NULL))
count++;
} while (*io && (++i < PARPORT_PC_MAX_PORTS));
} else {
/* Probe all the likely ports. */
- if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0], NULL))
count++;
- if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0], NULL))
count++;
- if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0], NULL))
count++;
count += parport_pc_init_pci (irq[0], dma[0]);
}
diff --git a/include/asm-alpha/siginfo.h b/include/asm-alpha/siginfo.h
index a8bedd8e0..ec9e9595c 100644
--- a/include/asm-alpha/siginfo.h
+++ b/include/asm-alpha/siginfo.h
@@ -149,7 +149,7 @@ typedef struct siginfo {
#define CLD_TRAPPED 4 /* traced child has trapped */
#define CLD_STOPPED 5 /* child has stopped */
#define CLD_CONTINUED 6 /* stopped child has continued */
-#define NSIGCHLD
+#define NSIGCHLD 6
/*
* SIGPOLL si_codes
diff --git a/include/asm-arm/parport.h b/include/asm-arm/parport.h
index bcb533af4..b61c0d62c 100644
--- a/include/asm-arm/parport.h
+++ b/include/asm-arm/parport.h
@@ -39,16 +39,16 @@ parport_pc_init(int *io, int *io_hi, int *irq, int *dma)
do {
if (!*io_hi) *io_hi = 0x400 + *io;
if (parport_pc_probe_port(*(io++), *(io_hi++),
- *(irq++), *(dma++)))
+ *(irq++), *(dma++), NULL))
count++;
} while (*io && (++i < PARPORT_PC_MAX_PORTS));
} else {
/* Probe all the likely ports. */
- if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0], NULL))
count++;
- if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0], NULL))
count++;
- if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0], NULL))
count++;
count += parport_pc_init_pci (irq[0], dma[0]);
}
diff --git a/include/asm-arm/siginfo.h b/include/asm-arm/siginfo.h
index 4ffd51452..945d4d429 100644
--- a/include/asm-arm/siginfo.h
+++ b/include/asm-arm/siginfo.h
@@ -24,8 +24,7 @@ typedef struct siginfo {
/* kill() */
struct {
pid_t _pid; /* sender's pid */
- old_uid_t _uid; /* backwards compatibility */
- uid_t _uid32; /* sender's uid */
+ uid_t _uid; /* sender's uid */
} _kill;
/* POSIX.1b timers */
@@ -37,19 +36,17 @@ typedef struct siginfo {
/* POSIX.1b signals */
struct {
pid_t _pid; /* sender's pid */
- old_uid_t _uid; /* backwards compatibility */
+ uid_t _uid; /* sender's uid */
sigval_t _sigval;
- uid_t _uid32; /* sender's uid */
} _rt;
/* SIGCHLD */
struct {
pid_t _pid; /* which child */
- old_uid_t _uid; /* backwards compatibility */
+ uid_t _uid; /* sender's uid */
int _status; /* exit code */
clock_t _utime;
clock_t _stime;
- uid_t _uid32; /* sender's uid */
} _sigchld;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
@@ -65,18 +62,11 @@ typedef struct siginfo {
} _sifields;
} siginfo_t;
-#define UID16_SIGINFO_COMPAT_NEEDED
-
/*
* How these fields are to be accessed.
*/
#define si_pid _sifields._kill._pid
-#ifdef __KERNEL__
-#define si_uid _sifields._kill._uid32
-#define si_uid16 _sifields._kill._uid
-#else
#define si_uid _sifields._kill._uid
-#endif /* __KERNEL__ */
#define si_status _sifields._sigchld._status
#define si_utime _sifields._sigchld._utime
#define si_stime _sifields._sigchld._stime
@@ -159,7 +149,7 @@ typedef struct siginfo {
#define CLD_TRAPPED 4 /* traced child has trapped */
#define CLD_STOPPED 5 /* child has stopped */
#define CLD_CONTINUED 6 /* stopped child has continued */
-#define NSIGCHLD
+#define NSIGCHLD 6
/*
* SIGPOLL si_codes
diff --git a/include/asm-arm/termios.h b/include/asm-arm/termios.h
index 1ccc31eb7..c45cea198 100644
--- a/include/asm-arm/termios.h
+++ b/include/asm-arm/termios.h
@@ -45,6 +45,7 @@ struct termio {
#define TIOCM_RI TIOCM_RNG
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
diff --git a/include/asm-i386/parport.h b/include/asm-i386/parport.h
index c08ee4686..1c2855bbe 100644
--- a/include/asm-i386/parport.h
+++ b/include/asm-i386/parport.h
@@ -39,16 +39,16 @@ parport_pc_init(int *io, int *io_hi, int *irq, int *dma)
do {
if (!*io_hi) *io_hi = 0x400 + *io;
if (parport_pc_probe_port(*(io++), *(io_hi++),
- *(irq++), *(dma++)))
+ *(irq++), *(dma++), NULL))
count++;
} while (*io && (++i < PARPORT_PC_MAX_PORTS));
} else {
/* Probe all the likely ports. */
- if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0], NULL))
count++;
- if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0], NULL))
count++;
- if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0], NULL))
count++;
count += parport_pc_init_pci (irq[0], dma[0]);
}
diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h
index ef5198dfc..8cc99dda0 100644
--- a/include/asm-i386/pci.h
+++ b/include/asm-i386/pci.h
@@ -10,5 +10,136 @@
#define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_MEM 0x10000000
+#ifdef __KERNEL__
+
+/* Dynamic DMA mapping stuff.
+ * i386 has everything mapped statically.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include <asm/io.h>
+
+struct pci_dev;
+
+/* Allocate and map kernel buffer using consistent mode DMA for a device.
+ * hwdev should be valid struct pci_dev pointer for PCI devices,
+ * NULL for PCI-like buses (ISA, EISA).
+ * Returns non-NULL cpu-view pointer to the buffer if successful and
+ * sets *dma_addrp to the pci side dma address as well, else *dma_addrp
+ * is undefined.
+ */
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+ dma_addr_t *dma_handle);
+
+/* Free and unmap a consistent DMA buffer.
+ * cpu_addr is what was returned from pci_alloc_consistent,
+ * size must be the same as what as passed into pci_alloc_consistent,
+ * and likewise dma_addr must be the same as what *dma_addrp was set to.
+ *
+ * References to the memory and mappings associated with cpu_addr/dma_addr
+ * past this call are illegal.
+ */
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+ void *vaddr, dma_addr_t dma_handle);
+
+/* Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+ size_t size)
+{
+ return virt_to_bus(ptr);
+}
+
+/* Unmap a single streaming mode DMA translation. The dma_addr and size
+ * must match what was provided for in a previous pci_map_single call. All
+ * other usages are undefined.
+ *
+ * After this call, reads by the cpu to the buffer are guarenteed to see
+ * whatever the device wrote there.
+ */
+extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+ size_t size)
+{
+ /* Nothing to do */
+}
+
+/* Map a set of buffers described by scatterlist in streaming
+ * mode for DMA. This is the scather-gather version of the
+ * above pci_map_single interface. Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length. They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ * DMA address/length pairs than there are SG table elements.
+ * (for example via virtual mapping capabilities)
+ * The routine returns the number of addr/length pairs actually
+ * used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+ int nents)
+{
+ return nents;
+}
+
+/* Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+extern inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+ int nents)
+{
+ /* Nothing to do */
+}
+
+/* Make physical memory consistent for a single
+ * streaming mode DMA translation after a transfer.
+ *
+ * If you perform a pci_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so. At the
+ * next point you give the PCI dma address back to the card, the
+ * device again owns the buffer.
+ */
+extern inline void pci_dma_sync_single(struct pci_dev *hwdev,
+ dma_addr_t dma_handle,
+ size_t size)
+{
+ /* Nothing to do */
+}
+
+/* Make physical memory consistent for a set of streaming
+ * mode DMA translations after a transfer.
+ *
+ * The same as pci_dma_sync_single but for a scatter-gather list,
+ * same rules and usage.
+ */
+extern inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+ struct scatterlist *sg,
+ int nelems)
+{
+ /* Nothing to do */
+}
+
+/* These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_dma_address(sg) (virt_to_bus((sg)->address))
+#define sg_dma_len(sg) ((sg)->length)
+
+#endif /* __KERNEL__ */
+
#endif /* __i386_PCI_H */
diff --git a/include/asm-i386/semaphore.h b/include/asm-i386/semaphore.h
index ef4c558da..827c53192 100644
--- a/include/asm-i386/semaphore.h
+++ b/include/asm-i386/semaphore.h
@@ -238,11 +238,18 @@ struct rw_semaphore {
#define __RWSEM_DEBUG_INIT /* */
#endif
-#define __RWSEM_INITIALIZER(name) \
-{ ATOMIC_INIT(RW_LOCK_BIAS), 0, 0, 0, 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
+#define __RWSEM_INITIALIZER(name,count) \
+{ ATOMIC_INIT(count), 0, 0, 0, 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
__WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait) \
__SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT }
+#define __DECLARE_RWSEM_GENERIC(name,count) \
+ struct rw_semaphore name = __RWSEM_INITIALIZER(name,count)
+
+#define DECLARE_RWSEM(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS)
+#define DECLARE_RWSEM_READ_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS-1)
+#define DECLARE_RWSEM_WRITE_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,0)
+
extern inline void init_rwsem(struct rw_semaphore *sem)
{
atomic_set(&sem->count, RW_LOCK_BIAS);
diff --git a/include/asm-i386/siginfo.h b/include/asm-i386/siginfo.h
index 467aa9d39..c762775c1 100644
--- a/include/asm-i386/siginfo.h
+++ b/include/asm-i386/siginfo.h
@@ -24,8 +24,7 @@ typedef struct siginfo {
/* kill() */
struct {
pid_t _pid; /* sender's pid */
- old_uid_t _uid; /* backwards compatibility */
- uid_t _uid32; /* sender's uid */
+ uid_t _uid; /* sender's uid */
} _kill;
/* POSIX.1b timers */
@@ -37,19 +36,17 @@ typedef struct siginfo {
/* POSIX.1b signals */
struct {
pid_t _pid; /* sender's pid */
- old_uid_t _uid; /* backwards compatibility */
+ uid_t _uid; /* sender's uid */
sigval_t _sigval;
- uid_t _uid32; /* sender's uid */
} _rt;
/* SIGCHLD */
struct {
pid_t _pid; /* which child */
- old_uid_t _uid; /* backwards compatibility */
+ uid_t _uid; /* sender's uid */
int _status; /* exit code */
clock_t _utime;
clock_t _stime;
- uid_t _uid32; /* sender's uid */
} _sigchld;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
@@ -65,18 +62,11 @@ typedef struct siginfo {
} _sifields;
} siginfo_t;
-#define UID16_SIGINFO_COMPAT_NEEDED
-
/*
* How these fields are to be accessed.
*/
#define si_pid _sifields._kill._pid
-#ifdef __KERNEL__
-#define si_uid _sifields._kill._uid32
-#define si_uid16 _sifields._kill._uid
-#else
#define si_uid _sifields._kill._uid
-#endif /* __KERNEL__ */
#define si_status _sifields._sigchld._status
#define si_utime _sifields._sigchld._utime
#define si_stime _sifields._sigchld._stime
@@ -159,7 +149,7 @@ typedef struct siginfo {
#define CLD_TRAPPED 4 /* traced child has trapped */
#define CLD_STOPPED 5 /* child has stopped */
#define CLD_CONTINUED 6 /* stopped child has continued */
-#define NSIGCHLD
+#define NSIGCHLD 6
/*
* SIGPOLL si_codes
diff --git a/include/asm-i386/termios.h b/include/asm-i386/termios.h
index 9e55723d3..9b337736f 100644
--- a/include/asm-i386/termios.h
+++ b/include/asm-i386/termios.h
@@ -35,6 +35,7 @@ struct termio {
#define TIOCM_RI TIOCM_RNG
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
diff --git a/include/asm-i386/types.h b/include/asm-i386/types.h
index d792546f9..6c8bc62c2 100644
--- a/include/asm-i386/types.h
+++ b/include/asm-i386/types.h
@@ -41,6 +41,10 @@ typedef unsigned long long u64;
#define BITS_PER_LONG 32
+/* Dma addresses are 32-bits wide. */
+
+typedef u32 dma_addr_t;
+
#endif /* __KERNEL__ */
#endif
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index 22286e151..6ec03679f 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -221,6 +221,7 @@
#define __NR_setgid32 214
#define __NR_setfsuid32 215
#define __NR_setfsgid32 216
+#define __NR_pivot_root 217
/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
diff --git a/include/asm-m68k/amigahw.h b/include/asm-m68k/amigahw.h
index 39dd49979..d63ceca32 100644
--- a/include/asm-m68k/amigahw.h
+++ b/include/asm-m68k/amigahw.h
@@ -281,7 +281,7 @@ struct CIA {
#define CHIP_PHYSADDR (0x000000)
#define chipaddr ((unsigned long)(zTwoBase + CHIP_PHYSADDR))
void amiga_chip_init (void);
-void *amiga_chip_alloc (long size);
+void *amiga_chip_alloc (long size, const char *name);
void amiga_chip_free (void *);
unsigned long amiga_chip_avail( void ); /*MILAN*/
diff --git a/include/asm-m68k/apollodma.h b/include/asm-m68k/apollodma.h
new file mode 100644
index 000000000..3abef61cb
--- /dev/null
+++ b/include/asm-m68k/apollodma.h
@@ -0,0 +1,248 @@
+/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $
+ * linux/include/asm/dma.h: Defines for using and allocating dma channels.
+ * Written by Hennus Bergman, 1992.
+ * High DMA channel support & info by Hannu Savolainen
+ * and John Boyd, Nov. 1992.
+ */
+
+#ifndef _ASM_APOLLO_DMA_H
+#define _ASM_APOLLO_DMA_H
+
+#include <asm/apollohw.h> /* need byte IO */
+#include <asm/spinlock.h> /* And spinlocks */
+#include <linux/delay.h>
+
+
+#define dma_outb(val,addr) (*((volatile unsigned char *)(addr+IO_BASE)) = (val))
+#define dma_inb(addr) (*((volatile unsigned char *)(addr+IO_BASE)))
+
+/*
+ * NOTES about DMA transfers:
+ *
+ * controller 1: channels 0-3, byte operations, ports 00-1F
+ * controller 2: channels 4-7, word operations, ports C0-DF
+ *
+ * - ALL registers are 8 bits only, regardless of transfer size
+ * - channel 4 is not used - cascades 1 into 2.
+ * - channels 0-3 are byte - addresses/counts are for physical bytes
+ * - channels 5-7 are word - addresses/counts are for physical words
+ * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
+ * - transfer count loaded to registers is 1 less than actual count
+ * - controller 2 offsets are all even (2x offsets for controller 1)
+ * - page registers for 5-7 don't use data bit 0, represent 128K pages
+ * - page registers for 0-3 use bit 0, represent 64K pages
+ *
+ * DMA transfers are limited to the lower 16MB of _physical_ memory.
+ * Note that addresses loaded into registers must be _physical_ addresses,
+ * not logical addresses (which may differ if paging is active).
+ *
+ * Address mapping for channels 0-3:
+ *
+ * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses)
+ * | ... | | ... | | ... |
+ * | ... | | ... | | ... |
+ * | ... | | ... | | ... |
+ * P7 ... P0 A7 ... A0 A7 ... A0
+ * | Page | Addr MSB | Addr LSB | (DMA registers)
+ *
+ * Address mapping for channels 5-7:
+ *
+ * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses)
+ * | ... | \ \ ... \ \ \ ... \ \
+ * | ... | \ \ ... \ \ \ ... \ (not used)
+ * | ... | \ \ ... \ \ \ ... \
+ * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0
+ * | Page | Addr MSB | Addr LSB | (DMA registers)
+ *
+ * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
+ * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
+ * the hardware level, so odd-byte transfers aren't possible).
+ *
+ * Transfer count (_not # bytes_) is limited to 64K, represented as actual
+ * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more,
+ * and up to 128K bytes may be transferred on channels 5-7 in one operation.
+ *
+ */
+
+#define MAX_DMA_CHANNELS 8
+
+/* The maximum address that we can perform a DMA transfer to on this platform */#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000)
+
+/* 8237 DMA controllers */
+#define IO_DMA1_BASE 0x10C00 /* 8 bit slave DMA, channels 0..3 */
+#define IO_DMA2_BASE 0x10D00 /* 16 bit master DMA, ch 4(=slave input)..7 */
+
+/* DMA controller registers */
+#define DMA1_CMD_REG (IO_DMA1_BASE+0x08) /* command register (w) */
+#define DMA1_STAT_REG (IO_DMA1_BASE+0x08) /* status register (r) */
+#define DMA1_REQ_REG (IO_DMA1_BASE+0x09) /* request register (w) */
+#define DMA1_MASK_REG (IO_DMA1_BASE+0x0A) /* single-channel mask (w) */
+#define DMA1_MODE_REG (IO_DMA1_BASE+0x0B) /* mode register (w) */
+#define DMA1_CLEAR_FF_REG (IO_DMA1_BASE+0x0C) /* clear pointer flip-flop (w) */
+#define DMA1_TEMP_REG (IO_DMA1_BASE+0x0D) /* Temporary Register (r) */
+#define DMA1_RESET_REG (IO_DMA1_BASE+0x0D) /* Master Clear (w) */
+#define DMA1_CLR_MASK_REG (IO_DMA1_BASE+0x0E) /* Clear Mask */
+#define DMA1_MASK_ALL_REG (IO_DMA1_BASE+0x0F) /* all-channels mask (w) */
+
+#define DMA2_CMD_REG (IO_DMA2_BASE+0x10) /* command register (w) */
+#define DMA2_STAT_REG (IO_DMA2_BASE+0x10) /* status register (r) */
+#define DMA2_REQ_REG (IO_DMA2_BASE+0x12) /* request register (w) */
+#define DMA2_MASK_REG (IO_DMA2_BASE+0x14) /* single-channel mask (w) */
+#define DMA2_MODE_REG (IO_DMA2_BASE+0x16) /* mode register (w) */
+#define DMA2_CLEAR_FF_REG (IO_DMA2_BASE+0x18) /* clear pointer flip-flop (w) */
+#define DMA2_TEMP_REG (IO_DMA2_BASE+0x1A) /* Temporary Register (r) */
+#define DMA2_RESET_REG (IO_DMA2_BASE+0x1A) /* Master Clear (w) */
+#define DMA2_CLR_MASK_REG (IO_DMA2_BASE+0x1C) /* Clear Mask */
+#define DMA2_MASK_ALL_REG (IO_DMA2_BASE+0x1E) /* all-channels mask (w) */
+
+#define DMA_ADDR_0 (IO_DMA1_BASE+0x00) /* DMA address registers */
+#define DMA_ADDR_1 (IO_DMA1_BASE+0x02)
+#define DMA_ADDR_2 (IO_DMA1_BASE+0x04)
+#define DMA_ADDR_3 (IO_DMA1_BASE+0x06)
+#define DMA_ADDR_4 (IO_DMA2_BASE+0x00)
+#define DMA_ADDR_5 (IO_DMA2_BASE+0x04)
+#define DMA_ADDR_6 (IO_DMA2_BASE+0x08)
+#define DMA_ADDR_7 (IO_DMA2_BASE+0x0C)
+
+#define DMA_CNT_0 (IO_DMA1_BASE+0x01) /* DMA count registers */
+#define DMA_CNT_1 (IO_DMA1_BASE+0x03)
+#define DMA_CNT_2 (IO_DMA1_BASE+0x05)
+#define DMA_CNT_3 (IO_DMA1_BASE+0x07)
+#define DMA_CNT_4 (IO_DMA2_BASE+0x02)
+#define DMA_CNT_5 (IO_DMA2_BASE+0x06)
+#define DMA_CNT_6 (IO_DMA2_BASE+0x0A)
+#define DMA_CNT_7 (IO_DMA2_BASE+0x0E)
+
+#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
+#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
+#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
+
+#define DMA_AUTOINIT 0x10
+
+#define DMA_8BIT 0
+#define DMA_16BIT 1
+#define DMA_BUSMASTER 2
+
+extern spinlock_t dma_spin_lock;
+
+static __inline__ unsigned long claim_dma_lock(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&dma_spin_lock, flags);
+ return flags;
+}
+
+static __inline__ void release_dma_lock(unsigned long flags)
+{
+ spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+ if (dmanr<=3)
+ dma_outb(dmanr, DMA1_MASK_REG);
+ else
+ dma_outb(dmanr & 3, DMA2_MASK_REG);
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+ if (dmanr<=3)
+ dma_outb(dmanr | 4, DMA1_MASK_REG);
+ else
+ dma_outb((dmanr & 3) | 4, DMA2_MASK_REG);
+}
+
+/* Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while holding the DMA lock ! ---
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+ if (dmanr<=3)
+ dma_outb(0, DMA1_CLEAR_FF_REG);
+ else
+ dma_outb(0, DMA2_CLEAR_FF_REG);
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+ if (dmanr<=3)
+ dma_outb(mode | dmanr, DMA1_MODE_REG);
+ else
+ dma_outb(mode | (dmanr&3), DMA2_MODE_REG);
+}
+
+/* Set transfer address & page bits for specific DMA channel.
+ * Assumes dma flipflop is clear.
+ */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+ if (dmanr <= 3) {
+ dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+ dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+ } else {
+ dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+ dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+ }
+}
+
+
+/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
+ * a specific DMA channel.
+ * You must ensure the parameters are valid.
+ * NOTE: from a manual: "the number of transfers is one more
+ * than the initial word count"! This is taken into account.
+ * Assumes dma flip-flop is clear.
+ * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+ count--;
+ if (dmanr <= 3) {
+ dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+ dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+ } else {
+ dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+ dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+ }
+}
+
+
+/* Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * If called before the channel has been used, it may return 1.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ *
+ * Assumes DMA flip-flop is clear.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+ unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
+ : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
+
+ /* using short to get 16-bit wrap around */
+ unsigned short count;
+
+ count = 1 + dma_inb(io_port);
+ count += dma_inb(io_port) << 8;
+
+ return (dmanr<=3)? count : (count<<1);
+}
+
+
+/* These are in kernel/dma.c: */
+extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr); /* release it again */
+
+/* These are in arch/m68k/apollo/dma.c: */
+extern unsigned short dma_map_page(unsigned long phys_addr,int count,int type);
+extern void dma_unmap_page(unsigned short dma_addr);
+
+#endif /* _ASM_APOLLO_DMA_H */
diff --git a/include/asm-m68k/apollohw.h b/include/asm-m68k/apollohw.h
index 54177aa3d..e12a638ca 100644
--- a/include/asm-m68k/apollohw.h
+++ b/include/asm-m68k/apollohw.h
@@ -3,6 +3,18 @@
#ifndef _ASMm68k_APOLLOHW_H_
#define _ASMm68k_APOLLOHW_H_
+/*
+ apollo models
+*/
+
+extern u_long apollo_model;
+
+#define APOLLO_UNKNOWN (0)
+#define APOLLO_DN3000 (1)
+#define APOLLO_DN3010 (2)
+#define APOLLO_DN3500 (3)
+#define APOLLO_DN4000 (4)
+#define APOLLO_DN4500 (5)
/*
see scn2681 data sheet for more info.
@@ -52,16 +64,42 @@ struct mc146818 {
unsigned char month, year;
};
+
#define IO_BASE 0x80000000
-#define SIO01_PHYSADDR 0x10400
-#define SIO23_PHYSADDR 0x10500
-#define RTC_PHYSADDR 0x10900
-#define PICA 0x11000
-#define PICB 0x11100
-#define sio01 ((*(volatile struct SCN2681 *)(IO_BASE + SIO01_PHYSADDR)))
-#define sio23 ((*(volatile struct SCN2681 *)(IO_BASE + SIO01_PHYSADDR)))
-#define rtc (((volatile struct mc146818 *)(IO_BASE + RTC_PHYSADDR)))
+extern u_long sio01_physaddr;
+extern u_long sio23_physaddr;
+extern u_long rtc_physaddr;
+extern u_long pica_physaddr;
+extern u_long picb_physaddr;
+extern u_long cpuctrl_physaddr;
+extern u_long timer_physaddr;
+
+#define SAU7_SIO01_PHYSADDR 0x10400
+#define SAU7_SIO23_PHYSADDR 0x10500
+#define SAU7_RTC_PHYSADDR 0x10900
+#define SAU7_PICA 0x11000
+#define SAU7_PICB 0x11100
+#define SAU7_CPUCTRL 0x10100
+#define SAU7_TIMER 0x010800
+
+#define SAU8_SIO01_PHYSADDR 0x8400
+#define SAU8_RTC_PHYSADDR 0x8900
+#define SAU8_PICA 0x9400
+#define SAU8_PICB 0x9500
+#define SAU8_CPUCTRL 0x8100
+#define SAU8_TIMER 0x8800
+
+#define sio01 ((*(volatile struct SCN2681 *)(IO_BASE + sio01_physaddr)))
+#define sio23 ((*(volatile struct SCN2681 *)(IO_BASE + sio23_physaddr)))
+#define rtc (((volatile struct mc146818 *)(IO_BASE + rtc_physaddr)))
+#define cpuctrl (*(volatile unsigned int *)(IO_BASE + cpuctrl_physaddr))
+#define pica (IO_BASE + pica_physaddr)
+#define picb (IO_BASE + picb_physaddr)
+#define timer (IO_BASE + timer_physaddr)
+#define addr_xlat_map ((unsigned short *)(IO_BASE + 0x17000))
+
+#define isaIO2mem(x) (((((x) & 0x3f8) << 7) | (((x) & 0xfc00) >> 6) | ((x) & 0x7)) + 0x40000 + IO_BASE)
#define inb(addr) (*((volatile unsigned char *)(addr)))
#define outb(val,addr) (*((volatile unsigned char *)(addr)) = (val))
diff --git a/include/asm-m68k/bootinfo.h b/include/asm-m68k/bootinfo.h
index 871d051fe..19f340b5c 100644
--- a/include/asm-m68k/bootinfo.h
+++ b/include/asm-m68k/bootinfo.h
@@ -103,6 +103,30 @@ struct bi_record {
#define ATARI_MACH_AB40 3 /* Afterburner040 on Falcon */
/*
+ * VME-specific tags
+ */
+
+#define BI_VME_TYPE 0x8000 /* VME sub-architecture (u_long) */
+#define BI_VME_BRDINFO 0x8001 /* VME board information (struct) */
+
+/* BI_VME_TYPE codes */
+#define VME_TYPE_TP34V 0x0034 /* Tadpole TP34V */
+#define VME_TYPE_MVME147 0x0147 /* Motorola MVME147 */
+#define VME_TYPE_MVME162 0x0162 /* Motorola MVME162 */
+#define VME_TYPE_MVME166 0x0166 /* Motorola MVME166 */
+#define VME_TYPE_MVME167 0x0167 /* Motorola MVME167 */
+#define VME_TYPE_MVME172 0x0172 /* Motorola MVME172 */
+#define VME_TYPE_MVME177 0x0177 /* Motorola MVME177 */
+#define VME_TYPE_BVME4000 0x4000 /* BVM Ltd. BVME4000 */
+#define VME_TYPE_BVME6000 0x6000 /* BVM Ltd. BVME6000 */
+
+/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on
+ * Motorola VME boards. Contains board number, Bug version, board
+ * configuration options, etc. See include/asm/mvme16xhw.h for details.
+ */
+
+
+ /*
* Macintosh-specific tags (all u_long)
*/
@@ -184,6 +208,14 @@ extern struct mac_booter_data
#endif
/*
+ * Apollo-specific tags
+ */
+
+#define BI_APOLLO_MODEL 0x8000 /* model (u_long) */
+
+
+
+ /*
* Stuff for bootinfo interface versioning
*
* At the start of kernel code, a 'struct bootversion' is located.
diff --git a/include/asm-m68k/bvme6000hw.h b/include/asm-m68k/bvme6000hw.h
index 853120a04..28a859b03 100644
--- a/include/asm-m68k/bvme6000hw.h
+++ b/include/asm-m68k/bvme6000hw.h
@@ -95,6 +95,7 @@ typedef struct {
#define BVME_SCC_A_ADDR 0xffb0000b
#define BVME_SCC_B_ADDR 0xffb00003
+#define BVME_SCC_RTxC 7372800
#define BVME_CONFIG_REG 0xff500003
diff --git a/include/asm-m68k/cache.h b/include/asm-m68k/cache.h
index 9e009ce18..52262e891 100644
--- a/include/asm-m68k/cache.h
+++ b/include/asm-m68k/cache.h
@@ -7,16 +7,4 @@
/* bytes per L1 cache line */
#define L1_CACHE_BYTES 16
-#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
-
-#define SMP_CACHE_BYTES L1_CACHE_BYTES
-
-#ifdef MODULE
-#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
-#else
-#define __cacheline_aligned \
- __attribute__((__aligned__(L1_CACHE_BYTES), \
- __section__(".data.cacheline_aligned")))
-#endif
-
#endif
diff --git a/include/asm-m68k/div64.h b/include/asm-m68k/div64.h
new file mode 100644
index 000000000..16bf1f88d
--- /dev/null
+++ b/include/asm-m68k/div64.h
@@ -0,0 +1,35 @@
+#ifndef _M68K_DIV64_H
+#define _M68K_DIV64_H
+
+/* n = n / base; return rem; */
+
+#if 1
+#define do_div(n, base) ({ \
+ union { \
+ unsigned long n32[2]; \
+ unsigned long long n64; \
+ } __n; \
+ unsigned long __rem, __upper; \
+ \
+ __n.n64 = (n); \
+ if ((__upper = __n.n32[0])) { \
+ asm ("divul.l %2,%1:%0" \
+ : "=d" (__n.n32[0]), "=d" (__upper) \
+ : "d" (base), "0" (__n.n32[0])); \
+ } \
+ asm ("divu.l %2,%1:%0" \
+ : "=d" (__n.n32[1]), "=d" (__rem) \
+ : "d" (base), "1" (__upper), "0" (__n.n32[1])); \
+ (n) = __n.n64; \
+ __rem; \
+})
+#else
+#define do_div(n,base) ({ \
+ int __res; \
+ __res = ((unsigned long) n) % (unsigned) base; \
+ n = ((unsigned long) n) / (unsigned) base; \
+ __res; \
+})
+#endif
+
+#endif /* _M68K_DIV64_H */
diff --git a/include/asm-m68k/dma.h b/include/asm-m68k/dma.h
index af73a0f6f..d5266a886 100644
--- a/include/asm-m68k/dma.h
+++ b/include/asm-m68k/dma.h
@@ -1,12 +1,21 @@
#ifndef _M68K_DMA_H
#define _M68K_DMA_H 1
-/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k and any
- occurrence should be flagged as an error. */
+#include <linux/config.h>
+
+/* it's useless on the m68k, but unfortunately needed by the new
+ bootmem allocator (but this should do it for this) */
+#define MAX_DMA_ADDRESS PAGE_OFFSET
#define MAX_DMA_CHANNELS 8
extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
extern void free_dma(unsigned int dmanr); /* release it again */
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy (0)
+#endif
+
#endif /* _M68K_DMA_H */
diff --git a/include/asm-m68k/entry.h b/include/asm-m68k/entry.h
index 56ab0dcf8..3575894b5 100644
--- a/include/asm-m68k/entry.h
+++ b/include/asm-m68k/entry.h
@@ -34,10 +34,6 @@
* the whole kernel.
*/
-#ifdef __ASSEMBLY__
-
-#define curptr a2
-
/* the following macro is used when enabling interrupts */
#if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES)
/* block out HSYNC on the atari */
@@ -49,6 +45,10 @@
#define MAX_NOINT_IPL 0
#endif /* machine compilation types */
+#ifdef __ASSEMBLY__
+
+#define curptr a2
+
LFLUSH_I_AND_D = 0x00000808
LSIGTRAP = 5
@@ -162,7 +162,7 @@ PF_DTRACE_BIT = 5
#endif
#define GET_CURRENT(tmp) \
"movel %%sp,"#tmp"\n\t" \
- "andw #-KTHREAD_SIZE,"#tmp"\n\t" \
+ "andw #-"STR(KTHREAD_SIZE)","#tmp"\n\t" \
"movel "#tmp",%%a2"
#endif
diff --git a/include/asm-m68k/fcntl.h b/include/asm-m68k/fcntl.h
index 2235bd5bb..b5780416f 100644
--- a/include/asm-m68k/fcntl.h
+++ b/include/asm-m68k/fcntl.h
@@ -18,6 +18,8 @@
#define FASYNC 020000 /* fcntl, for BSD compatibility */
#define O_DIRECTORY 040000 /* must be a directory */
#define O_NOFOLLOW 0100000 /* don't follow links */
+#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */
+#define O_LARGEFILE 0400000
#define F_DUPFD 0 /* dup */
#define F_GETFD 1 /* get f_flags */
diff --git a/include/asm-m68k/hardirq.h b/include/asm-m68k/hardirq.h
index 6e8e0d4ac..0e3cd0c6f 100644
--- a/include/asm-m68k/hardirq.h
+++ b/include/asm-m68k/hardirq.h
@@ -10,8 +10,8 @@ extern unsigned int local_irq_count[NR_CPUS];
#define hardirq_trylock(cpu) (local_irq_count[cpu] == 0)
#define hardirq_endlock(cpu) do { } while (0)
-#define hardirq_enter(cpu) (local_irq_count[cpu]++)
-#define hardirq_exit(cpu) (local_irq_count[cpu]--)
+#define irq_enter(cpu) (local_irq_count[cpu]++)
+#define irq_exit(cpu) (local_irq_count[cpu]--)
#define synchronize_irq() barrier()
diff --git a/include/asm-m68k/mmu_context.h b/include/asm-m68k/mmu_context.h
index a8a1dfc61..f54fbfa17 100644
--- a/include/asm-m68k/mmu_context.h
+++ b/include/asm-m68k/mmu_context.h
@@ -7,6 +7,7 @@
#include <asm/setup.h>
#include <asm/page.h>
+#include <asm/pgalloc.h>
extern inline void
init_new_context(struct task_struct *tsk, struct mm_struct *mm)
diff --git a/include/asm-m68k/movs.h b/include/asm-m68k/movs.h
index 67dbea369..540d3e60e 100644
--- a/include/asm-m68k/movs.h
+++ b/include/asm-m68k/movs.h
@@ -10,46 +10,46 @@
/* Set DFC register value */
#define SET_DFC(x) \
- __asm__ __volatile__ (" movec %0,%/dfc" : : "d" (x));
+ __asm__ __volatile__ ("movec %0,%%dfc" : : "r" (x))
/* Get DFC register value */
#define GET_DFC(x) \
- __asm__ __volatile__ (" movec %/dfc, %0" : "=d" (x) : );
+ __asm__ __volatile__ ("movec %%dfc,%0" : "=r" (x))
/* Set SFC register value */
#define SET_SFC(x) \
- __asm__ __volatile__ (" movec %0,%/sfc" : : "d" (x));
+ __asm__ __volatile__ ("movec %0,%%sfc" : : "r" (x))
/* Get SFC register value */
#define GET_SFC(x) \
- __asm__ __volatile__ (" movec %/sfc, %0" : "=d" (x) : );
+ __asm__ __volatile__ ("movec %%sfc,%0" : "=r" (x))
#define SET_VBR(x) \
- __asm__ __volatile__ (" movec %0,%/vbr" : : "r" (x));
+ __asm__ __volatile__ ("movec %0,%%vbr" : : "r" (x))
#define GET_VBR(x) \
- __asm__ __volatile__ (" movec %/vbr, %0" : "=g" (x) : );
+ __asm__ __volatile__ ("movec %%vbr,%0" : "=r" (x))
-/* Set a byte using the "movs" instruction */
+/* Set a byte using the "moves" instruction */
#define SET_CONTROL_BYTE(addr,value) \
- __asm__ __volatile__ (" movsb %0, %1@" : : "d" (value), "a" (addr));
+ __asm__ __volatile__ ("movesb %1,%0" : "=m" (addr) : "d" (value))
-/* Get a byte using the "movs" instruction */
+/* Get a byte using the "moves" instruction */
#define GET_CONTROL_BYTE(addr,value) \
- __asm__ __volatile__ (" movsb %1@, %0" : "=d" (value) : "a" (addr));
+ __asm__ __volatile__ ("movesb %1,%0" : "=d" (value) : "m" (addr))
-/* Set a (long)word using the "movs" instruction */
+/* Set a (long)word using the "moves" instruction */
#define SET_CONTROL_WORD(addr,value) \
- __asm__ __volatile__ (" movsl %0, %1@" : : "d" (value), "a" (addr));
+ __asm__ __volatile__ ("movesl %1,%0" : "=m" (addr) : "r" (value))
-/* Get a (long)word using the "movs" instruction */
+/* Get a (long)word using the "moves" instruction */
#define GET_CONTROL_WORD(addr,value) \
- __asm__ __volatile__ (" movsl %1@, %0" : "=d" (value) : "a" (addr));
+ __asm__ __volatile__ ("movesl %1,%0" : "=d" (value) : "m" (addr))
#endif
diff --git a/include/asm-m68k/mvme147hw.h b/include/asm-m68k/mvme147hw.h
index f57216b9e..195a50893 100644
--- a/include/asm-m68k/mvme147hw.h
+++ b/include/asm-m68k/mvme147hw.h
@@ -85,11 +85,12 @@ struct pcc_regs {
#define M147_SCC_A_ADDR 0xfffe3002
#define M147_SCC_B_ADDR 0xfffe3000
+#define M147_SCC_PCLK 5000000
#define MVME147_IRQ_SCSI_PORT 0x45
#define MVME147_IRQ_SCSI_DMA 0x46
-/* SCC interrupts, for MVME162 */
+/* SCC interrupts, for MVME147 */
#define MVME147_IRQ_TYPE_PRIO 0
#define MVME147_IRQ_SCC_BASE 0x60
diff --git a/include/asm-m68k/mvme16xhw.h b/include/asm-m68k/mvme16xhw.h
index 75a21d8a4..4102460fb 100644
--- a/include/asm-m68k/mvme16xhw.h
+++ b/include/asm-m68k/mvme16xhw.h
@@ -62,6 +62,7 @@ typedef struct {
#define MVME_SCC_A_ADDR 0xfff45005
#define MVME_SCC_B_ADDR 0xfff45001
+#define MVME_SCC_PCLK 10000000
#define MVME162_IRQ_TYPE_PRIO 0
diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h
index 6a3d9df66..23dd731c8 100644
--- a/include/asm-m68k/page.h
+++ b/include/asm-m68k/page.h
@@ -25,16 +25,14 @@
#ifndef __ASSEMBLY__
-#define STRICT_MM_TYPECHECKS
-
-#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
+#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
#define free_user_page(page, addr) free_page(addr)
/*
* We don't need to check for alignment etc.
*/
#ifdef CPU_M68040_OR_M68060_ONLY
-static inline void copy_page(unsigned long to, unsigned long from)
+static inline void copy_page(void *to, void *from)
{
unsigned long tmp;
@@ -49,11 +47,10 @@ static inline void copy_page(unsigned long to, unsigned long from)
);
}
-static inline void clear_page(unsigned long page)
+static inline void clear_page(void *page)
{
- unsigned long data, sp, tmp;
-
- sp = page;
+ unsigned long data, tmp;
+ void *sp = page;
data = 0;
@@ -75,11 +72,10 @@ static inline void clear_page(unsigned long page)
}
#else
-#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
-#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+#define clear_page(page) memset((page), 0, PAGE_SIZE)
+#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE)
#endif
-#ifdef STRICT_MM_TYPECHECKS
/*
* These are used to make use of C type-checking..
*/
@@ -98,55 +94,29 @@ typedef struct { unsigned long pgprot; } pgprot_t;
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
-#else
-/*
- * .. while these make it easier on the compiler
- */
-typedef unsigned long pte_t;
-typedef struct { unsigned long pmd[16]; } pmd_t;
-typedef unsigned long pgd_t;
-typedef unsigned long pgprot_t;
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-#define pte_val(x) (x)
-#define pmd_val(x) ((&x)->pmd[0])
-#define pgd_val(x) (x)
-#define pgprot_val(x) (x)
+#endif /* !__ASSEMBLY__ */
-#define __pte(x) (x)
-#define __pmd(x) ((pmd_t) { (x) } )
-#define __pgd(x) (x)
-#define __pgprot(x) (x)
+#include <asm/page_offset.h>
-#endif
+#define PAGE_OFFSET (PAGE_OFFSET_RAW)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
+#ifndef __ASSEMBLY__
-/* This handles the memory map.. */
#ifndef CONFIG_SUN3
-#define PAGE_OFFSET 0
+
+#ifdef CONFIG_SINGLE_MEMORY_CHUNK
+extern unsigned long m68k_memoffset;
+
+#define __pa(vaddr) ((unsigned long)(vaddr)+m68k_memoffset)
+#define __va(paddr) ((void *)((unsigned long)(paddr)-m68k_memoffset))
#else
-#define PAGE_OFFSET 0x0E000000
+#define __pa(vaddr) virt_to_phys((void *)vaddr)
+#define __va(paddr) phys_to_virt((unsigned long)paddr)
#endif
-#ifndef CONFIG_SUN3
-#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
-/*
- * A hacky workaround for the problems with mmap() of frame buffer
- * memory in the lower 16MB physical memoryspace.
- *
- * This is a short term solution, we will have to deal properly
- * with this in 2.3.x.
- */
-extern inline void *__va(unsigned long physaddr)
-{
-#ifdef CONFIG_AMIGA
- if (MACH_IS_AMIGA && (physaddr < 16*1024*1024))
- return (void *)0xffffffff;
- else
-#endif
- return (void *)(physaddr+PAGE_OFFSET);
-}
#else /* !CONFIG_SUN3 */
/* This #define is a horrible hack to suppress lots of warnings. --m */
#define __pa(x) ___pa((unsigned long)x)
@@ -172,9 +142,7 @@ static inline void *__va(unsigned long x)
}
#endif /* CONFIG_SUN3 */
-#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT)
-
-#endif /* !__ASSEMBLY__ */
+#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
#ifndef CONFIG_SUN3
#define BUG() do { \
@@ -192,6 +160,8 @@ static inline void *__va(unsigned long x)
BUG(); \
} while (0)
+#endif /* __ASSEMBLY__ */
+
#endif /* __KERNEL__ */
#endif /* _M68K_PAGE_H */
diff --git a/include/asm-m68k/page_offset.h b/include/asm-m68k/page_offset.h
new file mode 100644
index 000000000..39e30499c
--- /dev/null
+++ b/include/asm-m68k/page_offset.h
@@ -0,0 +1,9 @@
+#include <linux/config.h>
+
+/* This handles the memory map.. */
+#ifndef CONFIG_SUN3
+#define PAGE_OFFSET_RAW 0x00000000
+#else
+#define PAGE_OFFSET_RAW 0x0E000000
+#endif
+
diff --git a/include/asm-m68k/pci.h b/include/asm-m68k/pci.h
new file mode 100644
index 000000000..76915264d
--- /dev/null
+++ b/include/asm-m68k/pci.h
@@ -0,0 +1,38 @@
+#ifndef _ASM_M68K_PCI_H
+#define _ASM_M68K_PCI_H
+
+/*
+ * asm-m68k/pci_m68k.h - m68k specific PCI declarations.
+ *
+ * Written by Wout Klaren.
+ */
+
+struct pci_ops;
+
+/*
+ * Structure with hardware dependent information and functions of the
+ * PCI bus.
+ */
+
+struct pci_bus_info
+{
+ /*
+ * Resources of the PCI bus.
+ */
+
+ struct resource mem_space;
+ struct resource io_space;
+
+ /*
+ * System dependent functions.
+ */
+
+ struct pci_ops *m68k_pci_ops;
+
+ void (*fixup)(int pci_modify);
+ void (*conf_device)(unsigned char bus, unsigned char device_fn);
+};
+
+#define pcibios_assign_all_busses() 0
+
+#endif /* _ASM_M68K_PCI_H */
diff --git a/include/asm-m68k/pgalloc.h b/include/asm-m68k/pgalloc.h
new file mode 100644
index 000000000..3d2a2b87d
--- /dev/null
+++ b/include/asm-m68k/pgalloc.h
@@ -0,0 +1,399 @@
+#ifndef _M68K_PGALLOC_H
+#define _M68K_PGALLOC_H
+
+#include <asm/setup.h>
+#include <asm/virtconvert.h>
+
+extern struct pgtable_cache_struct {
+ unsigned long *pmd_cache;
+ unsigned long *pte_cache;
+/* This counts in units of pointer tables, of which can be eight per page. */
+ unsigned long pgtable_cache_sz;
+} quicklists;
+
+#define pgd_quicklist ((unsigned long *)0)
+#define pmd_quicklist (quicklists.pmd_cache)
+#define pte_quicklist (quicklists.pte_cache)
+/* This isn't accurate because of fragmentation of allocated pages for
+ pointer tables, but that should not be a problem. */
+#define pgtable_cache_size ((quicklists.pgtable_cache_sz+7)/8)
+
+extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset);
+extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset);
+
+extern pmd_t *get_pointer_table(void);
+extern int free_pointer_table(pmd_t *);
+
+extern inline pte_t *get_pte_fast(void)
+{
+ unsigned long *ret;
+
+ ret = pte_quicklist;
+ if (ret) {
+ pte_quicklist = (unsigned long *)*ret;
+ ret[0] = 0;
+ quicklists.pgtable_cache_sz -= 8;
+ }
+ return (pte_t *)ret;
+}
+
+extern inline void free_pte_fast(pte_t *pte)
+{
+ *(unsigned long *)pte = (unsigned long)pte_quicklist;
+ pte_quicklist = (unsigned long *)pte;
+ quicklists.pgtable_cache_sz += 8;
+}
+
+extern inline void free_pte_slow(pte_t *pte)
+{
+ cache_page((unsigned long)pte);
+ free_page((unsigned long) pte);
+}
+
+extern inline pmd_t *get_pmd_fast(void)
+{
+ unsigned long *ret;
+
+ ret = pmd_quicklist;
+ if (ret) {
+ pmd_quicklist = (unsigned long *)*ret;
+ ret[0] = 0;
+ quicklists.pgtable_cache_sz--;
+ }
+ return (pmd_t *)ret;
+}
+
+extern inline void free_pmd_fast(pmd_t *pmd)
+{
+ *(unsigned long *)pmd = (unsigned long)pmd_quicklist;
+ pmd_quicklist = (unsigned long *) pmd;
+ quicklists.pgtable_cache_sz++;
+}
+
+extern inline int free_pmd_slow(pmd_t *pmd)
+{
+ return free_pointer_table(pmd);
+}
+
+/* The pgd cache is folded into the pmd cache, so these are dummy routines. */
+extern inline pgd_t *get_pgd_fast(void)
+{
+ return (pgd_t *)0;
+}
+
+extern inline void free_pgd_fast(pgd_t *pgd)
+{
+}
+
+extern inline void free_pgd_slow(pgd_t *pgd)
+{
+}
+
+extern void __bad_pte(pmd_t *pmd);
+extern void __bad_pmd(pgd_t *pgd);
+
+extern inline void pte_free(pte_t *pte)
+{
+ free_pte_fast(pte);
+}
+
+extern inline pte_t *pte_alloc(pmd_t *pmd, unsigned long address)
+{
+ address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+ if (pmd_none(*pmd)) {
+ pte_t *page = get_pte_fast();
+
+ if (!page)
+ return get_pte_slow(pmd, address);
+ pmd_set(pmd,page);
+ return page + address;
+ }
+ if (pmd_bad(*pmd)) {
+ __bad_pte(pmd);
+ return NULL;
+ }
+ return (pte_t *)__pmd_page(*pmd) + address;
+}
+
+extern inline void pmd_free(pmd_t *pmd)
+{
+ free_pmd_fast(pmd);
+}
+
+extern inline pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address)
+{
+ address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
+ if (pgd_none(*pgd)) {
+ pmd_t *page = get_pmd_fast();
+
+ if (!page)
+ return get_pmd_slow(pgd, address);
+ pgd_set(pgd, page);
+ return page + address;
+ }
+ if (pgd_bad(*pgd)) {
+ __bad_pmd(pgd);
+ return NULL;
+ }
+ return (pmd_t *)__pgd_page(*pgd) + address;
+}
+
+extern inline void pte_free_kernel(pte_t *pte)
+{
+ free_pte_fast(pte);
+}
+
+extern inline pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address)
+{
+ return pte_alloc(pmd, address);
+}
+
+extern inline void pmd_free_kernel(pmd_t *pmd)
+{
+ free_pmd_fast(pmd);
+}
+
+extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address)
+{
+ return pmd_alloc(pgd, address);
+}
+
+extern inline void pgd_free(pgd_t *pgd)
+{
+ free_pmd_fast((pmd_t *)pgd);
+}
+
+extern inline pgd_t *pgd_alloc(void)
+{
+ pgd_t *pgd = (pgd_t *)get_pmd_fast();
+ if (!pgd)
+ pgd = (pgd_t *)get_pointer_table();
+ return pgd;
+}
+
+extern int do_check_pgt_cache(int, int);
+
+extern inline void set_pgdir(unsigned long address, pgd_t entry)
+{
+}
+
+
+/*
+ * Cache handling functions
+ */
+
+#define flush_icache() \
+({ \
+ if (CPU_IS_040_OR_060) \
+ __asm__ __volatile__("nop\n\t" \
+ ".chip 68040\n\t" \
+ "cinva %%ic\n\t" \
+ ".chip 68k" : ); \
+ else { \
+ unsigned long _tmp; \
+ __asm__ __volatile__("movec %%cacr,%0\n\t" \
+ "orw %1,%0\n\t" \
+ "movec %0,%%cacr" \
+ : "=&d" (_tmp) \
+ : "id" (FLUSH_I)); \
+ } \
+})
+
+/*
+ * invalidate the cache for the specified memory range.
+ * It starts at the physical address specified for
+ * the given number of bytes.
+ */
+extern void cache_clear(unsigned long paddr, int len);
+/*
+ * push any dirty cache in the specified memory range.
+ * It starts at the physical address specified for
+ * the given number of bytes.
+ */
+extern void cache_push(unsigned long paddr, int len);
+
+/*
+ * push and invalidate pages in the specified user virtual
+ * memory range.
+ */
+extern void cache_push_v(unsigned long vaddr, int len);
+
+/* cache code */
+#define FLUSH_I_AND_D (0x00000808)
+#define FLUSH_I (0x00000008)
+
+/* This is needed whenever the virtual mapping of the current
+ process changes. */
+#define __flush_cache_all() \
+({ \
+ if (CPU_IS_040_OR_060) \
+ __asm__ __volatile__("nop\n\t" \
+ ".chip 68040\n\t" \
+ "cpusha %dc\n\t" \
+ ".chip 68k"); \
+ else { \
+ unsigned long _tmp; \
+ __asm__ __volatile__("movec %%cacr,%0\n\t" \
+ "orw %1,%0\n\t" \
+ "movec %0,%%cacr" \
+ : "=&d" (_tmp) \
+ : "di" (FLUSH_I_AND_D)); \
+ } \
+})
+
+#define __flush_cache_030() \
+({ \
+ if (CPU_IS_020_OR_030) { \
+ unsigned long _tmp; \
+ __asm__ __volatile__("movec %%cacr,%0\n\t" \
+ "orw %1,%0\n\t" \
+ "movec %0,%%cacr" \
+ : "=&d" (_tmp) \
+ : "di" (FLUSH_I_AND_D)); \
+ } \
+})
+
+#define flush_cache_all() __flush_cache_all()
+
+extern inline void flush_cache_mm(struct mm_struct *mm)
+{
+ if (mm == current->mm)
+ __flush_cache_030();
+}
+
+extern inline void flush_cache_range(struct mm_struct *mm,
+ unsigned long start,
+ unsigned long end)
+{
+ if (mm == current->mm)
+ __flush_cache_030();
+}
+
+extern inline void flush_cache_page(struct vm_area_struct *vma,
+ unsigned long vmaddr)
+{
+ if (vma->vm_mm == current->mm)
+ __flush_cache_030();
+}
+
+/* Push the page at kernel virtual address and clear the icache */
+#define flush_page_to_ram(page) __flush_page_to_ram(page_address(page))
+extern inline void __flush_page_to_ram(unsigned long address)
+{
+ if (CPU_IS_040_OR_060) {
+ __asm__ __volatile__("nop\n\t"
+ ".chip 68040\n\t"
+ "cpushp %%dc,(%0)\n\t"
+ "cinvp %%ic,(%0)\n\t"
+ ".chip 68k"
+ : : "a" (__pa((void *)address)));
+ } else {
+ unsigned long _tmp;
+ __asm__ __volatile__("movec %%cacr,%0\n\t"
+ "orw %1,%0\n\t"
+ "movec %0,%%cacr"
+ : "=&d" (_tmp)
+ : "di" (FLUSH_I));
+ }
+}
+
+/* Push n pages at kernel virtual address and clear the icache */
+extern inline void flush_icache_range (unsigned long address,
+ unsigned long endaddr)
+{
+ if (CPU_IS_040_OR_060) {
+ short n = (endaddr - address + PAGE_SIZE - 1) / PAGE_SIZE;
+
+ while (--n >= 0) {
+ __asm__ __volatile__("nop\n\t"
+ ".chip 68040\n\t"
+ "cpushp %%dc,(%0)\n\t"
+ "cinvp %%ic,(%0)\n\t"
+ ".chip 68k"
+ : : "a" (virt_to_phys((void *)address)));
+ address += PAGE_SIZE;
+ }
+ } else {
+ unsigned long tmp;
+ __asm__ __volatile__("movec %%cacr,%0\n\t"
+ "orw %1,%0\n\t"
+ "movec %0,%%cacr"
+ : "=&d" (tmp)
+ : "di" (FLUSH_I));
+ }
+}
+
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+ if (CPU_IS_040_OR_060)
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflushan\n\t"
+ ".chip 68k");
+ else
+ __asm__ __volatile__("pflush #0,#4");
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+ if (CPU_IS_040_OR_060) {
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflush (%0)\n\t"
+ ".chip 68k"
+ : : "a" (addr));
+ } else
+ __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+ if (CPU_IS_040_OR_060)
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflusha\n\t"
+ ".chip 68k");
+ else
+ __asm__ __volatile__("pflusha");
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+ if (mm == current->mm)
+ __flush_tlb();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+ if (vma->vm_mm == current->mm)
+ __flush_tlb_one(addr);
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+ unsigned long start, unsigned long end)
+{
+ if (mm == current->mm)
+ __flush_tlb();
+}
+
+extern inline void flush_tlb_kernel_page(unsigned long addr)
+{
+ if (CPU_IS_040_OR_060) {
+ mm_segment_t old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflush (%0)\n\t"
+ ".chip 68k"
+ : : "a" (addr));
+ set_fs(old_fs);
+ } else
+ __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
+}
+
+#endif /* _M68K_PGALLOC_H */
diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h
index c94acfc38..9df773f9f 100644
--- a/include/asm-m68k/pgtable.h
+++ b/include/asm-m68k/pgtable.h
@@ -15,226 +15,6 @@
#include <asm/virtconvert.h>
-/*
- * Cache handling functions
- */
-
-#define flush_icache() \
-do { \
- if (CPU_IS_040_OR_060) \
- asm __volatile__ ("nop\n\t" \
- ".chip 68040\n\t" \
- "cinva %%ic\n\t" \
- ".chip 68k" : ); \
- else { \
- unsigned long _tmp; \
- asm __volatile__ ("movec %%cacr,%0\n\t" \
- "orw %1,%0\n\t" \
- "movec %0,%%cacr" \
- : "=&d" (_tmp) \
- : "id" (FLUSH_I)); \
- } \
-} while (0)
-
-/*
- * invalidate the cache for the specified memory range.
- * It starts at the physical address specified for
- * the given number of bytes.
- */
-extern void cache_clear (unsigned long paddr, int len);
-/*
- * push any dirty cache in the specified memory range.
- * It starts at the physical address specified for
- * the given number of bytes.
- */
-extern void cache_push (unsigned long paddr, int len);
-
-/*
- * push and invalidate pages in the specified user virtual
- * memory range.
- */
-extern void cache_push_v (unsigned long vaddr, int len);
-
-/* cache code */
-#define FLUSH_I_AND_D (0x00000808)
-#define FLUSH_I (0x00000008)
-
-/* This is needed whenever the virtual mapping of the current
- process changes. */
-#define __flush_cache_all() \
- do { \
- if (CPU_IS_040_OR_060) \
- __asm__ __volatile__ ("nop\n\t" \
- ".chip 68040\n\t" \
- "cpusha %dc\n\t" \
- ".chip 68k"); \
- else { \
- unsigned long _tmp; \
- __asm__ __volatile__ ("movec %%cacr,%0\n\t" \
- "orw %1,%0\n\t" \
- "movec %0,%%cacr" \
- : "=&d" (_tmp) \
- : "di" (FLUSH_I_AND_D)); \
- } \
- } while (0)
-
-#define __flush_cache_030() \
- do { \
- if (CPU_IS_020_OR_030) { \
- unsigned long _tmp; \
- __asm__ __volatile__ ("movec %%cacr,%0\n\t" \
- "orw %1,%0\n\t" \
- "movec %0,%%cacr" \
- : "=&d" (_tmp) \
- : "di" (FLUSH_I_AND_D)); \
- } \
- } while (0)
-
-#define flush_cache_all() __flush_cache_all()
-
-extern inline void flush_cache_mm(struct mm_struct *mm)
-{
- if (mm == current->mm)
- __flush_cache_030();
-}
-
-extern inline void flush_cache_range(struct mm_struct *mm,
- unsigned long start,
- unsigned long end)
-{
- if (mm == current->mm)
- __flush_cache_030();
-}
-
-extern inline void flush_cache_page(struct vm_area_struct *vma,
- unsigned long vmaddr)
-{
- if (vma->vm_mm == current->mm)
- __flush_cache_030();
-}
-
-/* Push the page at kernel virtual address and clear the icache */
-extern inline void flush_page_to_ram (unsigned long address)
-{
- if (CPU_IS_040_OR_060) {
- __asm__ __volatile__ ("nop\n\t"
- ".chip 68040\n\t"
- "cpushp %%dc,(%0)\n\t"
- "cinvp %%ic,(%0)\n\t"
- ".chip 68k"
- : : "a" (virt_to_phys((void *)address)));
- }
- else {
- unsigned long _tmp;
- __asm volatile ("movec %%cacr,%0\n\t"
- "orw %1,%0\n\t"
- "movec %0,%%cacr"
- : "=&d" (_tmp)
- : "di" (FLUSH_I));
- }
-}
-
-/* Push n pages at kernel virtual address and clear the icache */
-extern inline void flush_icache_range (unsigned long address,
- unsigned long endaddr)
-{
- if (CPU_IS_040_OR_060) {
- short n = (endaddr - address + PAGE_SIZE - 1) / PAGE_SIZE;
-
- while (n--) {
- __asm__ __volatile__ ("nop\n\t"
- ".chip 68040\n\t"
- "cpushp %%dc,(%0)\n\t"
- "cinvp %%ic,(%0)\n\t"
- ".chip 68k"
- : : "a" (virt_to_phys((void *)address)));
- address += PAGE_SIZE;
- }
- }
- else {
- unsigned long _tmp;
- __asm volatile ("movec %%cacr,%0\n\t"
- "orw %1,%0\n\t"
- "movec %0,%%cacr"
- : "=&d" (_tmp)
- : "di" (FLUSH_I));
- }
-}
-
-
-/*
- * flush all user-space atc entries.
- */
-static inline void __flush_tlb(void)
-{
- if (CPU_IS_040_OR_060)
- __asm__ __volatile__(".chip 68040\n\t"
- "pflushan\n\t"
- ".chip 68k");
- else
- __asm__ __volatile__("pflush #0,#4");
-}
-
-static inline void __flush_tlb_one(unsigned long addr)
-{
- if (CPU_IS_040_OR_060) {
- __asm__ __volatile__(".chip 68040\n\t"
- "pflush (%0)\n\t"
- ".chip 68k"
- : : "a" (addr));
- } else
- __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
-}
-
-#define flush_tlb() __flush_tlb()
-
-/*
- * flush all atc entries (both kernel and user-space entries).
- */
-static inline void flush_tlb_all(void)
-{
- if (CPU_IS_040_OR_060)
- __asm__ __volatile__(".chip 68040\n\t"
- "pflusha\n\t"
- ".chip 68k");
- else
- __asm__ __volatile__("pflusha");
-}
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
- if (mm == current->mm)
- __flush_tlb();
-}
-
-static inline void flush_tlb_page(struct vm_area_struct *vma,
- unsigned long addr)
-{
- if (vma->vm_mm == current->mm)
- __flush_tlb_one(addr);
-}
-
-static inline void flush_tlb_range(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- if (mm == current->mm)
- __flush_tlb();
-}
-
-extern inline void flush_tlb_kernel_page(unsigned long addr)
-{
- if (CPU_IS_040_OR_060) {
- mm_segment_t old_fs = get_fs();
- set_fs(KERNEL_DS);
- __asm__ __volatile__(".chip 68040\n\t"
- "pflush (%0)\n\t"
- ".chip 68k"
- : : "a" (addr));
- set_fs(old_fs);
- } else
- __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
-}
-
/* Certain architectures need to do special things when pte's
* within a page table are directly modified. Thus, the following
* hook is made available.
@@ -391,7 +171,7 @@ extern pte_t * __bad_pagetable(void);
#define BAD_PAGETABLE __bad_pagetable()
#define BAD_PAGE __bad_page()
-#define ZERO_PAGE(vaddr) empty_zero_page
+#define ZERO_PAGE(vaddr) (mem_map + MAP_NR(empty_zero_page))
/* number of bits that fit into a memory pointer */
#define BITS_PER_PTR (8*sizeof(unsigned long))
@@ -403,67 +183,78 @@ extern pte_t * __bad_pagetable(void);
/* 64-bit machines, beware! SRB. */
#define SIZEOF_PTR_LOG2 2
-/* to find an entry in a page-table */
-#define PAGE_PTR(address) \
-((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
-
/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
-#define mk_pte(page, pgprot) \
-({ pte_t __pte; pte_val(__pte) = virt_to_phys((void *)page) + pgprot_val(pgprot); __pte; })
+#define __mk_pte(page, pgprot) \
+({ \
+ pte_t __pte; \
+ \
+ pte_val(__pte) = __pa((void *)page) + pgprot_val(pgprot); \
+ __pte; \
+})
+#define mk_pte(page, pgprot) __mk_pte(page_address(page), (pgprot))
#define mk_pte_phys(physpage, pgprot) \
-({ pte_t __pte; pte_val(__pte) = (unsigned long)physpage + pgprot_val(pgprot); __pte; })
+({ \
+ pte_t __pte; \
+ \
+ pte_val(__pte) = (physpage) + pgprot_val(pgprot); \
+ __pte; \
+})
extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
{
- int i;
- unsigned long ptbl;
- ptbl = virt_to_phys(ptep) | _PAGE_TABLE | _PAGE_ACCESSED;
- for (i = 0; i < 16; i++, ptbl += (sizeof(pte_t)*PTRS_PER_PTE/16))
- pmdp->pmd[i] = ptbl;
+ unsigned long ptbl = virt_to_phys(ptep) | _PAGE_TABLE | _PAGE_ACCESSED;
+ unsigned long *ptr = pmdp->pmd;
+ short i = 16;
+ while (--i >= 0) {
+ *ptr++ = ptbl;
+ ptbl += (sizeof(pte_t)*PTRS_PER_PTE/16);
+ }
}
extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
-{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | virt_to_phys(pmdp); }
-
-extern inline unsigned long pte_page(pte_t pte)
-{ return (unsigned long)phys_to_virt(pte_val(pte) & PAGE_MASK); }
-
-extern inline unsigned long pmd_page2(pmd_t *pmd)
-{ return (unsigned long)phys_to_virt(pmd_val(*pmd) & _TABLE_MASK); }
-#define pmd_page(pmd) pmd_page2(&(pmd))
-
-extern inline unsigned long pgd_page(pgd_t pgd)
-{ return (unsigned long)phys_to_virt(pgd_val(pgd) & _TABLE_MASK); }
-
-extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
-extern inline int pte_present(pte_t pte) { return pte_val(pte) & (_PAGE_PRESENT | _PAGE_FAKE_SUPER); }
-extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; }
-
-extern inline int pmd_none2(pmd_t *pmd) { return !pmd_val(*pmd); }
-#define pmd_none(pmd) pmd_none2(&(pmd))
-extern inline int pmd_bad2(pmd_t *pmd) { return (pmd_val(*pmd) & _DESCTYPE_MASK) != _PAGE_TABLE; }
-#define pmd_bad(pmd) pmd_bad2(&(pmd))
-extern inline int pmd_present2(pmd_t *pmd) { return pmd_val(*pmd) & _PAGE_TABLE; }
-#define pmd_present(pmd) pmd_present2(&(pmd))
-extern inline void pmd_clear(pmd_t * pmdp)
-{
- short i;
-
- for (i = 15; i >= 0; i--)
- pmdp->pmd[i] = 0;
-}
-
-extern inline int pgd_none(pgd_t pgd) { return !pgd_val(pgd); }
-extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE; }
-extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_TABLE; }
-
-extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; }
+{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp); }
+
+#define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK))
+#define __pmd_page(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK))
+#define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _TABLE_MASK))
+
+#define pte_none(pte) (!pte_val(pte))
+#define pte_present(pte) (pte_val(pte) & (_PAGE_PRESENT | _PAGE_FAKE_SUPER))
+#define pte_clear(ptep) ({ pte_val(*(ptep)) = 0; })
+#define pte_pagenr(pte) ((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)
+
+#define pmd_none(pmd) (!pmd_val(pmd))
+#define pmd_bad(pmd) ((pmd_val(pmd) & _DESCTYPE_MASK) != _PAGE_TABLE)
+#define pmd_present(pmd) (pmd_val(pmd) & _PAGE_TABLE)
+#define pmd_clear(pmdp) ({ \
+ unsigned long *__ptr = pmdp->pmd; \
+ short __i = 16; \
+ while (--__i >= 0) \
+ *__ptr++ = 0; \
+})
+
+#define pgd_none(pgd) (!pgd_val(pgd))
+#define pgd_bad(pgd) ((pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE)
+#define pgd_present(pgd) (pgd_val(pgd) & _PAGE_TABLE)
+#define pgd_clear(pgdp) ({ pgd_val(*pgdp) = 0; })
+
+/* Permanent address of a page. */
+#define page_address(page) ({ if (!(page)->virtual) BUG(); (page)->virtual; })
+#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define pte_page(pte) (mem_map+pte_pagenr(pte))
+
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %p(%08lx).\n", __FILE__, __LINE__, &(e), pte_val(e))
+#define pmd_ERROR(e) \
+ printk("%s:%d: bad pmd %p(%08lx).\n", __FILE__, __LINE__, &(e), pmd_val(e))
+#define pgd_ERROR(e) \
+ printk("%s:%d: bad pgd %p(%08lx).\n", __FILE__, __LINE__, &(e), pgd_val(e))
/*
* The following only work if pte_present() is true.
@@ -512,13 +303,13 @@ extern inline pgd_t * pgd_offset_k(unsigned long address)
/* Find an entry in the second-level page table.. */
extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
{
- return (pmd_t *) pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1));
+ return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1));
}
/* Find an entry in the third-level page table.. */
extern inline pte_t * pte_offset(pmd_t * pmdp, unsigned long address)
{
- return (pte_t *) pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
+ return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
}
/*
@@ -559,178 +350,6 @@ static inline void cache_page (unsigned long vaddr)
}
}
-extern struct pgtable_cache_struct {
- unsigned long *pmd_cache;
- unsigned long *pte_cache;
-/* This counts in units of pointer tables, of which can be eight per page. */
- unsigned long pgtable_cache_sz;
-} quicklists;
-
-#define pgd_quicklist ((unsigned long *)0)
-#define pmd_quicklist (quicklists.pmd_cache)
-#define pte_quicklist (quicklists.pte_cache)
-/* This isn't accurate because of fragmentation of allocated pages for
- pointer tables, but that should not be a problem. */
-#define pgtable_cache_size ((quicklists.pgtable_cache_sz+7)/8)
-
-extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset);
-extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset);
-
-extern pmd_t *get_pointer_table(void);
-extern int free_pointer_table(pmd_t *);
-
-extern __inline__ pte_t *get_pte_fast(void)
-{
- unsigned long *ret;
-
- ret = pte_quicklist;
- if (ret) {
- pte_quicklist = (unsigned long *)*ret;
- ret[0] = 0;
- quicklists.pgtable_cache_sz -= 8;
- }
- return (pte_t *)ret;
-}
-
-extern __inline__ void free_pte_fast(pte_t *pte)
-{
- *(unsigned long *)pte = (unsigned long)pte_quicklist;
- pte_quicklist = (unsigned long *)pte;
- quicklists.pgtable_cache_sz += 8;
-}
-
-extern __inline__ void free_pte_slow(pte_t *pte)
-{
- cache_page((unsigned long)pte);
- free_page((unsigned long) pte);
-}
-
-extern __inline__ pmd_t *get_pmd_fast(void)
-{
- unsigned long *ret;
-
- ret = pmd_quicklist;
- if (ret) {
- pmd_quicklist = (unsigned long *)*ret;
- ret[0] = 0;
- quicklists.pgtable_cache_sz--;
- }
- return (pmd_t *)ret;
-}
-
-extern __inline__ void free_pmd_fast(pmd_t *pmd)
-{
- *(unsigned long *)pmd = (unsigned long)pmd_quicklist;
- pmd_quicklist = (unsigned long *) pmd;
- quicklists.pgtable_cache_sz++;
-}
-
-extern __inline__ int free_pmd_slow(pmd_t *pmd)
-{
- return free_pointer_table(pmd);
-}
-
-/* The pgd cache is folded into the pmd cache, so these are dummy routines. */
-extern __inline__ pgd_t *get_pgd_fast(void)
-{
- return (pgd_t *)0;
-}
-
-extern __inline__ void free_pgd_fast(pgd_t *pgd)
-{
-}
-
-extern __inline__ void free_pgd_slow(pgd_t *pgd)
-{
-}
-
-extern void __bad_pte(pmd_t *pmd);
-extern void __bad_pmd(pgd_t *pgd);
-
-extern inline void pte_free(pte_t * pte)
-{
- free_pte_fast(pte);
-}
-
-extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
-{
- address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
- if (pmd_none(*pmd)) {
- pte_t * page = get_pte_fast();
-
- if (!page)
- return get_pte_slow(pmd, address);
- pmd_set(pmd,page);
- return page + address;
- }
- if (pmd_bad(*pmd)) {
- __bad_pte(pmd);
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + address;
-}
-
-extern inline void pmd_free(pmd_t * pmd)
-{
- free_pmd_fast(pmd);
-}
-
-extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
-{
- address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
- if (pgd_none(*pgd)) {
- pmd_t *page = get_pmd_fast();
-
- if (!page)
- return get_pmd_slow(pgd, address);
- pgd_set(pgd, page);
- return page + address;
- }
- if (pgd_bad(*pgd)) {
- __bad_pmd(pgd);
- return NULL;
- }
- return (pmd_t *) pgd_page(*pgd) + address;
-}
-
-extern inline void pte_free_kernel(pte_t * pte)
-{
- free_pte_fast(pte);
-}
-
-extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
-{
- return pte_alloc(pmd, address);
-}
-
-extern inline void pmd_free_kernel(pmd_t * pmd)
-{
- free_pmd_fast(pmd);
-}
-
-extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address)
-{
- return pmd_alloc(pgd, address);
-}
-
-extern inline void pgd_free(pgd_t * pgd)
-{
- free_pmd_fast((pmd_t *)pgd);
-}
-
-extern inline pgd_t * pgd_alloc(void)
-{
- pgd_t *pgd = (pgd_t *)get_pmd_fast();
- if (!pgd)
- pgd = (pgd_t *)get_pointer_table();
- return pgd;
-}
-
-extern int do_check_pgt_cache(int, int);
-
-extern inline void set_pgdir(unsigned long address, pgd_t entry)
-{
-}
/*
* Check if the addr/len goes up to the end of a physical
@@ -760,21 +379,12 @@ extern inline void update_mmu_cache(struct vm_area_struct * vma,
{
}
-/*
- * I don't know what is going on here, but since these were changed,
- * swapping hasn't been working on the 68040.
- */
-/* With the new handling of PAGE_NONE the old definitions definitely
- don't work any more. */
-
-#define SWP_TYPE(entry) (((entry) >> 2) & 0x7f)
-#if 0
-#define SWP_OFFSET(entry) ((entry) >> 9)
-#define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << 9))
-#else
-#define SWP_OFFSET(entry) ((entry) >> PAGE_SHIFT)
-#define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << PAGE_SHIFT))
-#endif
+/* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */
+#define SWP_TYPE(x) (((x).val >> 1) & 0xff)
+#define SWP_OFFSET(x) ((x).val >> 10)
+#define SWP_ENTRY(type, offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 10) })
+#define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define swp_entry_to_pte(x) ((pte_t) { (x).val })
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-m68k/poll.h b/include/asm-m68k/poll.h
index f66153a74..32dcf6490 100644
--- a/include/asm-m68k/poll.h
+++ b/include/asm-m68k/poll.h
@@ -11,6 +11,7 @@
#define POLLWRNORM POLLOUT
#define POLLRDBAND 128
#define POLLWRBAND 256
+#define POLLMSG 0x0400
struct pollfd {
int fd;
diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h
index cb4f38230..16ab57862 100644
--- a/include/asm-m68k/semaphore.h
+++ b/include/asm-m68k/semaphore.h
@@ -1,6 +1,8 @@
#ifndef _M68K_SEMAPHORE_H
#define _M68K_SEMAPHORE_H
+#ifndef __ASSEMBLY__
+
#include <linux/linkage.h>
#include <linux/wait.h>
#include <linux/spinlock.h>
@@ -9,13 +11,14 @@
#include <asm/atomic.h>
/*
- * SMP- and interrupt-safe semaphores..
+ * Interrupt-safe semaphores..
*
* (C) Copyright 1996 Linus Torvalds
*
* m68k version by Andreas Schwab
*/
+
struct semaphore {
atomic_t count;
atomic_t waking;
@@ -180,4 +183,174 @@ extern inline void up(struct semaphore * sem)
: "memory");
}
+
+/* rw mutexes (should that be mutices? =) -- throw rw
+ * spinlocks and semaphores together, and this is what we
+ * end up with...
+ *
+ * m68k version by Roman Zippel
+ */
+
+struct rw_semaphore {
+ atomic_t count;
+ volatile unsigned char write_bias_granted;
+ volatile unsigned char read_bias_granted;
+ volatile unsigned char pad1;
+ volatile unsigned char pad2;
+ wait_queue_head_t wait;
+ wait_queue_head_t write_bias_wait;
+#if WAITQUEUE_DEBUG
+ long __magic;
+ atomic_t readers;
+ atomic_t writers;
+#endif
+};
+#endif /* __ASSEMBLY__ */
+
+#define RW_LOCK_BIAS 0x01000000
+
+#ifndef __ASSEMBLY__
+
+extern inline void down_read(struct rw_semaphore *sem)
+{
+ register struct rw_semaphore *__sem __asm__ ("%a1") = sem;
+
+#if WAITQUEUE_DEBUG
+ if (sem->__magic != (long)&sem->__magic)
+ BUG();
+#endif
+ __asm__ __volatile__(
+ "| atomic down_read operation\n\t"
+ "subql #1,%0@\n\t"
+ "jmi 2f\n"
+ "1:\n"
+ ".section .text.lock,\"ax\"\n"
+ ".even\n"
+ "2:\n\t"
+ "pea 1b\n\t"
+ "jbra __down_read_failed\n"
+ ".previous"
+ : /* no outputs */
+ : "a" (__sem)
+ : "memory");
+#if WAITQUEUE_DEBUG
+ if (sem->write_bias_granted)
+ BUG();
+ if (atomic_read(&sem->writers))
+ BUG();
+ atomic_inc(&sem->readers);
+#endif
+}
+
+extern inline void down_write(struct rw_semaphore *sem)
+{
+ register struct rw_semaphore *__sem __asm__ ("%a1") = sem;
+
+#if WAITQUEUE_DEBUG
+ if (sem->__magic != (long)&sem->__magic)
+ BUG();
+#endif
+ __asm__ __volatile__(
+ "| atomic down_write operation\n\t"
+ "subl %1,%0@\n\t"
+ "jne 2f\n"
+ "1:\n"
+ ".section .text.lock,\"ax\"\n"
+ ".even\n"
+ "2:\n\t"
+ "pea 1b\n\t"
+ "jbra __down_write_failed\n"
+ ".previous"
+ : /* no outputs */
+ : "a" (__sem), "id" (RW_LOCK_BIAS)
+ : "memory");
+#if WAITQUEUE_DEBUG
+ if (atomic_read(&sem->writers))
+ BUG();
+ if (atomic_read(&sem->readers))
+ BUG();
+ if (sem->read_bias_granted)
+ BUG();
+ if (sem->write_bias_granted)
+ BUG();
+ atomic_inc(&sem->writers);
+#endif
+}
+
+/* When a reader does a release, the only significant
+ * case is when there was a writer waiting, and we've
+ * bumped the count to 0: we must wake the writer up.
+ */
+extern inline void __up_read(struct rw_semaphore *sem)
+{
+ register struct rw_semaphore *__sem __asm__ ("%a1") = sem;
+
+ __asm__ __volatile__(
+ "| atomic up_read operation\n\t"
+ "addql #1,%0@\n\t"
+ "jeq 2f\n"
+ "1:\n"
+ ".section .text.lock,\"ax\"\n"
+ ".even\n"
+ "2:\n\t"
+ "pea 1b\n\t"
+ "jbra __rwsem_wake\n"
+ ".previous"
+ : /* no outputs */
+ : "a" (__sem)
+ : "memory");
+}
+
+extern inline void up_read(struct rw_semaphore *sem)
+{
+#if WAITQUEUE_DEBUG
+ if (sem->write_bias_granted)
+ BUG();
+ if (atomic_read(&sem->writers))
+ BUG();
+ atomic_dec(&sem->readers);
+#endif
+ __up_read(sem);
+}
+
+/* releasing the writer is easy -- just release it and
+ * wake up any sleepers.
+ */
+extern inline void __up_write(struct rw_semaphore *sem)
+{
+ register struct rw_semaphore *__sem __asm__ ("%a1") = sem;
+
+ __asm__ __volatile__(
+ "| atomic up_write operation\n\t"
+ "addl %1,%0@\n\t"
+ "jcs 2f\n"
+ "1:\n"
+ ".section .text.lock,\"ax\"\n"
+ ".even\n"
+ "2:\n\t"
+ "pea 1b\n\t"
+ "jbra __rwsem_wake\n"
+ ".previous"
+ : /* no outputs */
+ : "a" (__sem), "id" (RW_LOCK_BIAS)
+ : "memory");
+}
+
+extern inline void up_write(struct rw_semaphore *sem)
+{
+#if WAITQUEUE_DEBUG
+ if (sem->read_bias_granted)
+ BUG();
+ if (sem->write_bias_granted)
+ BUG();
+ if (atomic_read(&sem->readers))
+ BUG();
+ if (atomic_read(&sem->writers) != 1)
+ BUG();
+ atomic_dec(&sem->writers);
+#endif
+ __up_write(sem);
+}
+#endif /* __ASSEMBLY__ */
+
#endif
diff --git a/include/asm-m68k/setup.h b/include/asm-m68k/setup.h
index b2b11ed76..6d198bc5f 100644
--- a/include/asm-m68k/setup.h
+++ b/include/asm-m68k/setup.h
@@ -246,6 +246,9 @@ extern unsigned long m68k_machtype;
extern unsigned long m68k_cputype;
extern unsigned long m68k_fputype;
extern unsigned long m68k_mmutype; /* Not really used yet */
+#ifdef CONFIG_VME
+extern unsigned long vme_brdtype;
+#endif
/*
* m68k_is040or060 is != 0 for a '040 or higher;
diff --git a/include/asm-m68k/siginfo.h b/include/asm-m68k/siginfo.h
index 2dac2b063..4061e6f72 100644
--- a/include/asm-m68k/siginfo.h
+++ b/include/asm-m68k/siginfo.h
@@ -24,8 +24,7 @@ typedef struct siginfo {
/* kill() */
struct {
pid_t _pid; /* sender's pid */
- old_uid_t _uid; /* backwards compatibility */
- uid_t _uid32; /* sender's uid */
+ uid_t _uid; /* sender's uid */
} _kill;
/* POSIX.1b timers */
@@ -37,19 +36,17 @@ typedef struct siginfo {
/* POSIX.1b signals */
struct {
pid_t _pid; /* sender's pid */
- old_uid_t _uid; /* backwards compatibility */
+ uid_t _uid; /* sender's uid */
sigval_t _sigval;
- uid_t _uid32; /* sender's uid */
} _rt;
/* SIGCHLD */
struct {
pid_t _pid; /* which child */
- old_uid_t _uid; /* backwards compatibility */
+ uid_t _uid; /* sender's uid */
int _status; /* exit code */
clock_t _utime;
clock_t _stime;
- uid_t _uid32; /* sender's uid */
} _sigchld;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
@@ -65,18 +62,11 @@ typedef struct siginfo {
} _sifields;
} siginfo_t;
-#define UID16_SIGINFO_COMPAT_NEEDED
-
/*
* How these fields are to be accessed.
*/
#define si_pid _sifields._kill._pid
-#ifdef __KERNEL__
-#define si_uid _sifields._kill._uid32
-#define si_uid16 _sifields._kill._uid
-#else
#define si_uid _sifields._kill._uid
-#endif /* __KERNEL__ */
#define si_status _sifields._sigchld._status
#define si_utime _sifields._sigchld._utime
#define si_stime _sifields._sigchld._stime
diff --git a/include/asm-m68k/stat.h b/include/asm-m68k/stat.h
index c2145c33d..b28ce37c5 100644
--- a/include/asm-m68k/stat.h
+++ b/include/asm-m68k/stat.h
@@ -38,8 +38,40 @@ struct stat {
unsigned long __unused5;
};
-/* stat64 struct goes here -- someone please make
- * it mesh with whatever glibc does in userland on
- * m68k's.
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
*/
+struct stat64 {
+ unsigned short st_dev;
+ unsigned char __pad0[10];
+
+ unsigned long st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ unsigned long st_uid;
+ unsigned long st_gid;
+
+ unsigned short st_rdev;
+ unsigned char __pad3[10];
+
+ long long st_size;
+ unsigned long st_blksize;
+
+ unsigned long st_blocks; /* Number 512-byte blocks allocated. */
+ unsigned long __pad4; /* future possible st_blocks high bits */
+
+ unsigned long st_atime;
+ unsigned long __pad5;
+
+ unsigned long st_mtime;
+ unsigned long __pad6;
+
+ unsigned long st_ctime;
+ unsigned long __pad7; /* will be high 32 bits of ctime someday */
+
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
#endif /* _M68K_STAT_H */
diff --git a/include/asm-m68k/system.h b/include/asm-m68k/system.h
index 7d1afa286..7b6ae7d16 100644
--- a/include/asm-m68k/system.h
+++ b/include/asm-m68k/system.h
@@ -4,6 +4,7 @@
#include <linux/config.h> /* get configuration macros */
#include <linux/linkage.h>
#include <asm/segment.h>
+#include <asm/entry.h>
#define prepare_to_switch() do { } while(0)
@@ -44,36 +45,52 @@ asmlinkage void resume(void);
(last) = _last; \
}
+
+/* interrupt control.. */
+#if 0
+#define __sti() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory")
+#else
+#include <asm/hardirq.h>
+#define __sti() ({ \
+ if (!local_irq_count[smp_processor_id()]) \
+ asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory"); \
+})
+#endif
+#define __cli() asm volatile ("oriw #0x0700,%%sr": : : "memory")
+#define __save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory")
+#define __restore_flags(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory")
+
+/* For spinlocks etc */
+#define local_irq_save(x) ({ __save_flags(x); __cli(); })
+#define local_irq_restore(x) __restore_flags(x)
+#define local_irq_disable() __cli()
+#define local_irq_enable() __sti()
+
+#define cli() __cli()
+#define sti() __sti()
+#define save_flags(x) __save_flags(x)
+#define restore_flags(x) __restore_flags(x)
+
+
+/*
+ * Force strict CPU ordering.
+ * Not really required on m68k...
+ */
+#define nop() asm volatile ("nop"::)
+#define mb() asm volatile ("" : : :"memory")
+#define rmb() asm volatile ("" : : :"memory")
+#define wmb() asm volatile ("" : : :"memory")
+#define set_rmb(var, value) do { xchg(&var, value); } while (0)
+#define set_mb(var, value) set_rmb(var, value)
+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+
+
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
#define tas(ptr) (xchg((ptr),1))
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((volatile struct __xchg_dummy *)(x))
-#if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES)
-/* block out HSYNC on the atari */
-#define __sti() __asm__ __volatile__ ("andiw #0xfbff,%/sr": : : "memory")
-#else /* portable version */
-#define __sti() __asm__ __volatile__ ("andiw #0xf8ff,%/sr": : : "memory")
-#endif /* machine compilation types */
-#define __cli() __asm__ __volatile__ ("oriw #0x0700,%/sr": : : "memory")
-#define nop() __asm__ __volatile__ ("nop"::)
-#define mb() __asm__ __volatile__ ("" : : :"memory")
-#define rmb() __asm__ __volatile__ ("" : : :"memory")
-#define wmb() __asm__ __volatile__ ("" : : :"memory")
-
-#define __save_flags(x) \
-__asm__ __volatile__("movew %/sr,%0":"=d" (x) : /* no input */ :"memory")
-
-#define __restore_flags(x) \
-__asm__ __volatile__("movew %0,%/sr": /* no outputs */ :"d" (x) : "memory")
-
-#define cli() __cli()
-#define sti() __sti()
-#define save_flags(x) __save_flags(x)
-#define restore_flags(x) __restore_flags(x)
-#define save_and_cli(flags) do { save_flags(flags); cli(); } while(0)
-
#ifndef CONFIG_RMW_INSNS
static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
diff --git a/include/asm-m68k/termios.h b/include/asm-m68k/termios.h
index 07f6b8585..0f127c134 100644
--- a/include/asm-m68k/termios.h
+++ b/include/asm-m68k/termios.h
@@ -43,6 +43,9 @@ struct termio {
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
diff --git a/include/asm-m68k/uaccess.h b/include/asm-m68k/uaccess.h
index 548ce9ede..82897ade9 100644
--- a/include/asm-m68k/uaccess.h
+++ b/include/asm-m68k/uaccess.h
@@ -799,33 +799,46 @@ strncpy_from_user(char *dst, const char *src, long count)
/*
* Return the size of a string (including the ending 0)
*
- * Return 0 for error
+ * Return 0 on exception, a value greater than N if too long
*/
-static inline long strlen_user(const char * src)
+static inline long strnlen_user(const char *src, long n)
{
- long res = -(long) src;
- __asm__ __volatile__
- ("1: movesb (%1)+,%%d0\n"
- "12:tstb %%d0\n"
- " jne 1b\n"
- " addl %1,%0\n"
- "2:\n"
- ".section .fixup,\"ax\"\n"
- " .even\n"
- "3: moveq %2,%0\n"
- " jra 2b\n"
- ".previous\n"
- ".section __ex_table,\"a\"\n"
- " .align 4\n"
- " .long 1b,3b\n"
- " .long 12b,3b\n"
- ".previous"
- : "=d"(res), "=a"(src)
- : "i"(0), "0"(res), "1"(src)
- : "d0");
- return res;
+ long res;
+
+ res = -(long)src;
+ __asm__ __volatile__
+ ("1:\n"
+ " tstl %2\n"
+ " jeq 3f\n"
+ "2: movesb (%1)+,%%d0\n"
+ "22:\n"
+ " subql #1,%2\n"
+ " tstb %%d0\n"
+ " jne 1b\n"
+ " jra 4f\n"
+ "3:\n"
+ " addql #1,%0\n"
+ "4:\n"
+ " addl %1,%0\n"
+ "5:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "6: moveq %3,%0\n"
+ " jra 5b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 2b,6b\n"
+ " .long 22b,6b\n"
+ ".previous"
+ : "=d"(res), "=a"(src), "=d"(n)
+ : "i"(0), "0"(res), "1"(src), "2"(n)
+ : "d0");
+ return res;
}
+#define strlen_user(str) strnlen_user(str, 32767)
+
/*
* Zero Userspace
*/
diff --git a/include/asm-m68k/virtconvert.h b/include/asm-m68k/virtconvert.h
index 302308d88..4841264ab 100644
--- a/include/asm-m68k/virtconvert.h
+++ b/include/asm-m68k/virtconvert.h
@@ -9,6 +9,7 @@
#include <linux/config.h>
#include <asm/setup.h>
+#include <asm/page.h>
#ifdef CONFIG_AMIGA
#include <asm/amigahw.h>
@@ -34,22 +35,22 @@ extern inline unsigned long mm_ptov(unsigned long paddr)
#endif
#ifdef CONFIG_SINGLE_MEMORY_CHUNK
-extern inline unsigned long virt_to_phys(volatile void * address)
+extern inline unsigned long virt_to_phys(volatile void *vaddr)
{
- unsigned long voff = (unsigned long) address;
+ unsigned long voff = (unsigned long)vaddr - PAGE_OFFSET;
if (voff < m68k_memory[0].size)
- return m68k_memory[0].addr + voff;
- else
- return mm_vtop_fallback(voff);
+ return voff + m68k_memory[0].addr;
+ return mm_vtop_fallback((unsigned long)vaddr);
}
extern inline void * phys_to_virt(unsigned long paddr)
{
- unsigned long base = m68k_memory[0].addr;
+ unsigned long poff = paddr - m68k_memory[0].addr;
+
+ if (poff < m68k_memory[0].size)
+ return (void *)(poff + PAGE_OFFSET);
- if ((paddr >= base) && (paddr < (base + m68k_memory[0].size)))
- return (void *)(paddr - base);
#ifdef CONFIG_AMIGA
/*
* if on an amiga and address is in first 16M, move it
diff --git a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h
index 5d4f314dc..a5c61a5d0 100644
--- a/include/asm-mips/checksum.h
+++ b/include/asm-mips/checksum.h
@@ -1,4 +1,4 @@
-/* $Id: checksum.h,v 1.6 1998/09/19 19:19:36 ralf Exp $
+/* $Id: checksum.h,v 1.7 2000/02/16 01:07:48 ralf Exp $
*
* 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
@@ -9,6 +9,8 @@
#ifndef _ASM_CHECKSUM_H
#define _ASM_CHECKSUM_H
+#include <asm/uaccess.h>
+
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
diff --git a/include/asm-mips/parport.h b/include/asm-mips/parport.h
index dcf0ff69d..0ae99c2e9 100644
--- a/include/asm-mips/parport.h
+++ b/include/asm-mips/parport.h
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: parport.h,v 1.1 1999/10/09 00:01:43 ralf Exp $
*
* parport.h: ia32-specific parport initialisation
*
@@ -39,16 +39,16 @@ parport_pc_init(int *io, int *io_hi, int *irq, int *dma)
do {
if (!*io_hi) *io_hi = 0x400 + *io;
if (parport_pc_probe_port(*(io++), *(io_hi++),
- *(irq++), *(dma++)))
+ *(irq++), *(dma++), NULL))
count++;
} while (*io && (++i < PARPORT_PC_MAX_PORTS));
} else {
/* Probe all the likely ports. */
- if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0], NULL))
count++;
- if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0], NULL))
count++;
- if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0], NULL))
count++;
count += parport_pc_init_pci (irq[0], dma[0]);
}
diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h
index b6a865e9a..20c330760 100644
--- a/include/asm-mips/pci.h
+++ b/include/asm-mips/pci.h
@@ -1,4 +1,4 @@
-/* $Id: pci.h,v 1.6 1999/10/09 00:01:43 ralf Exp $
+/* $Id: pci.h,v 1.7 2000/02/16 01:07:48 ralf Exp $
*
* 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
@@ -16,4 +16,162 @@
#define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_MEM 0x10000000
+#ifdef __KERNEL__
+
+/*
+ * Dynamic DMA mapping stuff.
+ * MIPS has everything mapped statically.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include <asm/io.h>
+
+struct pci_dev;
+
+/*
+ * Allocate and map kernel buffer using consistent mode DMA for a device.
+ * hwdev should be valid struct pci_dev pointer for PCI devices,
+ * NULL for PCI-like buses (ISA, EISA).
+ * Returns non-NULL cpu-view pointer to the buffer if successful and
+ * sets *dma_addrp to the pci side dma address as well, else *dma_addrp
+ * is undefined.
+ */
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+ dma_addr_t *dma_handle);
+
+/*
+ * Free and unmap a consistent DMA buffer.
+ * cpu_addr is what was returned from pci_alloc_consistent,
+ * size must be the same as what as passed into pci_alloc_consistent,
+ * and likewise dma_addr must be the same as what *dma_addrp was set to.
+ *
+ * References to the memory and mappings associated with cpu_addr/dma_addr
+ * past this call are illegal.
+ */
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+ void *vaddr, dma_addr_t dma_handle);
+
+/*
+ * Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+ size_t size)
+{
+ dma_cache_wback_inv((unsigned long)ptr, size);
+
+ return virt_to_bus(ptr);
+}
+
+/*
+ * Unmap a single streaming mode DMA translation. The dma_addr and size
+ * must match what was provided for in a previous pci_map_single call. All
+ * other usages are undefined.
+ *
+ * After this call, reads by the cpu to the buffer are guarenteed to see
+ * whatever the device wrote there.
+ */
+extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+ size_t size)
+{
+ /* Nothing to do */
+}
+
+/*
+ * Map a set of buffers described by scatterlist in streaming
+ * mode for DMA. This is the scather-gather version of the
+ * above pci_map_single interface. Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length. They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ * DMA address/length pairs than there are SG table elements.
+ * (for example via virtual mapping capabilities)
+ * The routine returns the number of addr/length pairs actually
+ * used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+ int nents)
+{
+ /* Make sure that gcc doesn't leave the empty loop body. */
+#ifndef CONFIG_COHERENT_IO
+ int i;
+
+ for (i = 0; i < nents; i++, sg++)
+ dma_cache_wback_inv((unsigned long)sg->address, sg->length);
+#endif
+
+ return nents;
+}
+
+/*
+ * Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+extern inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+ int nents)
+{
+ /* Nothing to do */
+}
+
+/*
+ * Make physical memory consistent for a single
+ * streaming mode DMA translation after a transfer.
+ *
+ * If you perform a pci_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so. At the
+ * next point you give the PCI dma address back to the card, the
+ * device again owns the buffer.
+ */
+extern inline void pci_dma_sync_single(struct pci_dev *hwdev,
+ dma_addr_t dma_handle,
+ size_t size)
+{
+ dma_cache_wback_inv((unsigned long)bus_to_virt(dma_handle), size);
+}
+
+/*
+ * Make physical memory consistent for a set of streaming
+ * mode DMA translations after a transfer.
+ *
+ * The same as pci_dma_sync_single but for a scatter-gather list,
+ * same rules and usage.
+ */
+extern inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+ struct scatterlist *sg,
+ int nelems)
+{
+ /* Make sure that gcc doesn't leave the empty loop body. */
+#ifndef CONFIG_COHERENT_IO
+ int i;
+
+ for (i = 0; i < nelems; i++, sg++)
+ dma_cache_wback_inv((unsigned long)sg->address, sg->length);
+#endif
+}
+
+/*
+ * These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_dma_address(sg) (virt_to_bus((sg)->address))
+#define sg_dma_len(sg) ((sg)->length)
+
+#endif /* __KERNEL__ */
+
#endif /* _ASM_PCI_H */
diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h
index 433c3b862..6a0fab080 100644
--- a/include/asm-mips/semaphore.h
+++ b/include/asm-mips/semaphore.h
@@ -1,4 +1,4 @@
-/* $Id: semaphore.h,v 1.11 1999/10/20 21:10:58 ralf Exp $
+/* $Id: semaphore.h,v 1.12 1999/12/08 22:05:10 harald Exp $
*
* SMP- and interrupt-safe semaphores..
*
@@ -7,8 +7,8 @@
* for more details.
*
* (C) Copyright 1996 Linus Torvalds
- * (C) Copyright 1998, 1999 Ralf Baechle
- * (C) Copyright 1999 Silicon Graphics, Inc.
+ * (C) Copyright 1998, 1999, 2000 Ralf Baechle
+ * (C) Copyright 1999, 2000 Silicon Graphics, Inc.
*/
#ifndef _ASM_SEMAPHORE_H
#define _ASM_SEMAPHORE_H
@@ -189,4 +189,174 @@ extern inline void up(struct semaphore * sem)
__up(sem);
}
+/*
+ * rw mutexes (should that be mutices? =) -- throw rw spinlocks and
+ * semaphores together, and this is what we end up with...
+ *
+ * The lock is initialized to BIAS. This way, a writer subtracts BIAS ands
+ * gets 0 for the case of an uncontended lock. Readers decrement by 1 and
+ * see a positive value when uncontended, negative if there are writers
+ * waiting (in which case it goes to sleep).
+ *
+ * The value 0x01000000 supports up to 128 processors and lots of processes.
+ * BIAS must be chosen such that subtracting BIAS once per CPU will result
+ * in the int remaining negative. In terms of fairness, this should result
+ * in the lock flopping back and forth between readers and writers under
+ * heavy use.
+ *
+ * Once we start supporting machines with more than 128 CPUs, we should go
+ * for using a 64bit atomic type instead of 32bit as counter. We shall
+ * probably go for bias 0x80000000 then, so that single sethi can set it.
+ * */
+
+#define RW_LOCK_BIAS 0x01000000
+
+struct rw_semaphore {
+ atomic_t count;
+ /* bit 0 means read bias granted;
+ bit 1 means write bias granted. */
+ unsigned granted;
+ wait_queue_head_t wait;
+ wait_queue_head_t write_bias_wait;
+#if WAITQUEUE_DEBUG
+ long __magic;
+ atomic_t readers;
+ atomic_t writers;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+#define __RWSEM_DEBUG_INIT , ATOMIC_INIT(0), ATOMIC_INIT(0)
+#else
+#define __RWSEM_DEBUG_INIT /* */
+#endif
+
+#define __RWSEM_INITIALIZER(name,count) \
+ { ATOMIC_INIT(count), 0, \
+ __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
+ __WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait) \
+ __SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT }
+
+#define __DECLARE_RWSEM_GENERIC(name,count) \
+ struct rw_semaphore name = __RWSEM_INITIALIZER(name,count)
+
+#define DECLARE_RWSEM(name) \
+ __DECLARE_RWSEM_GENERIC(name, RW_LOCK_BIAS)
+#define DECLARE_RWSEM_READ_LOCKED(name) \
+ __DECLARE_RWSEM_GENERIC(name, RW_LOCK_BIAS-1)
+#define DECLARE_RWSEM_WRITE_LOCKED(name) \
+ __DECLARE_RWSEM_GENERIC(name, 0)
+
+extern inline void init_rwsem(struct rw_semaphore *sem)
+{
+ atomic_set(&sem->count, RW_LOCK_BIAS);
+ sem->granted = 0;
+ init_waitqueue_head(&sem->wait);
+ init_waitqueue_head(&sem->write_bias_wait);
+#if WAITQUEUE_DEBUG
+ sem->__magic = (long)&sem->__magic;
+ atomic_set(&sem->readers, 0);
+ atomic_set(&sem->writers, 0);
+#endif
+}
+
+/* The expensive part is outlined. */
+extern void __down_read(struct rw_semaphore *sem, int count);
+extern void __down_write(struct rw_semaphore *sem, int count);
+extern void __rwsem_wake(struct rw_semaphore *sem, unsigned long readers);
+
+extern inline void down_read(struct rw_semaphore *sem)
+{
+ int count;
+
+#if WAITQUEUE_DEBUG
+ CHECK_MAGIC(sem->__magic);
+#endif
+
+ count = atomic_dec_return(&sem->count);
+ if (count < 0) {
+ __down_read(sem, count);
+ }
+ mb();
+
+#if WAITQUEUE_DEBUG
+ if (sem->granted & 2)
+ BUG();
+ if (atomic_read(&sem->writers))
+ BUG();
+ atomic_inc(&sem->readers);
+#endif
+}
+
+extern inline void down_write(struct rw_semaphore *sem)
+{
+ int count;
+
+#if WAITQUEUE_DEBUG
+ CHECK_MAGIC(sem->__magic);
+#endif
+
+ count = atomic_sub_return(RW_LOCK_BIAS, &sem->count);
+ if (count) {
+ __down_write(sem, count);
+ }
+ mb();
+
+#if WAITQUEUE_DEBUG
+ if (atomic_read(&sem->writers))
+ BUG();
+ if (atomic_read(&sem->readers))
+ BUG();
+ if (sem->granted & 3)
+ BUG();
+ atomic_inc(&sem->writers);
+#endif
+}
+
+/* When a reader does a release, the only significant case is when
+ there was a writer waiting, and we've bumped the count to 0: we must
+ wake the writer up. */
+
+extern inline void up_read(struct rw_semaphore *sem)
+{
+#if WAITQUEUE_DEBUG
+ CHECK_MAGIC(sem->__magic);
+ if (sem->granted & 2)
+ BUG();
+ if (atomic_read(&sem->writers))
+ BUG();
+ atomic_dec(&sem->readers);
+#endif
+
+ mb();
+ if (atomic_inc_return(&sem->count) == 0)
+ __rwsem_wake(sem, 0);
+}
+
+/*
+ * Releasing the writer is easy -- just release it and wake up any sleepers.
+ */
+extern inline void up_write(struct rw_semaphore *sem)
+{
+ int count;
+
+#if WAITQUEUE_DEBUG
+ CHECK_MAGIC(sem->__magic);
+ if (sem->granted & 3)
+ BUG();
+ if (atomic_read(&sem->readers))
+ BUG();
+ if (atomic_read(&sem->writers) != 1)
+ BUG();
+ atomic_dec(&sem->writers);
+#endif
+
+ mb();
+ count = atomic_add_return(RW_LOCK_BIAS, &sem->count);
+ if (count - RW_LOCK_BIAS < 0 && count >= 0) {
+ /* Only do the wake if we're no longer negative. */
+ __rwsem_wake(sem, count);
+ }
+}
+
#endif /* _ASM_SEMAPHORE_H */
diff --git a/include/asm-mips/siginfo.h b/include/asm-mips/siginfo.h
index ef8ea8765..2dd4765e7 100644
--- a/include/asm-mips/siginfo.h
+++ b/include/asm-mips/siginfo.h
@@ -1,4 +1,4 @@
-/* $Id: siginfo.h,v 1.4 1999/06/13 16:35:54 ralf Exp $
+/* $Id: siginfo.h,v 1.5 1999/08/18 23:37:49 ralf Exp $
*
* 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
@@ -169,7 +169,7 @@ typedef struct siginfo {
#define CLD_TRAPPED 4 /* traced child has trapped */
#define CLD_STOPPED 5 /* child has stopped */
#define CLD_CONTINUED 6 /* stopped child has continued */
-#define NSIGCLD 6
+#define NSIGCHLD 6
/*
* SIGPOLL si_codes
diff --git a/include/asm-mips/termios.h b/include/asm-mips/termios.h
index e7688850b..2e0ed639a 100644
--- a/include/asm-mips/termios.h
+++ b/include/asm-mips/termios.h
@@ -1,4 +1,4 @@
-/* $Id: termios.h,v 1.8 2000/01/27 22:49:42 ralf Exp $
+/* $Id: termios.h,v 1.8 2000/01/27 23:45:30 ralf Exp $
*
* 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
@@ -83,6 +83,7 @@ struct termio {
#define TIOCM_DSR 0x400 /* data set ready */
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
/* line disciplines */
#define N_TTY 0
diff --git a/include/asm-mips/types.h b/include/asm-mips/types.h
index 99b23a1e9..d7bf84ee4 100644
--- a/include/asm-mips/types.h
+++ b/include/asm-mips/types.h
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: types.h,v 1.3 1999/08/18 23:37:50 ralf Exp $
*
* 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
@@ -70,6 +70,8 @@ typedef unsigned long long u64;
#define BITS_PER_LONG _MIPS_SZLONG
+typedef unsigned long dma_addr_t;
+
#endif /* __KERNEL__ */
#endif /* _ASM_TYPES_H */
diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h
index d1dbd1e5f..c07c5154a 100644
--- a/include/asm-mips/unistd.h
+++ b/include/asm-mips/unistd.h
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.18 2000/02/04 07:40:53 ralf Exp $
+/* $Id: unistd.h,v 1.19 2000/02/05 06:47:37 ralf Exp $
*
* 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
@@ -1202,11 +1202,12 @@
#define __NR_stat64 (__NR_Linux + 213)
#define __NR_lstat64 (__NR_Linux + 214)
#define __NR_fstat64 (__NR_Linux + 215)
+#define __NR_pivot_root (__NR_Linux + 216)
/*
* Offset of the last Linux flavoured syscall
*/
-#define __NR_Linux_syscalls 215
+#define __NR_Linux_syscalls 216
#ifndef _LANGUAGE_ASSEMBLY
diff --git a/include/asm-mips64/checksum.h b/include/asm-mips64/checksum.h
index 7d389ed21..979088f57 100644
--- a/include/asm-mips64/checksum.h
+++ b/include/asm-mips64/checksum.h
@@ -1,4 +1,4 @@
-/* $Id: checksum.h,v 1.3 1999/11/19 23:22:59 ralf Exp $
+/* $Id: checksum.h,v 1.4 2000/02/16 01:07:48 ralf Exp $
*
* 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
@@ -10,6 +10,8 @@
#ifndef _ASM_CHECKSUM_H
#define _ASM_CHECKSUM_H
+#include <asm/checksum.h>
+
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
diff --git a/include/asm-mips64/parport.h b/include/asm-mips64/parport.h
index dcf0ff69d..0ae99c2e9 100644
--- a/include/asm-mips64/parport.h
+++ b/include/asm-mips64/parport.h
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: parport.h,v 1.1 1999/10/09 00:01:43 ralf Exp $
*
* parport.h: ia32-specific parport initialisation
*
@@ -39,16 +39,16 @@ parport_pc_init(int *io, int *io_hi, int *irq, int *dma)
do {
if (!*io_hi) *io_hi = 0x400 + *io;
if (parport_pc_probe_port(*(io++), *(io_hi++),
- *(irq++), *(dma++)))
+ *(irq++), *(dma++), NULL))
count++;
} while (*io && (++i < PARPORT_PC_MAX_PORTS));
} else {
/* Probe all the likely ports. */
- if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x3bc, 0x7bc, irq[0], dma[0], NULL))
count++;
- if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x378, 0x778, irq[0], dma[0], NULL))
count++;
- if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0]))
+ if (parport_pc_probe_port(0x278, 0x678, irq[0], dma[0], NULL))
count++;
count += parport_pc_init_pci (irq[0], dma[0]);
}
diff --git a/include/asm-mips64/pci.h b/include/asm-mips64/pci.h
index 96a39ad98..a1e0e992e 100644
--- a/include/asm-mips64/pci.h
+++ b/include/asm-mips64/pci.h
@@ -1,4 +1,4 @@
-/* $Id: pci.h,v 1.1 1999/12/04 03:59:12 ralf Exp $
+/* $Id: pci.h,v 1.2 2000/02/16 01:07:49 ralf Exp $
*
* 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
@@ -16,4 +16,162 @@
#define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_MEM 0x10000000
+#ifdef __KERNEL__
+
+/*
+ * Dynamic DMA mapping stuff.
+ * MIPS has everything mapped statically.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include <asm/io.h>
+
+struct pci_dev;
+
+/*
+ * Allocate and map kernel buffer using consistent mode DMA for a device.
+ * hwdev should be valid struct pci_dev pointer for PCI devices,
+ * NULL for PCI-like buses (ISA, EISA).
+ * Returns non-NULL cpu-view pointer to the buffer if successful and
+ * sets *dma_addrp to the pci side dma address as well, else *dma_addrp
+ * is undefined.
+ */
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+ dma_addr_t *dma_handle);
+
+/*
+ * Free and unmap a consistent DMA buffer.
+ * cpu_addr is what was returned from pci_alloc_consistent,
+ * size must be the same as what as passed into pci_alloc_consistent,
+ * and likewise dma_addr must be the same as what *dma_addrp was set to.
+ *
+ * References to the memory and mappings associated with cpu_addr/dma_addr
+ * past this call are illegal.
+ */
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+ void *vaddr, dma_addr_t dma_handle);
+
+/*
+ * Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+ size_t size)
+{
+ dma_cache_wback_inv((unsigned long)ptr, size);
+
+ return virt_to_bus(ptr);
+}
+
+/*
+ * Unmap a single streaming mode DMA translation. The dma_addr and size
+ * must match what was provided for in a previous pci_map_single call. All
+ * other usages are undefined.
+ *
+ * After this call, reads by the cpu to the buffer are guarenteed to see
+ * whatever the device wrote there.
+ */
+extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+ size_t size)
+{
+ /* Nothing to do */
+}
+
+/*
+ * Map a set of buffers described by scatterlist in streaming
+ * mode for DMA. This is the scather-gather version of the
+ * above pci_map_single interface. Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length. They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ * DMA address/length pairs than there are SG table elements.
+ * (for example via virtual mapping capabilities)
+ * The routine returns the number of addr/length pairs actually
+ * used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+ int nents)
+{
+ /* Make sure that gcc doesn't leave the empty loop body. */
+#ifndef CONFIG_COHERENT_IO
+ int i;
+
+ for (i = 0; i < nents; i++, sg++)
+ dma_cache_wback_inv((unsigned long)sg->address, sg->length);
+#endif
+
+ return nents;
+}
+
+/*
+ * Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+extern inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+ int nents)
+{
+ /* Nothing to do */
+}
+
+/*
+ * Make physical memory consistent for a single
+ * streaming mode DMA translation after a transfer.
+ *
+ * If you perform a pci_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so. At the
+ * next point you give the PCI dma address back to the card, the
+ * device again owns the buffer.
+ */
+extern inline void pci_dma_sync_single(struct pci_dev *hwdev,
+ dma_addr_t dma_handle,
+ size_t size)
+{
+ dma_cache_wback_inv((unsigned long)bus_to_virt(dma_handle), size);
+}
+
+/*
+ * Make physical memory consistent for a set of streaming
+ * mode DMA translations after a transfer.
+ *
+ * The same as pci_dma_sync_single but for a scatter-gather list,
+ * same rules and usage.
+ */
+extern inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+ struct scatterlist *sg,
+ int nelems)
+{
+ /* Make sure that gcc doesn't leave the empty loop body. */
+#ifndef CONFIG_COHERENT_IO
+ int i;
+
+ for (i = 0; i < nelems; i++, sg++)
+ dma_cache_wback_inv((unsigned long)sg->address, sg->length);
+#endif
+}
+
+/*
+ * These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_dma_address(sg) (virt_to_bus((sg)->address))
+#define sg_dma_len(sg) ((sg)->length)
+
+#endif /* __KERNEL__ */
+
#endif /* _ASM_PCI_H */
diff --git a/include/asm-mips64/semaphore.h b/include/asm-mips64/semaphore.h
index 52f5eb11d..626d2d2fd 100644
--- a/include/asm-mips64/semaphore.h
+++ b/include/asm-mips64/semaphore.h
@@ -1,11 +1,11 @@
-/* $Id: semaphore.h,v 1.3 1999/12/04 03:59:12 ralf Exp $
+/* $Id: semaphore.h,v 1.4 1999/12/09 11:01:42 ralf Exp $
*
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1996 Linus Torvalds
- * Copyright (C) 1998, 1999 Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1998, 1999, 2000 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
#ifndef _ASM_SEMAPHORE_H
#define _ASM_SEMAPHORE_H
@@ -170,4 +170,177 @@ extern inline void up(struct semaphore * sem)
__up(sem);
}
+/*
+ * rw mutexes (should that be mutices? =) -- throw rw spinlocks and
+ * semaphores together, and this is what we end up with...
+ *
+ * The lock is initialized to BIAS. This way, a writer subtracts BIAS ands
+ * gets 0 for the case of an uncontended lock. Readers decrement by 1 and
+ * see a positive value when uncontended, negative if there are writers
+ * waiting (in which case it goes to sleep).
+ *
+ * The value 0x01000000 supports up to 128 processors and lots of processes.
+ * BIAS must be chosen such that subtracting BIAS once per CPU will result
+ * in the int remaining negative. In terms of fairness, this should result
+ * in the lock flopping back and forth between readers and writers under
+ * heavy use.
+ *
+ * Once we start supporting machines with more than 128 CPUs, we should go
+ * for using a 64bit atomic type instead of 32bit as counter. We shall
+ * probably go for bias 0x80000000 then, so that single sethi can set it.
+ * */
+
+#define RW_LOCK_BIAS 0x01000000
+
+struct rw_semaphore {
+ atomic_t count;
+ /* bit 0 means read bias granted;
+ bit 1 means write bias granted. */
+ unsigned granted;
+ wait_queue_head_t wait;
+ wait_queue_head_t write_bias_wait;
+#if WAITQUEUE_DEBUG
+ long __magic;
+ atomic_t readers;
+ atomic_t writers;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+#define __RWSEM_DEBUG_INIT , ATOMIC_INIT(0), ATOMIC_INIT(0)
+#else
+#define __RWSEM_DEBUG_INIT /* */
+#endif
+
+#define __RWSEM_INITIALIZER(name,count) \
+ { (count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
+ __WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait) \
+ __SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT }
+
+#define __DECLARE_RWSEM_GENERIC(name,count) \
+ struct rw_semaphore name = __RWSEM_INITIALIZER(name,count)
+
+#define DECLARE_RWSEM(name) \
+ __DECLARE_RWSEM_GENERIC(name, RW_LOCK_BIAS)
+#define DECLARE_RWSEM_READ_LOCKED(name) \
+ __DECLARE_RWSEM_GENERIC(name, RW_LOCK_BIAS-1)
+#define DECLARE_RWSEM_WRITE_LOCKED(name) \
+ __DECLARE_RWSEM_GENERIC(name, 0)
+
+extern inline void init_rwsem(struct rw_semaphore *sem)
+{
+ atomic_set(&sem->count, RW_LOCK_BIAS);
+ sem->granted = 0;
+ init_waitqueue_head(&sem->wait);
+ init_waitqueue_head(&sem->write_bias_wait);
+#if WAITQUEUE_DEBUG
+ sem->__magic = (long)&sem->__magic;
+ atomic_set(&sem->readers, 0);
+ atomic_set(&sem->writers, 0);
+#endif
+}
+
+/* The expensive part is outlined. */
+extern void __down_read(struct rw_semaphore *sem, int count);
+extern void __down_write(struct rw_semaphore *sem, int count);
+extern void __rwsem_wake(struct rw_semaphore *sem, unsigned long readers);
+
+extern inline void down_read(struct rw_semaphore *sem)
+{
+ int count;
+
+#if WAITQUEUE_DEBUG
+ CHECK_MAGIC(sem->__magic);
+#endif
+
+ count = atomic_dec_return(&sem->count);
+ if (count < 0) {
+ __down_read(sem, count);
+ }
+ mb();
+
+#if WAITQUEUE_DEBUG
+ if (sem->granted & 2)
+ BUG();
+ if (atomic_read(&sem->writers))
+ BUG();
+ atomic_inc(&sem->readers);
+#endif
+}
+
+extern inline void down_write(struct rw_semaphore *sem)
+{
+ int count;
+
+#if WAITQUEUE_DEBUG
+ CHECK_MAGIC(sem->__magic);
+#endif
+
+ count = atomic_sub_return(RW_LOCK_BIAS, &sem->count);
+ if (count) {
+ __down_write(sem, count);
+ }
+ mb();
+
+#if WAITQUEUE_DEBUG
+ if (atomic_read(&sem->writers))
+ BUG();
+ if (atomic_read(&sem->readers))
+ BUG();
+ if (sem->granted & 3)
+ BUG();
+ atomic_inc(&sem->writers);
+#endif
+}
+
+/* When a reader does a release, the only significant case is when
+ there was a writer waiting, and we've bumped the count to 0: we must
+ wake the writer up. */
+
+extern inline void up_read(struct rw_semaphore *sem)
+{
+ int count;
+
+#if WAITQUEUE_DEBUG
+ CHECK_MAGIC(sem->__magic);
+ if (sem->granted & 2)
+ BUG();
+ if (atomic_read(&sem->writers))
+ BUG();
+ atomic_dec(&sem->readers);
+#endif
+
+ mb();
+ count = atomic_inc_return(&sem->count);
+ if (count == 0) {
+ __rwsem_wake(sem, 0);
+ }
+}
+
+/*
+ * Releasing the writer is easy -- just release it and wake up any sleepers.
+ */
+extern inline void up_write(struct rw_semaphore *sem)
+{
+ int count;
+
+#if WAITQUEUE_DEBUG
+ CHECK_MAGIC(sem->__magic);
+ if (sem->granted & 3)
+ BUG();
+ if (atomic_read(&sem->readers))
+ BUG();
+ if (atomic_read(&sem->writers) != 1)
+ BUG();
+ atomic_dec(&sem->writers);
+#endif
+
+ mb();
+ count = atomic_add_return(RW_LOCK_BIAS, &sem->count);
+ if (count - RW_LOCK_BIAS < 0 && count >= 0) {
+ /* Only do the wake if we're no longer negative. */
+ __rwsem_wake(sem, count);
+ }
+}
+
#endif /* _ASM_SEMAPHORE_H */
diff --git a/include/asm-mips64/siginfo.h b/include/asm-mips64/siginfo.h
index cdd8e5ff4..f20703273 100644
--- a/include/asm-mips64/siginfo.h
+++ b/include/asm-mips64/siginfo.h
@@ -1,4 +1,4 @@
-/* $Id: siginfo.h,v 1.1 1999/08/18 23:37:52 ralf Exp $
+/* $Id: siginfo.h,v 1.2 2000/01/27 01:05:37 ralf Exp $
*
* 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
@@ -169,7 +169,7 @@ typedef struct siginfo {
#define CLD_TRAPPED 4 /* traced child has trapped */
#define CLD_STOPPED 5 /* child has stopped */
#define CLD_CONTINUED 6 /* stopped child has continued */
-#define NSIGCLD 6
+#define NSIGCHLD 6
/*
* SIGPOLL si_codes
diff --git a/include/asm-mips64/termios.h b/include/asm-mips64/termios.h
index 05eb9c253..930a6dcb1 100644
--- a/include/asm-mips64/termios.h
+++ b/include/asm-mips64/termios.h
@@ -1,4 +1,4 @@
-/* $Id: termios.h,v 1.1 1999/08/18 23:37:53 ralf Exp $
+/* $Id: termios.h,v 1.2 2000/01/27 23:45:30 ralf Exp $
*
* 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
@@ -83,6 +83,7 @@ struct termio {
#define TIOCM_DSR 0x400 /* data set ready */
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
/* line disciplines */
#define N_TTY 0
diff --git a/include/asm-mips64/types.h b/include/asm-mips64/types.h
index cc07bde05..989e79622 100644
--- a/include/asm-mips64/types.h
+++ b/include/asm-mips64/types.h
@@ -1,4 +1,4 @@
-/* $Id: types.h,v 1.1 1999/08/18 23:37:53 ralf Exp $
+/* $Id: types.h,v 1.2 1999/12/04 03:59:12 ralf Exp $
*
* 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
@@ -70,6 +70,8 @@ typedef unsigned long long u64;
#define BITS_PER_LONG _MIPS_SZLONG
+typedef unsigned long dma_addr_t;
+
#endif /* __KERNEL__ */
#endif /* _ASM_TYPES_H */
diff --git a/include/asm-mips64/unistd.h b/include/asm-mips64/unistd.h
index 5ab08b0bc..0308f3bf3 100644
--- a/include/asm-mips64/unistd.h
+++ b/include/asm-mips64/unistd.h
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.8 2000/02/04 07:40:53 ralf Exp $
+/* $Id: unistd.h,v 1.9 2000/02/05 06:47:37 ralf Exp $
*
* 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
@@ -1195,17 +1195,18 @@
#define __NR_Linux32_sendfile (__NR_Linux32 + 207)
#define __NR_Linux32_getpmsg (__NR_Linux32 + 208)
#define __NR_Linux32_putpmsg (__NR_Linux32 + 209)
-#define __NR_mmap2 (__NR_Linux32 + 210)
-#define __NR_truncate64 (__NR_Linux32 + 211)
-#define __NR_ftruncate64 (__NR_Linux32 + 212)
-#define __NR_stat64 (__NR_Linux32 + 213)
-#define __NR_lstat64 (__NR_Linux32 + 214)
-#define __NR_fstat64 (__NR_Linux32 + 215)
+#define __NR_Linux32_mmap2 (__NR_Linux32 + 210)
+#define __NR_Linux32_truncate64 (__NR_Linux32 + 211)
+#define __NR_Linux32_ftruncate64 (__NR_Linux32 + 212)
+#define __NR_Linux32_stat64 (__NR_Linux32 + 213)
+#define __NR_Linux32_lstat64 (__NR_Linux32 + 214)
+#define __NR_Linux32_fstat64 (__NR_Linux32 + 215)
+#define __NR_Linux32_root_pivot (__NR_Linux32 + 216)
/*
* Offset of the last Linux o32 flavoured syscall
*/
-#define __NR_Linux32_syscalls 215
+#define __NR_Linux32_syscalls 216
/*
* Linux 64-bit syscalls are in the range from 5000 to 5999.
@@ -1421,11 +1422,12 @@
#define __NR_sendfile (__NR_Linux + 207)
#define __NR_getpmsg (__NR_Linux + 208)
#define __NR_putpmsg (__NR_Linux + 209)
+#define __NR_root_pivot (__NR_Linux + 210)
/*
* Offset of the last Linux flavoured syscall
*/
-#define __NR_Linux_syscalls 209
+#define __NR_Linux_syscalls 210
#ifndef _LANGUAGE_ASSEMBLY
diff --git a/include/asm-ppc/siginfo.h b/include/asm-ppc/siginfo.h
index f838fcc82..58e4b22e9 100644
--- a/include/asm-ppc/siginfo.h
+++ b/include/asm-ppc/siginfo.h
@@ -149,7 +149,7 @@ typedef struct siginfo {
#define CLD_TRAPPED 4 /* traced child has trapped */
#define CLD_STOPPED 5 /* child has stopped */
#define CLD_CONTINUED 6 /* stopped child has continued */
-#define NSIGCHLD
+#define NSIGCHLD 6
/*
* SIGPOLL si_codes
diff --git a/include/asm-ppc/termios.h b/include/asm-ppc/termios.h
index e74609c13..2a9b8b025 100644
--- a/include/asm-ppc/termios.h
+++ b/include/asm-ppc/termios.h
@@ -166,6 +166,9 @@ struct termio {
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
diff --git a/include/asm-sparc/asm_offsets.h b/include/asm-sparc/asm_offsets.h
index 58f26364c..15f2d5093 100644
--- a/include/asm-sparc/asm_offsets.h
+++ b/include/asm-sparc/asm_offsets.h
@@ -159,32 +159,32 @@
#define AOFF_task_semsleeping 0x00000238
#define ASIZ_task_semsleeping 0x00000004
#define AOFF_task_thread 0x00000240
-#define ASIZ_task_thread 0x00000388
-#define AOFF_task_fs 0x000005c8
+#define ASIZ_task_thread 0x00000380
+#define AOFF_task_fs 0x000005c0
#define ASIZ_task_fs 0x00000004
-#define AOFF_task_files 0x000005cc
+#define AOFF_task_files 0x000005c4
#define ASIZ_task_files 0x00000004
-#define AOFF_task_sigmask_lock 0x000005d0
+#define AOFF_task_sigmask_lock 0x000005c8
#define ASIZ_task_sigmask_lock 0x00000000
-#define AOFF_task_sig 0x000005d0
+#define AOFF_task_sig 0x000005c8
#define ASIZ_task_sig 0x00000004
-#define AOFF_task_signal 0x000005d4
+#define AOFF_task_signal 0x000005cc
#define ASIZ_task_signal 0x00000008
-#define AOFF_task_blocked 0x000005dc
+#define AOFF_task_blocked 0x000005d4
#define ASIZ_task_blocked 0x00000008
-#define AOFF_task_sigqueue 0x000005e4
+#define AOFF_task_sigqueue 0x000005dc
#define ASIZ_task_sigqueue 0x00000004
-#define AOFF_task_sigqueue_tail 0x000005e8
+#define AOFF_task_sigqueue_tail 0x000005e0
#define ASIZ_task_sigqueue_tail 0x00000004
-#define AOFF_task_sas_ss_sp 0x000005ec
+#define AOFF_task_sas_ss_sp 0x000005e4
#define ASIZ_task_sas_ss_sp 0x00000004
-#define AOFF_task_sas_ss_size 0x000005f0
+#define AOFF_task_sas_ss_size 0x000005e8
#define ASIZ_task_sas_ss_size 0x00000004
-#define AOFF_task_parent_exec_id 0x000005f4
+#define AOFF_task_parent_exec_id 0x000005ec
#define ASIZ_task_parent_exec_id 0x00000004
-#define AOFF_task_self_exec_id 0x000005f8
+#define AOFF_task_self_exec_id 0x000005f0
#define ASIZ_task_self_exec_id 0x00000004
-#define AOFF_task_exit_sem 0x000005fc
+#define AOFF_task_exit_sem 0x000005f4
#define ASIZ_task_exit_sem 0x0000001c
#define AOFF_mm_mmap 0x00000000
#define ASIZ_mm_mmap 0x00000004
@@ -248,45 +248,41 @@
#define ASIZ_thread_uwinmask 0x00000004
#define AOFF_thread_kregs 0x00000004
#define ASIZ_thread_kregs 0x00000004
-#define AOFF_thread_sig_address 0x00000008
-#define ASIZ_thread_sig_address 0x00000004
-#define AOFF_thread_sig_desc 0x0000000c
-#define ASIZ_thread_sig_desc 0x00000004
-#define AOFF_thread_ksp 0x00000010
+#define AOFF_thread_ksp 0x00000008
#define ASIZ_thread_ksp 0x00000004
-#define AOFF_thread_kpc 0x00000014
+#define AOFF_thread_kpc 0x0000000c
#define ASIZ_thread_kpc 0x00000004
-#define AOFF_thread_kpsr 0x00000018
+#define AOFF_thread_kpsr 0x00000010
#define ASIZ_thread_kpsr 0x00000004
-#define AOFF_thread_kwim 0x0000001c
+#define AOFF_thread_kwim 0x00000014
#define ASIZ_thread_kwim 0x00000004
-#define AOFF_thread_fork_kpsr 0x00000020
+#define AOFF_thread_fork_kpsr 0x00000018
#define ASIZ_thread_fork_kpsr 0x00000004
-#define AOFF_thread_fork_kwim 0x00000024
+#define AOFF_thread_fork_kwim 0x0000001c
#define ASIZ_thread_fork_kwim 0x00000004
-#define AOFF_thread_reg_window 0x00000028
+#define AOFF_thread_reg_window 0x00000020
#define ASIZ_thread_reg_window 0x00000200
-#define AOFF_thread_rwbuf_stkptrs 0x00000228
+#define AOFF_thread_rwbuf_stkptrs 0x00000220
#define ASIZ_thread_rwbuf_stkptrs 0x00000020
-#define AOFF_thread_w_saved 0x00000248
+#define AOFF_thread_w_saved 0x00000240
#define ASIZ_thread_w_saved 0x00000004
-#define AOFF_thread_float_regs 0x00000250
+#define AOFF_thread_float_regs 0x00000248
#define ASIZ_thread_float_regs 0x00000080
-#define AOFF_thread_fsr 0x000002d0
+#define AOFF_thread_fsr 0x000002c8
#define ASIZ_thread_fsr 0x00000004
-#define AOFF_thread_fpqdepth 0x000002d4
+#define AOFF_thread_fpqdepth 0x000002cc
#define ASIZ_thread_fpqdepth 0x00000004
-#define AOFF_thread_fpqueue 0x000002d8
+#define AOFF_thread_fpqueue 0x000002d0
#define ASIZ_thread_fpqueue 0x00000080
-#define AOFF_thread_flags 0x00000358
+#define AOFF_thread_flags 0x00000350
#define ASIZ_thread_flags 0x00000004
-#define AOFF_thread_current_ds 0x0000035c
+#define AOFF_thread_current_ds 0x00000354
#define ASIZ_thread_current_ds 0x00000004
-#define AOFF_thread_core_exec 0x00000360
+#define AOFF_thread_core_exec 0x00000358
#define ASIZ_thread_core_exec 0x00000020
-#define AOFF_thread_new_signal 0x00000380
+#define AOFF_thread_new_signal 0x00000378
#define ASIZ_thread_new_signal 0x00000004
-#define AOFF_thread_refcount 0x00000384
+#define AOFF_thread_refcount 0x0000037c
#define ASIZ_thread_refcount 0x00000004
#else /* CONFIG_SMP */
@@ -444,32 +440,32 @@
#define AOFF_task_semsleeping 0x00000338
#define ASIZ_task_semsleeping 0x00000004
#define AOFF_task_thread 0x00000340
-#define ASIZ_task_thread 0x00000388
-#define AOFF_task_fs 0x000006c8
+#define ASIZ_task_thread 0x00000380
+#define AOFF_task_fs 0x000006c0
#define ASIZ_task_fs 0x00000004
-#define AOFF_task_files 0x000006cc
+#define AOFF_task_files 0x000006c4
#define ASIZ_task_files 0x00000004
-#define AOFF_task_sigmask_lock 0x000006d0
+#define AOFF_task_sigmask_lock 0x000006c8
#define ASIZ_task_sigmask_lock 0x00000008
-#define AOFF_task_sig 0x000006d8
+#define AOFF_task_sig 0x000006d0
#define ASIZ_task_sig 0x00000004
-#define AOFF_task_signal 0x000006dc
+#define AOFF_task_signal 0x000006d4
#define ASIZ_task_signal 0x00000008
-#define AOFF_task_blocked 0x000006e4
+#define AOFF_task_blocked 0x000006dc
#define ASIZ_task_blocked 0x00000008
-#define AOFF_task_sigqueue 0x000006ec
+#define AOFF_task_sigqueue 0x000006e4
#define ASIZ_task_sigqueue 0x00000004
-#define AOFF_task_sigqueue_tail 0x000006f0
+#define AOFF_task_sigqueue_tail 0x000006e8
#define ASIZ_task_sigqueue_tail 0x00000004
-#define AOFF_task_sas_ss_sp 0x000006f4
+#define AOFF_task_sas_ss_sp 0x000006ec
#define ASIZ_task_sas_ss_sp 0x00000004
-#define AOFF_task_sas_ss_size 0x000006f8
+#define AOFF_task_sas_ss_size 0x000006f0
#define ASIZ_task_sas_ss_size 0x00000004
-#define AOFF_task_parent_exec_id 0x000006fc
+#define AOFF_task_parent_exec_id 0x000006f4
#define ASIZ_task_parent_exec_id 0x00000004
-#define AOFF_task_self_exec_id 0x00000700
+#define AOFF_task_self_exec_id 0x000006f8
#define ASIZ_task_self_exec_id 0x00000004
-#define AOFF_task_exit_sem 0x00000704
+#define AOFF_task_exit_sem 0x000006fc
#define ASIZ_task_exit_sem 0x00000024
#define AOFF_mm_mmap 0x00000000
#define ASIZ_mm_mmap 0x00000004
@@ -533,45 +529,41 @@
#define ASIZ_thread_uwinmask 0x00000004
#define AOFF_thread_kregs 0x00000004
#define ASIZ_thread_kregs 0x00000004
-#define AOFF_thread_sig_address 0x00000008
-#define ASIZ_thread_sig_address 0x00000004
-#define AOFF_thread_sig_desc 0x0000000c
-#define ASIZ_thread_sig_desc 0x00000004
-#define AOFF_thread_ksp 0x00000010
+#define AOFF_thread_ksp 0x00000008
#define ASIZ_thread_ksp 0x00000004
-#define AOFF_thread_kpc 0x00000014
+#define AOFF_thread_kpc 0x0000000c
#define ASIZ_thread_kpc 0x00000004
-#define AOFF_thread_kpsr 0x00000018
+#define AOFF_thread_kpsr 0x00000010
#define ASIZ_thread_kpsr 0x00000004
-#define AOFF_thread_kwim 0x0000001c
+#define AOFF_thread_kwim 0x00000014
#define ASIZ_thread_kwim 0x00000004
-#define AOFF_thread_fork_kpsr 0x00000020
+#define AOFF_thread_fork_kpsr 0x00000018
#define ASIZ_thread_fork_kpsr 0x00000004
-#define AOFF_thread_fork_kwim 0x00000024
+#define AOFF_thread_fork_kwim 0x0000001c
#define ASIZ_thread_fork_kwim 0x00000004
-#define AOFF_thread_reg_window 0x00000028
+#define AOFF_thread_reg_window 0x00000020
#define ASIZ_thread_reg_window 0x00000200
-#define AOFF_thread_rwbuf_stkptrs 0x00000228
+#define AOFF_thread_rwbuf_stkptrs 0x00000220
#define ASIZ_thread_rwbuf_stkptrs 0x00000020
-#define AOFF_thread_w_saved 0x00000248
+#define AOFF_thread_w_saved 0x00000240
#define ASIZ_thread_w_saved 0x00000004
-#define AOFF_thread_float_regs 0x00000250
+#define AOFF_thread_float_regs 0x00000248
#define ASIZ_thread_float_regs 0x00000080
-#define AOFF_thread_fsr 0x000002d0
+#define AOFF_thread_fsr 0x000002c8
#define ASIZ_thread_fsr 0x00000004
-#define AOFF_thread_fpqdepth 0x000002d4
+#define AOFF_thread_fpqdepth 0x000002cc
#define ASIZ_thread_fpqdepth 0x00000004
-#define AOFF_thread_fpqueue 0x000002d8
+#define AOFF_thread_fpqueue 0x000002d0
#define ASIZ_thread_fpqueue 0x00000080
-#define AOFF_thread_flags 0x00000358
+#define AOFF_thread_flags 0x00000350
#define ASIZ_thread_flags 0x00000004
-#define AOFF_thread_current_ds 0x0000035c
+#define AOFF_thread_current_ds 0x00000354
#define ASIZ_thread_current_ds 0x00000004
-#define AOFF_thread_core_exec 0x00000360
+#define AOFF_thread_core_exec 0x00000358
#define ASIZ_thread_core_exec 0x00000020
-#define AOFF_thread_new_signal 0x00000380
+#define AOFF_thread_new_signal 0x00000378
#define ASIZ_thread_new_signal 0x00000004
-#define AOFF_thread_refcount 0x00000384
+#define AOFF_thread_refcount 0x0000037c
#define ASIZ_thread_refcount 0x00000004
#endif /* CONFIG_SMP */
diff --git a/include/asm-sparc/hdreg.h b/include/asm-sparc/hdreg.h
new file mode 100644
index 000000000..1c321c3e7
--- /dev/null
+++ b/include/asm-sparc/hdreg.h
@@ -0,0 +1,13 @@
+/* $Id: hdreg.h,v 1.1 2000/01/21 04:56:27 zaitcev Exp $
+ * hdreg.h: SPARC PCI specific IDE glue.
+ *
+ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
+ */
+
+#ifndef __SPARC_HDREG_H
+#define __SPARC_HDREG_H
+
+typedef unsigned int ide_ioreg_t;
+
+#endif /* __SPARC_HDREG_H */
diff --git a/include/asm-sparc/ide.h b/include/asm-sparc/ide.h
new file mode 100644
index 000000000..bec4233e6
--- /dev/null
+++ b/include/asm-sparc/ide.h
@@ -0,0 +1,289 @@
+/* $Id: ide.h,v 1.2 2000/01/21 04:56:27 zaitcev Exp $
+ * ide.h: SPARC PCI specific IDE glue.
+ *
+ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
+ * Adaptation from sparc64 version to sparc by Pete Zaitcev.
+ */
+
+#ifndef _SPARC_IDE_H
+#define _SPARC_IDE_H
+
+#ifdef __KERNEL__
+
+#include <asm/pgtable.h>
+#include <asm/io.h>
+#include <asm/hdreg.h>
+#include <asm/psr.h>
+
+#undef MAX_HWIFS
+#define MAX_HWIFS 2
+
+#define ide__sti() __sti()
+
+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;
+}
+
+/*
+ * Doing any sort of ioremap() here does not work
+ * because this function may be called with null aguments.
+ */
+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;
+
+ for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+ hw->io_ports[i] = reg;
+ reg += 1;
+ }
+ if (ctrl_port) {
+ hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+ } else {
+ hw->io_ports[IDE_CONTROL_OFFSET] = 0;
+ }
+ if (irq != NULL)
+ *irq = 0;
+}
+
+/*
+ * This registers the standard ports for this architecture with the IDE
+ * driver.
+ */
+static __inline__ void ide_init_default_hwifs(void)
+{
+#ifdef __DO_I_NEED_THIS
+ hw_regs_t hw;
+ int index;
+
+ for (index = 0; index < MAX_HWIFS; index++) {
+ ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, 0);
+ hw.irq = ide_default_irq(ide_default_io_base(index));
+ ide_register_hw(&hw, NULL);
+ }
+#endif /* __DO_I_NEED_THIS */
+}
+
+typedef union {
+ unsigned int all : 8; /* all of the bits together */
+ struct {
+ unsigned int bit7 : 1;
+ unsigned int lba : 1;
+ unsigned int bit5 : 1;
+ unsigned int unit : 1;
+ unsigned int head : 4;
+ } b;
+} select_t;
+
+static __inline__ int ide_request_irq(unsigned int irq,
+ void (*handler)(int, void *, struct pt_regs *),
+ unsigned long flags, const char *name, void *devid)
+{
+ return request_irq(irq, handler, SA_SHIRQ, name, devid);
+}
+
+static __inline__ void ide_free_irq(unsigned int irq, void *dev_id)
+{
+ free_irq(irq, dev_id);
+}
+
+static __inline__ int ide_check_region(ide_ioreg_t base, unsigned int size)
+{
+ /* We leave these empty because pcic.c calls sparc_alloc_io() */
+ return 0;
+}
+
+static __inline__ void ide_request_region(ide_ioreg_t base, unsigned int size,
+ const char *name)
+{
+}
+
+static __inline__ void ide_release_region(ide_ioreg_t base, unsigned int size)
+{
+}
+
+#undef SUPPORT_SLOW_DATA_PORTS
+#define SUPPORT_SLOW_DATA_PORTS 0
+
+#undef SUPPORT_VLB_SYNC
+#define SUPPORT_VLB_SYNC 0
+
+#undef HD_DATA
+#define HD_DATA ((ide_ioreg_t)0)
+
+/* From m68k code... */
+
+#ifdef insl
+#undef insl
+#endif
+#ifdef outsl
+#undef outsl
+#endif
+#ifdef insw
+#undef insw
+#endif
+#ifdef outsw
+#undef outsw
+#endif
+
+#define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1)
+#define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
+
+#define insw(port, buf, nr) ide_insw((port), (buf), (nr))
+#define outsw(port, buf, nr) ide_outsw((port), (buf), (nr))
+
+static __inline__ void ide_insw(unsigned long port,
+ void *dst,
+ unsigned long count)
+{
+ volatile unsigned short *data_port;
+ /* unsigned long end = (unsigned long)dst + (count << 1); */ /* P3 */
+ u16 *ps = dst;
+ u32 *pi;
+
+ data_port = (volatile unsigned short *)port;
+
+ if(((unsigned long)ps) & 0x2) {
+ *ps++ = *data_port;
+ count--;
+ }
+ pi = (u32 *)ps;
+ while(count >= 2) {
+ u32 w;
+
+ w = (*data_port) << 16;
+ w |= (*data_port);
+ *pi++ = w;
+ count -= 2;
+ }
+ ps = (u16 *)pi;
+ if(count)
+ *ps++ = *data_port;
+
+ /* __flush_dcache_range((unsigned long)dst, end); */ /* P3 see hme */
+}
+
+static __inline__ void ide_outsw(unsigned long port,
+ const void *src,
+ unsigned long count)
+{
+ volatile unsigned short *data_port;
+ /* unsigned long end = (unsigned long)src + (count << 1); */
+ const u16 *ps = src;
+ const u32 *pi;
+
+ data_port = (volatile unsigned short *)port;
+
+ if(((unsigned long)src) & 0x2) {
+ *data_port = *ps++;
+ count--;
+ }
+ pi = (const u32 *)ps;
+ while(count >= 2) {
+ u32 w;
+
+ w = *pi++;
+ *data_port = (w >> 16);
+ *data_port = w;
+ count -= 2;
+ }
+ ps = (const u16 *)pi;
+ if(count)
+ *data_port = *ps;
+
+ /* __flush_dcache_range((unsigned long)src, end); */ /* P3 see hme */
+}
+
+#define T_CHAR (0x0000) /* char: don't touch */
+#define T_SHORT (0x4000) /* short: 12 -> 21 */
+#define T_INT (0x8000) /* int: 1234 -> 4321 */
+#define T_TEXT (0xc000) /* text: 12 -> 21 */
+
+#define T_MASK_TYPE (0xc000)
+#define T_MASK_COUNT (0x3fff)
+
+#define D_CHAR(cnt) (T_CHAR | (cnt))
+#define D_SHORT(cnt) (T_SHORT | (cnt))
+#define D_INT(cnt) (T_INT | (cnt))
+#define D_TEXT(cnt) (T_TEXT | (cnt))
+
+static u_short driveid_types[] = {
+ D_SHORT(10), /* config - vendor2 */
+ D_TEXT(20), /* serial_no */
+ D_SHORT(3), /* buf_type - ecc_bytes */
+ D_TEXT(48), /* fw_rev - model */
+ D_CHAR(2), /* max_multsect - vendor3 */
+ D_SHORT(1), /* dword_io */
+ D_CHAR(2), /* vendor4 - capability */
+ D_SHORT(1), /* reserved50 */
+ D_CHAR(4), /* vendor5 - tDMA */
+ D_SHORT(4), /* field_valid - cur_sectors */
+ D_INT(1), /* cur_capacity */
+ D_CHAR(2), /* multsect - multsect_valid */
+ D_INT(1), /* lba_capacity */
+ D_SHORT(194) /* dma_1word - reservedyy */
+};
+
+#define num_driveid_types (sizeof(driveid_types)/sizeof(*driveid_types))
+
+static __inline__ void ide_fix_driveid(struct hd_driveid *id)
+{
+ u_char *p = (u_char *)id;
+ int i, j, cnt;
+ u_char t;
+
+ for (i = 0; i < num_driveid_types; i++) {
+ cnt = driveid_types[i] & T_MASK_COUNT;
+ switch (driveid_types[i] & T_MASK_TYPE) {
+ case T_CHAR:
+ p += cnt;
+ break;
+ case T_SHORT:
+ for (j = 0; j < cnt; j++) {
+ t = p[0];
+ p[0] = p[1];
+ p[1] = t;
+ p += 2;
+ }
+ break;
+ case T_INT:
+ for (j = 0; j < cnt; j++) {
+ t = p[0];
+ p[0] = p[3];
+ p[3] = t;
+ t = p[1];
+ p[1] = p[2];
+ p[2] = t;
+ p += 4;
+ }
+ break;
+ case T_TEXT:
+ for (j = 0; j < cnt; j += 2) {
+ t = p[0];
+ p[0] = p[1];
+ p[1] = t;
+ p += 2;
+ }
+ break;
+ };
+ }
+}
+
+/*
+ * The following are not needed for the non-m68k ports
+ */
+#define ide_ack_intr(hwif) (1)
+/* #define ide_ack_intr(hwif) ((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1) */
+#define ide_release_lock(lock) do {} while (0)
+#define ide_get_lock(lock, hdlr, data) do {} while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _SPARC_IDE_H */
diff --git a/include/asm-sparc/io.h b/include/asm-sparc/io.h
index 80fa5caa6..71610a59f 100644
--- a/include/asm-sparc/io.h
+++ b/include/asm-sparc/io.h
@@ -1,5 +1,5 @@
/*
- * $Id: io.h,v 1.24 1999/12/20 04:58:40 davem Exp $
+ * $Id: io.h,v 1.25 2000/01/22 07:35:46 zaitcev Exp $
*/
#ifndef __SPARC_IO_H
#define __SPARC_IO_H
@@ -12,7 +12,7 @@
#include <asm/system.h>
#define virt_to_bus virt_to_phys
-
+#define bus_to_virt phys_to_virt
extern __inline__ unsigned flip_dword (unsigned d) {
return ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff);
@@ -78,6 +78,13 @@ extern __inline__ void writel(unsigned int b, unsigned long addr) {
#define outl(b, addr) writel(b, addr)
#define outb_p(b, addr) writeb(b, addr)
+extern void outsb(unsigned long addr, const void *src, unsigned long cnt);
+extern void outsw(unsigned long addr, const void *src, unsigned long cnt);
+extern void outsl(unsigned long addr, const void *src, unsigned long cnt);
+extern void insb(unsigned long addr, void *dst, unsigned long count);
+extern void insw(unsigned long addr, void *dst, unsigned long count);
+extern void insl(unsigned long addr, void *dst, unsigned long count);
+
#define IO_SPACE_LIMIT 0xffffffff
/*
diff --git a/include/asm-sparc/irq.h b/include/asm-sparc/irq.h
index 05c3374fa..b7ea70091 100644
--- a/include/asm-sparc/irq.h
+++ b/include/asm-sparc/irq.h
@@ -1,4 +1,4 @@
-/* $Id: irq.h,v 1.27 1999/08/14 03:52:02 anton Exp $
+/* $Id: irq.h,v 1.28 2000/01/22 06:06:58 zaitcev Exp $
* irq.h: IRQ registers on the Sparc.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -49,6 +49,7 @@ BTFIXUPDEF_CALL(void, clear_clock_irq, void)
BTFIXUPDEF_CALL(void, clear_profile_irq, int)
BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int)
+#define disable_irq_nosync disable_irq
#define disable_irq(irq) BTFIXUP_CALL(disable_irq)(irq)
#define enable_irq(irq) BTFIXUP_CALL(enable_irq)(irq)
#define disable_pil_irq(irq) BTFIXUP_CALL(disable_pil_irq)(irq)
diff --git a/include/asm-sparc/pci.h b/include/asm-sparc/pci.h
index 17c8ce462..f30a5bcc2 100644
--- a/include/asm-sparc/pci.h
+++ b/include/asm-sparc/pci.h
@@ -7,4 +7,7 @@
*/
#define pcibios_assign_all_busses() 0
+#define PCIBIOS_MIN_IO 0UL
+#define PCIBIOS_MIN_MEM 0UL
+
#endif /* __SPARC_PCI_H */
diff --git a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h
index a74493500..278c15c80 100644
--- a/include/asm-sparc/processor.h
+++ b/include/asm-sparc/processor.h
@@ -1,4 +1,4 @@
-/* $Id: processor.h,v 1.76 2000/01/09 09:13:38 anton Exp $
+/* $Id: processor.h,v 1.77 2000/01/21 11:39:17 jj Exp $
* include/asm-sparc/processor.h
*
* Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
@@ -58,10 +58,6 @@ struct thread_struct {
unsigned long uwinmask __attribute__ ((aligned (8)));
struct pt_regs *kregs;
- /* For signal handling */
- unsigned long sig_address __attribute__ ((aligned (8)));
- unsigned long sig_desc;
-
/* Context switch saved kernel state. */
unsigned long ksp __attribute__ ((aligned (8)));
unsigned long kpc;
@@ -99,8 +95,8 @@ struct thread_struct {
NULL, __pgprot(0x0) , VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
#define INIT_THREAD { \
-/* uwinmask, kregs, sig_address, sig_desc, ksp, kpc, kpsr, kwim */ \
- 0, 0, 0, 0, 0, 0, 0, 0, \
+/* uwinmask, kregs, ksp, kpc, kpsr, kwim */ \
+ 0, 0, 0, 0, 0, 0, \
/* fork_kpsr, fork_kwim */ \
0, 0, \
/* reg_window */ \
diff --git a/include/asm-sparc/sbus.h b/include/asm-sparc/sbus.h
index ecfc3037f..c96b5660e 100644
--- a/include/asm-sparc/sbus.h
+++ b/include/asm-sparc/sbus.h
@@ -101,9 +101,9 @@ sbus_is_slave(struct sbus_dev *dev)
#define sbus_can_burst64(sdev) (1)
extern void sbus_set_sbus64(struct sbus_dev *, int);
-/* These yield IOMMU mappings in consistant mode. */
-extern void *sbus_alloc_consistant(struct sbus_dev *, long, u32 *dma_addrp);
-extern void sbus_free_consistant(struct sbus_dev *, long, void *, u32);
+/* These yield IOMMU mappings in consistent mode. */
+extern void *sbus_alloc_consistent(struct sbus_dev *, long, u32 *dma_addrp);
+extern void sbus_free_consistent(struct sbus_dev *, long, void *, u32);
/* All the rest use streaming mode mappings. */
extern u32 sbus_map_single(struct sbus_dev *, void *, long);
diff --git a/include/asm-sparc/semaphore.h b/include/asm-sparc/semaphore.h
index 68c2dc359..ec2471223 100644
--- a/include/asm-sparc/semaphore.h
+++ b/include/asm-sparc/semaphore.h
@@ -250,11 +250,18 @@ struct rw_semaphore {
#define __RWSEM_DEBUG_INIT /* */
#endif
-#define __RWSEM_INITIALIZER(name) \
-{ RW_LOCK_BIAS, 0, 0xff, 0xff, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
+#define __RWSEM_INITIALIZER(name,count) \
+{ (count), 0, 0xff, 0xff, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
__WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait) \
__SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT }
+#define __DECLARE_RWSEM_GENERIC(name,count) \
+ struct rw_semaphore name = __RWSEM_INITIALIZER(name,count)
+
+#define DECLARE_RWSEM(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS)
+#define DECLARE_RWSEM_READ_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS-1)
+#define DECLARE_RWSEM_WRITE_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,0)
+
extern inline void init_rwsem(struct rw_semaphore *sem)
{
sem->count = RW_LOCK_BIAS;
diff --git a/include/asm-sparc/sembuf.h b/include/asm-sparc/sembuf.h
index 47b2ef9bc..a79c4bb3c 100644
--- a/include/asm-sparc/sembuf.h
+++ b/include/asm-sparc/sembuf.h
@@ -8,7 +8,7 @@
*
* Pad space is left for:
* - 64-bit time_t to solve y2038 problem
- * - 2 miscellaneous 64-bit values
+ * - 2 miscellaneous 32-bit values
*/
struct semid64_ds {
diff --git a/include/asm-sparc/siginfo.h b/include/asm-sparc/siginfo.h
index 2baed407f..480126b38 100644
--- a/include/asm-sparc/siginfo.h
+++ b/include/asm-sparc/siginfo.h
@@ -1,4 +1,4 @@
-/* $Id: siginfo.h,v 1.5 1999/07/29 12:56:57 jj Exp $
+/* $Id: siginfo.h,v 1.6 2000/01/21 11:39:17 jj Exp $
* siginfo.c:
*/
@@ -81,6 +81,11 @@ typedef struct siginfo {
#define si_band _sifields._sigpoll._band
#define si_fd _sifields._sigpoll._fd
+#ifdef __KERNEL__
+#define __SI_MASK 0
+#define __SI_FAULT 0
+#endif
+
/*
* si_code values
* Digital reserves positive values for kernel-generated signals.
@@ -127,7 +132,7 @@ typedef struct siginfo {
* SIGSEGV si_codes
*/
#define SEGV_MAPERR 1 /* address not mapped to object */
-#define SRGV_ACCERR 2 /* invalid permissions for mapped object */
+#define SEGV_ACCERR 2 /* invalid permissions for mapped object */
#define NSIGSEGV 2
/*
@@ -154,7 +159,7 @@ typedef struct siginfo {
#define CLD_TRAPPED 4 /* traced child has trapped */
#define CLD_STOPPED 5 /* child has stopped */
#define CLD_CONTINUED 6 /* stopped child has continued */
-#define NSIGCHLD
+#define NSIGCHLD 6
/*
* SIGPOLL si_codes
diff --git a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h
index 7c69f57c2..ca4604fe7 100644
--- a/include/asm-sparc/smp.h
+++ b/include/asm-sparc/smp.h
@@ -92,7 +92,7 @@ extern __inline__ void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg
unsigned long arg3, unsigned long arg4, unsigned long arg5)
{ smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); }
-extern __volatile__ int cpu_number_map[NR_CPUS];
+extern __volatile__ int __cpu_number_map[NR_CPUS];
extern __volatile__ int __cpu_logical_map[NR_CPUS];
extern unsigned long smp_proc_in_lock[NR_CPUS];
@@ -100,6 +100,10 @@ extern __inline__ int cpu_logical_map(int cpu)
{
return __cpu_logical_map[cpu];
}
+extern __inline__ int cpu_number_map(int cpu)
+{
+ return __cpu_number_map[cpu];
+}
extern __inline__ int hard_smp4m_processor_id(void)
{
diff --git a/include/asm-sparc/stat.h b/include/asm-sparc/stat.h
index dd266dc5d..4b0dd7fa4 100644
--- a/include/asm-sparc/stat.h
+++ b/include/asm-sparc/stat.h
@@ -1,4 +1,4 @@
-/* $Id: stat.h,v 1.10 1999/12/21 14:09:41 jj Exp $ */
+/* $Id: stat.h,v 1.11 2000/01/16 15:22:53 jj Exp $ */
#ifndef _SPARC_STAT_H
#define _SPARC_STAT_H
@@ -19,23 +19,23 @@ struct __old_kernel_stat {
};
struct stat {
- dev_t st_dev;
- ino_t st_ino;
- mode_t st_mode;
- short st_nlink;
- uid_t st_uid;
- gid_t st_gid;
- dev_t st_rdev;
- off_t st_size;
- time_t st_atime;
- unsigned long __unused1;
- time_t st_mtime;
- unsigned long __unused2;
- time_t st_ctime;
- unsigned long __unused3;
- off_t st_blksize;
- off_t st_blocks;
- unsigned long __unused4[2];
+ unsigned short st_dev;
+ unsigned long st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ unsigned short st_uid;
+ unsigned short st_gid;
+ unsigned short st_rdev;
+ long st_size;
+ long st_atime;
+ unsigned long __unused1;
+ long st_mtime;
+ unsigned long __unused2;
+ long st_ctime;
+ unsigned long __unused3;
+ long st_blksize;
+ long st_blocks;
+ unsigned long __unused4[2];
};
struct stat64 {
diff --git a/include/asm-sparc/termbits.h b/include/asm-sparc/termbits.h
index c0c4959a2..2d07e4e1e 100644
--- a/include/asm-sparc/termbits.h
+++ b/include/asm-sparc/termbits.h
@@ -203,6 +203,9 @@ struct termios {
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
index f16345145..c25741549 100644
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.63 2000/01/12 11:47:40 anton Exp $ */
+/* $Id: unistd.h,v 1.64 2000/01/16 06:20:32 davem Exp $ */
#ifndef _SPARC_UNISTD_H
#define _SPARC_UNISTD_H
diff --git a/include/asm-sparc64/asm_offsets.h b/include/asm-sparc64/asm_offsets.h
index 07dfc1d30..895583bb8 100644
--- a/include/asm-sparc64/asm_offsets.h
+++ b/include/asm-sparc64/asm_offsets.h
@@ -165,34 +165,34 @@
#define AOFF_task_semsleeping 0x00000378
#define ASIZ_task_semsleeping 0x00000008
#define AOFF_task_thread 0x00000380
-#define ASIZ_task_thread 0x00000460
-#define AOFF_task_fs 0x000007e0
+#define ASIZ_task_thread 0x00000450
+#define AOFF_task_fs 0x000007d0
#define ASIZ_task_fs 0x00000008
-#define AOFF_task_files 0x000007e8
+#define AOFF_task_files 0x000007d8
#define ASIZ_task_files 0x00000008
-#define AOFF_task_sigmask_lock 0x000007f0
+#define AOFF_task_sigmask_lock 0x000007e0
#define ASIZ_task_sigmask_lock 0x00000000
-#define AOFF_task_sig 0x000007f0
+#define AOFF_task_sig 0x000007e0
#define ASIZ_task_sig 0x00000008
-#define AOFF_task_signal 0x000007f8
+#define AOFF_task_signal 0x000007e8
#define ASIZ_task_signal 0x00000008
-#define AOFF_task_blocked 0x00000800
+#define AOFF_task_blocked 0x000007f0
#define ASIZ_task_blocked 0x00000008
-#define AOFF_task_sigqueue 0x00000808
+#define AOFF_task_sigqueue 0x000007f8
#define ASIZ_task_sigqueue 0x00000008
-#define AOFF_task_sigqueue_tail 0x00000810
+#define AOFF_task_sigqueue_tail 0x00000800
#define ASIZ_task_sigqueue_tail 0x00000008
-#define AOFF_task_sas_ss_sp 0x00000818
+#define AOFF_task_sas_ss_sp 0x00000808
#define ASIZ_task_sas_ss_sp 0x00000008
-#define AOFF_task_sas_ss_size 0x00000820
+#define AOFF_task_sas_ss_size 0x00000810
#define ASIZ_task_sas_ss_size 0x00000008
-#define AOFF_task_parent_exec_id 0x00000828
+#define AOFF_task_parent_exec_id 0x00000818
#define ASIZ_task_parent_exec_id 0x00000004
-#define AOFF_task_self_exec_id 0x0000082c
+#define AOFF_task_self_exec_id 0x0000081c
#define ASIZ_task_self_exec_id 0x00000004
-#define AOFF_task_exit_sem 0x00000830
+#define AOFF_task_exit_sem 0x00000820
#define ASIZ_task_exit_sem 0x00000030
-#define ASIZ_task 0x00000860
+#define ASIZ_task 0x00000850
#define AOFF_mm_mmap 0x00000000
#define ASIZ_mm_mmap 0x00000008
#define AOFF_mm_mmap_avl 0x00000008
@@ -278,29 +278,23 @@
#define ASIZ_thread_gsr 0x00000007
#define AOFF_thread___pad2 0x0000002f
#define ASIZ_thread___pad2 0x00000001
-#define AOFF_thread_sig_address 0x00000030
-#define ASIZ_thread_sig_address 0x00000008
-#define AOFF_thread_sig_desc 0x00000038
-#define ASIZ_thread_sig_desc 0x00000008
-#define AOFF_thread_xfsr 0x00000040
+#define AOFF_thread_xfsr 0x00000030
#define ASIZ_thread_xfsr 0x00000038
-#define AOFF_thread___pad3 0x00000078
-#define ASIZ_thread___pad3 0x00000008
-#define AOFF_thread_reg_window 0x00000080
+#define AOFF_thread_reg_window 0x00000068
#define ASIZ_thread_reg_window 0x00000380
-#define AOFF_thread_rwbuf_stkptrs 0x00000400
+#define AOFF_thread_rwbuf_stkptrs 0x000003e8
#define ASIZ_thread_rwbuf_stkptrs 0x00000038
-#define AOFF_thread_user_cntd0 0x00000438
+#define AOFF_thread_user_cntd0 0x00000420
#define ASIZ_thread_user_cntd0 0x00000008
-#define AOFF_thread_user_cntd1 0x00000440
+#define AOFF_thread_user_cntd1 0x00000428
#define ASIZ_thread_user_cntd1 0x00000008
-#define AOFF_thread_kernel_cntd0 0x00000448
+#define AOFF_thread_kernel_cntd0 0x00000430
#define ASIZ_thread_kernel_cntd0 0x00000008
-#define AOFF_thread_kernel_cntd1 0x00000450
+#define AOFF_thread_kernel_cntd1 0x00000438
#define ASIZ_thread_kernel_cntd1 0x00000008
-#define AOFF_thread_pcr_reg 0x00000458
+#define AOFF_thread_pcr_reg 0x00000440
#define ASIZ_thread_pcr_reg 0x00000008
-#define ASIZ_thread 0x00000460
+#define ASIZ_thread 0x00000450
#else /* CONFIG_SMP */
@@ -459,34 +453,34 @@
#define AOFF_task_semsleeping 0x00000570
#define ASIZ_task_semsleeping 0x00000008
#define AOFF_task_thread 0x00000580
-#define ASIZ_task_thread 0x00000460
-#define AOFF_task_fs 0x000009e0
+#define ASIZ_task_thread 0x00000450
+#define AOFF_task_fs 0x000009d0
#define ASIZ_task_fs 0x00000008
-#define AOFF_task_files 0x000009e8
+#define AOFF_task_files 0x000009d8
#define ASIZ_task_files 0x00000008
-#define AOFF_task_sigmask_lock 0x000009f0
+#define AOFF_task_sigmask_lock 0x000009e0
#define ASIZ_task_sigmask_lock 0x00000001
-#define AOFF_task_sig 0x000009f8
+#define AOFF_task_sig 0x000009e8
#define ASIZ_task_sig 0x00000008
-#define AOFF_task_signal 0x00000a00
+#define AOFF_task_signal 0x000009f0
#define ASIZ_task_signal 0x00000008
-#define AOFF_task_blocked 0x00000a08
+#define AOFF_task_blocked 0x000009f8
#define ASIZ_task_blocked 0x00000008
-#define AOFF_task_sigqueue 0x00000a10
+#define AOFF_task_sigqueue 0x00000a00
#define ASIZ_task_sigqueue 0x00000008
-#define AOFF_task_sigqueue_tail 0x00000a18
+#define AOFF_task_sigqueue_tail 0x00000a08
#define ASIZ_task_sigqueue_tail 0x00000008
-#define AOFF_task_sas_ss_sp 0x00000a20
+#define AOFF_task_sas_ss_sp 0x00000a10
#define ASIZ_task_sas_ss_sp 0x00000008
-#define AOFF_task_sas_ss_size 0x00000a28
+#define AOFF_task_sas_ss_size 0x00000a18
#define ASIZ_task_sas_ss_size 0x00000008
-#define AOFF_task_parent_exec_id 0x00000a30
+#define AOFF_task_parent_exec_id 0x00000a20
#define ASIZ_task_parent_exec_id 0x00000004
-#define AOFF_task_self_exec_id 0x00000a34
+#define AOFF_task_self_exec_id 0x00000a24
#define ASIZ_task_self_exec_id 0x00000004
-#define AOFF_task_exit_sem 0x00000a38
+#define AOFF_task_exit_sem 0x00000a28
#define ASIZ_task_exit_sem 0x00000038
-#define ASIZ_task 0x00000a70
+#define ASIZ_task 0x00000a60
#define AOFF_mm_mmap 0x00000000
#define ASIZ_mm_mmap 0x00000008
#define AOFF_mm_mmap_avl 0x00000008
@@ -572,29 +566,23 @@
#define ASIZ_thread_gsr 0x00000007
#define AOFF_thread___pad2 0x0000002f
#define ASIZ_thread___pad2 0x00000001
-#define AOFF_thread_sig_address 0x00000030
-#define ASIZ_thread_sig_address 0x00000008
-#define AOFF_thread_sig_desc 0x00000038
-#define ASIZ_thread_sig_desc 0x00000008
-#define AOFF_thread_xfsr 0x00000040
+#define AOFF_thread_xfsr 0x00000030
#define ASIZ_thread_xfsr 0x00000038
-#define AOFF_thread___pad3 0x00000078
-#define ASIZ_thread___pad3 0x00000008
-#define AOFF_thread_reg_window 0x00000080
+#define AOFF_thread_reg_window 0x00000068
#define ASIZ_thread_reg_window 0x00000380
-#define AOFF_thread_rwbuf_stkptrs 0x00000400
+#define AOFF_thread_rwbuf_stkptrs 0x000003e8
#define ASIZ_thread_rwbuf_stkptrs 0x00000038
-#define AOFF_thread_user_cntd0 0x00000438
+#define AOFF_thread_user_cntd0 0x00000420
#define ASIZ_thread_user_cntd0 0x00000008
-#define AOFF_thread_user_cntd1 0x00000440
+#define AOFF_thread_user_cntd1 0x00000428
#define ASIZ_thread_user_cntd1 0x00000008
-#define AOFF_thread_kernel_cntd0 0x00000448
+#define AOFF_thread_kernel_cntd0 0x00000430
#define ASIZ_thread_kernel_cntd0 0x00000008
-#define AOFF_thread_kernel_cntd1 0x00000450
+#define AOFF_thread_kernel_cntd1 0x00000438
#define ASIZ_thread_kernel_cntd1 0x00000008
-#define AOFF_thread_pcr_reg 0x00000458
+#define AOFF_thread_pcr_reg 0x00000440
#define ASIZ_thread_pcr_reg 0x00000008
-#define ASIZ_thread 0x00000460
+#define ASIZ_thread 0x00000450
#else /* SPIN_LOCK_DEBUG */
@@ -751,34 +739,34 @@
#define AOFF_task_semsleeping 0x00000578
#define ASIZ_task_semsleeping 0x00000008
#define AOFF_task_thread 0x00000580
-#define ASIZ_task_thread 0x00000460
-#define AOFF_task_fs 0x000009e0
+#define ASIZ_task_thread 0x00000450
+#define AOFF_task_fs 0x000009d0
#define ASIZ_task_fs 0x00000008
-#define AOFF_task_files 0x000009e8
+#define AOFF_task_files 0x000009d8
#define ASIZ_task_files 0x00000008
-#define AOFF_task_sigmask_lock 0x000009f0
+#define AOFF_task_sigmask_lock 0x000009e0
#define ASIZ_task_sigmask_lock 0x0000000c
-#define AOFF_task_sig 0x00000a00
+#define AOFF_task_sig 0x000009f0
#define ASIZ_task_sig 0x00000008
-#define AOFF_task_signal 0x00000a08
+#define AOFF_task_signal 0x000009f8
#define ASIZ_task_signal 0x00000008
-#define AOFF_task_blocked 0x00000a10
+#define AOFF_task_blocked 0x00000a00
#define ASIZ_task_blocked 0x00000008
-#define AOFF_task_sigqueue 0x00000a18
+#define AOFF_task_sigqueue 0x00000a08
#define ASIZ_task_sigqueue 0x00000008
-#define AOFF_task_sigqueue_tail 0x00000a20
+#define AOFF_task_sigqueue_tail 0x00000a10
#define ASIZ_task_sigqueue_tail 0x00000008
-#define AOFF_task_sas_ss_sp 0x00000a28
+#define AOFF_task_sas_ss_sp 0x00000a18
#define ASIZ_task_sas_ss_sp 0x00000008
-#define AOFF_task_sas_ss_size 0x00000a30
+#define AOFF_task_sas_ss_size 0x00000a20
#define ASIZ_task_sas_ss_size 0x00000008
-#define AOFF_task_parent_exec_id 0x00000a38
+#define AOFF_task_parent_exec_id 0x00000a28
#define ASIZ_task_parent_exec_id 0x00000004
-#define AOFF_task_self_exec_id 0x00000a3c
+#define AOFF_task_self_exec_id 0x00000a2c
#define ASIZ_task_self_exec_id 0x00000004
-#define AOFF_task_exit_sem 0x00000a40
+#define AOFF_task_exit_sem 0x00000a30
#define ASIZ_task_exit_sem 0x00000040
-#define ASIZ_task 0x00000a80
+#define ASIZ_task 0x00000a70
#define AOFF_mm_mmap 0x00000000
#define ASIZ_mm_mmap 0x00000008
#define AOFF_mm_mmap_avl 0x00000008
@@ -864,29 +852,23 @@
#define ASIZ_thread_gsr 0x00000007
#define AOFF_thread___pad2 0x0000002f
#define ASIZ_thread___pad2 0x00000001
-#define AOFF_thread_sig_address 0x00000030
-#define ASIZ_thread_sig_address 0x00000008
-#define AOFF_thread_sig_desc 0x00000038
-#define ASIZ_thread_sig_desc 0x00000008
-#define AOFF_thread_xfsr 0x00000040
+#define AOFF_thread_xfsr 0x00000030
#define ASIZ_thread_xfsr 0x00000038
-#define AOFF_thread___pad3 0x00000078
-#define ASIZ_thread___pad3 0x00000008
-#define AOFF_thread_reg_window 0x00000080
+#define AOFF_thread_reg_window 0x00000068
#define ASIZ_thread_reg_window 0x00000380
-#define AOFF_thread_rwbuf_stkptrs 0x00000400
+#define AOFF_thread_rwbuf_stkptrs 0x000003e8
#define ASIZ_thread_rwbuf_stkptrs 0x00000038
-#define AOFF_thread_user_cntd0 0x00000438
+#define AOFF_thread_user_cntd0 0x00000420
#define ASIZ_thread_user_cntd0 0x00000008
-#define AOFF_thread_user_cntd1 0x00000440
+#define AOFF_thread_user_cntd1 0x00000428
#define ASIZ_thread_user_cntd1 0x00000008
-#define AOFF_thread_kernel_cntd0 0x00000448
+#define AOFF_thread_kernel_cntd0 0x00000430
#define ASIZ_thread_kernel_cntd0 0x00000008
-#define AOFF_thread_kernel_cntd1 0x00000450
+#define AOFF_thread_kernel_cntd1 0x00000438
#define ASIZ_thread_kernel_cntd1 0x00000008
-#define AOFF_thread_pcr_reg 0x00000458
+#define AOFF_thread_pcr_reg 0x00000440
#define ASIZ_thread_pcr_reg 0x00000008
-#define ASIZ_thread 0x00000460
+#define ASIZ_thread 0x00000450
#endif /* SPIN_LOCK_DEBUG */
#endif /* CONFIG_SMP */
diff --git a/include/asm-sparc64/checksum.h b/include/asm-sparc64/checksum.h
index 6f6f8fe06..b2c06823a 100644
--- a/include/asm-sparc64/checksum.h
+++ b/include/asm-sparc64/checksum.h
@@ -1,4 +1,4 @@
-/* $Id: checksum.h,v 1.14 2000/01/05 21:27:42 davem Exp $ */
+/* $Id: checksum.h,v 1.15 2000/01/19 04:06:09 davem Exp $ */
#ifndef __SPARC64_CHECKSUM_H
#define __SPARC64_CHECKSUM_H
@@ -37,12 +37,6 @@ extern unsigned int csum_partial(const unsigned char * buff, int len, unsigned i
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
-/* FIXME: Remove these macros ASAP */
-#define csum_partial_copy(src, dst, len, sum) \
- csum_partial_copy_nocheck(src,dst,len,sum)
-#define csum_partial_copy_fromuser(s, d, l, w) \
- csum_partial_copy_from_user((char *) (s), (d), (l), (w), NULL)
-
extern unsigned int csum_partial_copy_sparc64(const char *src, char *dst, int len, unsigned int sum);
extern __inline__ unsigned int
@@ -66,15 +60,19 @@ csum_partial_copy_from_user(const char *src, char *dst, int len,
return csum_partial_copy_sparc64(src, dst, len, sum);
}
-#if 0
-/* XXX should implement this now... -DaveM */
+/*
+ * Copy and checksum to user
+ */
+#define HAVE_CSUM_COPY_USER
+extern unsigned int csum_partial_copy_user_sparc64(const char *src, char *dst, int len, unsigned int sum);
extern __inline__ unsigned int
-csum_partial_copy_to_user(const char *src, char *dst, int len,
- unsigned int sum, int *err)
+csum_and_copy_to_user(const char *src, char *dst, int len,
+ unsigned int sum, int *err)
{
- return 0;
+ __asm__ __volatile__ ("stx %0, [%%sp + 0x7ff + 128]"
+ : : "r" (err));
+ return csum_partial_copy_user_sparc64(src, dst, len, sum);
}
-#endif
/* ihl is always 5 or greater, almost always is 5, and iph is word aligned
* the majority of the time.
diff --git a/include/asm-sparc64/dma.h b/include/asm-sparc64/dma.h
index 9bab4ebca..4f0b0baf2 100644
--- a/include/asm-sparc64/dma.h
+++ b/include/asm-sparc64/dma.h
@@ -218,4 +218,10 @@ extern int isa_dma_bridge_buggy;
#define isa_dma_bridge_buggy (0)
#endif
+/* We support dynamic DMA remapping and adjacent SG entries
+ * which have addresses modulo DMA_CHUNK_SIZE will be merged
+ * by dma_prepare_sg().
+ */
+#define DMA_CHUNK_SIZE 8192
+
#endif /* !(_ASM_SPARC64_DMA_H) */
diff --git a/include/asm-sparc64/floppy.h b/include/asm-sparc64/floppy.h
index 9a7fd950a..3758686e2 100644
--- a/include/asm-sparc64/floppy.h
+++ b/include/asm-sparc64/floppy.h
@@ -270,7 +270,10 @@ static int sun_fd_eject(int drive)
#include <asm/ns87303.h>
static struct linux_ebus_dma *sun_pci_fd_ebus_dma;
+static struct pci_dev *sun_pci_ebus_dev;
static int sun_pci_broken_drive = -1;
+static unsigned int sun_pci_dma_addr = -1U;
+static int sun_pci_dma_len;
extern void floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
@@ -363,6 +366,11 @@ static void sun_pci_fd_disable_dma(void)
writel(dcsr, &sun_pci_fd_ebus_dma->dcsr);
}
}
+ if (sun_pci_dma_addr != -1U)
+ pci_unmap_single(sun_pci_ebus_dev,
+ sun_pci_dma_addr,
+ sun_pci_dma_len);
+ sun_pci_dma_addr = -1U;
}
static void sun_pci_fd_set_dma_mode(int mode)
@@ -389,12 +397,17 @@ static void sun_pci_fd_set_dma_mode(int mode)
static void sun_pci_fd_set_dma_count(int length)
{
+ sun_pci_dma_len = length;
writel(length, &sun_pci_fd_ebus_dma->dbcr);
}
static void sun_pci_fd_set_dma_addr(char *buffer)
{
- unsigned int addr = virt_to_bus(buffer);
+ unsigned int addr;
+
+ addr = sun_pci_dma_addr = pci_map_single(sun_pci_ebus_dev,
+ buffer,
+ sun_pci_dma_len);
writel(addr, &sun_pci_fd_ebus_dma->dacr);
}
@@ -599,6 +612,8 @@ static unsigned long __init sun_floppy_init(void)
auxio_reg = edev->resource[2].start;
writel(readl(auxio_reg)|0x2, auxio_reg);
+ sun_pci_ebus_dev = ebus->self;
+
sun_pci_fd_ebus_dma = (struct linux_ebus_dma *)
edev->resource[1].start;
sun_pci_fd_reset_dma();
diff --git a/include/asm-sparc64/io.h b/include/asm-sparc64/io.h
index 5dc5c88c6..37a1e847b 100644
--- a/include/asm-sparc64/io.h
+++ b/include/asm-sparc64/io.h
@@ -13,7 +13,7 @@
#define __SLOW_DOWN_IO do { } while (0)
#define SLOW_DOWN_IO do { } while (0)
-#undef NEW_PCI_DMA_MAP
+#define NEW_PCI_DMA_MAP
#ifndef NEW_PCI_DMA_MAP
#define PCI_DVMA_HASHSZ 256
diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h
index 97aeaf7f6..5184ba51a 100644
--- a/include/asm-sparc64/parport.h
+++ b/include/asm-sparc64/parport.h
@@ -149,7 +149,7 @@ parport_pc_init(int *io, int *io_hi, int *irq, int *dma)
if (parport_pc_probe_port(base, base + 0x400,
edev->irqs[0],
- count))
+ count, ebus->self))
count++;
}
}
diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h
index 4131b698f..881de6c2f 100644
--- a/include/asm-sparc64/pci.h
+++ b/include/asm-sparc64/pci.h
@@ -1,8 +1,6 @@
#ifndef __SPARC64_PCI_H
#define __SPARC64_PCI_H
-#include <asm/scatterlist.h>
-
/* Can be used to override the logic in pci_scan_bus for skipping
* already-configured bus numbers - to be used for buggy BIOSes
* or architectures with incomplete PCI setup by the loader.
@@ -12,32 +10,37 @@
#define PCIBIOS_MIN_IO 0UL
#define PCIBIOS_MIN_MEM 0UL
+#ifdef __KERNEL__
+
+/* Dynamic DMA mapping stuff.
+ */
+
+#include <asm/scatterlist.h>
+
struct pci_dev;
-/* Allocate and map kernel buffer using consistant mode DMA for PCI device.
- * Returns non-NULL cpu-view pointer to the buffer if successful and
- * sets *dma_addrp to the pci side dma address as well, else *dma_addrp
- * is undefined.
+/* Allocate and map kernel buffer using consistent mode DMA for a device.
+ * hwdev should be valid struct pci_dev pointer for PCI devices.
*/
-extern void *pci_alloc_consistant(struct pci_dev *pdev, long size, u32 *dma_addrp);
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle);
-/* Free and unmap a consistant DMA buffer.
- * cpu_addr is what was returned from pci_alloc_consistant,
- * size must be the same as what as passed into pci_alloc_consistant,
+/* Free and unmap a consistent DMA buffer.
+ * cpu_addr is what was returned from pci_alloc_consistent,
+ * size must be the same as what as passed into pci_alloc_consistent,
* and likewise dma_addr must be the same as what *dma_addrp was set to.
*
* References to the memory and mappings assosciated with cpu_addr/dma_addr
* past this call are illegal.
*/
-extern void pci_free_consistant(struct pci_dev *pdev, long size, void *cpu_addr, u32 dma_addr);
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle);
-/* Map a single buffer of the indicate size for PCI DMA in streaming mode.
- * The 32-bit PCI bus mastering address to use is returned.
+/* Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
*
* Once the device is given the dma address, the device owns this memory
- * until either pci_unmap_single or pci_sync_single is performed.
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
*/
-extern u32 pci_map_single(struct pci_dev *pdev, void *buffer, long size);
+extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size);
/* Unmap a single streaming mode DMA translation. The dma_addr and size
* must match what was provided for in a previous pci_map_single call. All
@@ -46,32 +49,32 @@ extern u32 pci_map_single(struct pci_dev *pdev, void *buffer, long size);
* After this call, reads by the cpu to the buffer are guarenteed to see
* whatever the device wrote there.
*/
-extern void pci_unmap_single(struct pci_dev *pdev, u32 dma_addr, long size);
+extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size);
/* Map a set of buffers described by scatterlist in streaming
- * mode for PCI DMA. This is the scather-gather version of the
+ * mode for DMA. This is the scather-gather version of the
* above pci_map_single interface. Here the scatter gather list
- * elements are each tagged with the appropriate PCI dma address
+ * elements are each tagged with the appropriate dma address
* and length. They are obtained via sg_dma_{address,length}(SG).
*
* NOTE: An implementation may be able to use a smaller number of
* DMA address/length pairs than there are SG table elements.
* (for example via virtual mapping capabilities)
- * The routine returns the number of addr/length pairs actually
- * used, at most nents.
+ * The routine returns the number of addr/length pairs actually
+ * used, at most nents.
*
* Device ownership issues as mentioned above for pci_map_single are
* the same here.
*/
-extern int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents);
+extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents);
/* Unmap a set of streaming mode DMA translations.
* Again, cpu read rules concerning calls here are the same as for
* pci_unmap_single() above.
*/
-extern void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents);
+extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nhwents);
-/* Make physical memory consistant for a single
+/* Make physical memory consistent for a single
* streaming mode DMA translation after a transfer.
*
* If you perform a pci_map_single() but wish to interrogate the
@@ -80,14 +83,16 @@ extern void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents
* next point you give the PCI dma address back to the card, the
* device again owns the buffer.
*/
-extern void pci_dma_sync_single(struct pci_dev *, u32, long);
+extern void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size);
-/* Make physical memory consistant for a set of streaming
+/* Make physical memory consistent for a set of streaming
* mode DMA translations after a transfer.
*
* The same as pci_dma_sync_single but for a scatter-gather list,
* same rules and usage.
*/
-extern void pci_dma_sync_sg(struct pci_dev *, struct scatterlist *, int);
+extern void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nelems);
+
+#endif /* __KERNEL__ */
#endif /* __SPARC64_PCI_H */
diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h
index 807dd0cf4..158fbbf39 100644
--- a/include/asm-sparc64/processor.h
+++ b/include/asm-sparc64/processor.h
@@ -1,4 +1,4 @@
-/* $Id: processor.h,v 1.60 2000/01/07 20:21:45 davem Exp $
+/* $Id: processor.h,v 1.61 2000/01/21 11:39:22 jj Exp $
* include/asm-sparc64/processor.h
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -56,16 +56,11 @@ struct thread_struct {
unsigned char __pad1[3];
struct pt_regs *kregs;
- /* D$ line 2 */
+ /* D$ line 2, 3, 4 */
unsigned long *utraps;
unsigned char gsr[7];
unsigned char __pad2;
- unsigned long sig_address;
- unsigned long sig_desc;
-
- /* D$ lines 3 and 4 */
unsigned long xfsr[7];
- unsigned long __pad3;
struct reg_window reg_window[NSWINS];
unsigned long rwbuf_stkptrs[NSWINS];
@@ -92,10 +87,8 @@ struct thread_struct {
0, 0, 0, 0, KERNEL_DS, \
/* w_saved, fpdepth, fpsaved, pad1, kregs, */ \
0, 0, { 0 }, { 0 }, 0, \
-/* utraps, gsr, pad2, sig_address, sig_desc, */ \
- 0, { 0 }, 0, 0, 0, \
-/* xfsr, pad3, */ \
- { 0 }, 0, \
+/* utraps, gsr, pad2, xfsr, */ \
+ 0, { 0 }, 0, { 0 }, \
/* reg_window */ \
{ { { 0, }, { 0, } }, }, \
/* rwbuf_stkptrs */ \
diff --git a/include/asm-sparc64/sbus.h b/include/asm-sparc64/sbus.h
index 1718e234f..1b0b5137a 100644
--- a/include/asm-sparc64/sbus.h
+++ b/include/asm-sparc64/sbus.h
@@ -94,18 +94,18 @@ extern struct sbus_bus *sbus_root;
#define sbus_can_burst64(sdev) (1)
extern void sbus_set_sbus64(struct sbus_dev *, int);
-/* These yield IOMMU mappings in consistant mode. */
-extern void *sbus_alloc_consistant(struct sbus_dev *, long, u32 *dma_addrp);
-extern void sbus_free_consistant(struct sbus_dev *, long, void *, u32);
+/* These yield IOMMU mappings in consistent mode. */
+extern void *sbus_alloc_consistent(struct sbus_dev *, size_t, dma_addr_t *dma_addrp);
+extern void sbus_free_consistent(struct sbus_dev *, size_t, void *, dma_addr_t);
/* All the rest use streaming mode mappings. */
-extern u32 sbus_map_single(struct sbus_dev *, void *, long);
-extern void sbus_unmap_single(struct sbus_dev *, u32, long);
+extern dma_addr_t sbus_map_single(struct sbus_dev *, void *, size_t);
+extern void sbus_unmap_single(struct sbus_dev *, dma_addr_t, size_t);
extern int sbus_map_sg(struct sbus_dev *, struct scatterlist *, int);
extern void sbus_unmap_sg(struct sbus_dev *, struct scatterlist *, int);
/* Finally, allow explicit synchronization of streamable mappings. */
-extern void sbus_dma_sync_single(struct sbus_dev *, u32, long);
+extern void sbus_dma_sync_single(struct sbus_dev *, dma_addr_t, size_t);
extern void sbus_dma_sync_sg(struct sbus_dev *, struct scatterlist *, int);
#endif /* !(_SPARC64_SBUS_H) */
diff --git a/include/asm-sparc64/semaphore.h b/include/asm-sparc64/semaphore.h
index 046385d3c..1d7b0e31c 100644
--- a/include/asm-sparc64/semaphore.h
+++ b/include/asm-sparc64/semaphore.h
@@ -253,11 +253,18 @@ struct rw_semaphore {
#define __RWSEM_DEBUG_INIT /* */
#endif
-#define __RWSEM_INITIALIZER(name) \
-{ RW_LOCK_BIAS, 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
+#define __RWSEM_INITIALIZER(name,count) \
+{ (count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
__WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait) \
__SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT }
+#define __DECLARE_RWSEM_GENERIC(name,count) \
+ struct rw_semaphore name = __RWSEM_INITIALIZER(name,count)
+
+#define DECLARE_RWSEM(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS)
+#define DECLARE_RWSEM_READ_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS-1)
+#define DECLARE_RWSEM_WRITE_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,0)
+
extern inline void init_rwsem(struct rw_semaphore *sem)
{
sem->count = RW_LOCK_BIAS;
diff --git a/include/asm-sparc64/siginfo.h b/include/asm-sparc64/siginfo.h
index 9e60d6015..ee7d80809 100644
--- a/include/asm-sparc64/siginfo.h
+++ b/include/asm-sparc64/siginfo.h
@@ -141,6 +141,11 @@ typedef struct siginfo32 {
#define si_band _sifields._sigpoll._band
#define si_fd _sifields._sigpoll._fd
+#ifdef __KERNEL__
+#define __SI_MASK 0
+#define __SI_FAULT 0
+#endif
+
/*
* si_code values
* Digital reserves positive values for kernel-generated signals.
@@ -187,7 +192,7 @@ typedef struct siginfo32 {
* SIGSEGV si_codes
*/
#define SEGV_MAPERR 1 /* address not mapped to object */
-#define SRGV_ACCERR 2 /* invalid permissions for mapped object */
+#define SEGV_ACCERR 2 /* invalid permissions for mapped object */
#define NSIGSEGV 2
/*
@@ -214,7 +219,7 @@ typedef struct siginfo32 {
#define CLD_TRAPPED 4 /* traced child has trapped */
#define CLD_STOPPED 5 /* child has stopped */
#define CLD_CONTINUED 6 /* stopped child has continued */
-#define NSIGCHLD
+#define NSIGCHLD 6
/*
* SIGPOLL si_codes
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
index 7cd66aa56..116fe903e 100644
--- a/include/asm-sparc64/smp.h
+++ b/include/asm-sparc64/smp.h
@@ -68,13 +68,17 @@ extern void smp_callin(void);
extern void smp_boot_cpus(void);
extern void smp_store_cpu_info(int id);
-extern __volatile__ int cpu_number_map[NR_CPUS];
+extern __volatile__ int __cpu_number_map[NR_CPUS];
extern __volatile__ int __cpu_logical_map[NR_CPUS];
extern __inline__ int cpu_logical_map(int cpu)
{
return __cpu_logical_map[cpu];
}
+extern __inline__ int cpu_number_map(int cpu)
+{
+ return __cpu_number_map[cpu];
+}
extern __inline__ int hard_smp_processor_id(void)
{
diff --git a/include/asm-sparc64/termbits.h b/include/asm-sparc64/termbits.h
index 6d490333c..faa32e785 100644
--- a/include/asm-sparc64/termbits.h
+++ b/include/asm-sparc64/termbits.h
@@ -204,6 +204,9 @@ struct termios {
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
diff --git a/include/asm-sparc64/types.h b/include/asm-sparc64/types.h
index e96909af4..f8e42235c 100644
--- a/include/asm-sparc64/types.h
+++ b/include/asm-sparc64/types.h
@@ -45,6 +45,10 @@ typedef unsigned long u64;
#define BITS_PER_LONG 64
+/* Dma addresses are 32-bits wide for now. */
+
+typedef u32 dma_addr_t;
+
#endif /* __KERNEL__ */
#endif /* defined(_SPARC64_TYPES_H) */
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
index 49c063d44..d1c874480 100644
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.39 2000/01/11 17:34:05 jj Exp $ */
+/* $Id: unistd.h,v 1.40 2000/01/16 06:20:38 davem Exp $ */
#ifndef _SPARC64_UNISTD_H
#define _SPARC64_UNISTD_H
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index c96ef3283..5b1ad645c 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -24,7 +24,6 @@
#include <linux/types.h>
#include <linux/ioctl.h>
#ifdef __KERNEL__
-#include <linux/config.h>
#include <linux/sched.h>
#include <linux/wait.h>
#endif /* __KERNEL__ */
@@ -57,139 +56,10 @@ enum
typedef int acpi_dstate_t;
-/*
- * HID (PnP) values
- */
-enum
-{
- ACPI_UNKNOWN_HID = 0x00000000, /* generic */
- ACPI_KBC_HID = 0x41d00303, /* keyboard controller */
- ACPI_COM_HID = 0x41d00500, /* serial port */
- ACPI_FDC_HID = 0x41d00700, /* floppy controller */
- ACPI_VGA_HID = 0x41d00900, /* VGA controller */
- ACPI_ISA_HID = 0x41d00a00, /* ISA bus */
- ACPI_EISA_HID = 0x41d00a01, /* EISA bus */
- ACPI_PCI_HID = 0x41d00a03, /* PCI bus */
-};
-
-typedef int acpi_hid_t;
-
#ifdef __KERNEL__
-/*
- * Device types
- */
-enum
-{
- ACPI_SYS_DEV, /* system device (fan, KB controller, ...) */
- ACPI_PCI_DEV, /* generic PCI device */
- ACPI_PCI_BUS, /* PCI bus */
- ACPI_ISA_DEV, /* generic ISA device */
- ACPI_ISA_BUS, /* ISA bus */
- ACPI_USB_DEV, /* generic USB device */
- ACPI_USB_HUB, /* USB hub device */
- ACPI_USB_CTRL, /* USB controller */
- ACPI_SCSI_DEV, /* generic SCSI device */
- ACPI_SCSI_CTRL, /* SCSI controller */
-};
-
-typedef int acpi_dev_t;
-
-/*
- * Device addresses
- */
-#define ACPI_PCI_ADR(dev) ((dev)->bus->number << 16 | (dev)->devfn)
-
-struct acpi_dev;
-
-/*
- * Device state transition function
- */
-typedef int (*acpi_transition)(struct acpi_dev *dev, acpi_dstate_t state);
-
-/*
- * Static device information
- */
-struct acpi_dev_info
-{
- acpi_dev_t type; /* device type */
- acpi_hid_t hid; /* PnP identifier */
- acpi_transition transition; /* state transition callback */
-
- /* other information like D-states supported,
- * D-state latencies, and in-rush current needs
- * will go here
- */
-};
-
-/*
- * Dynamic device information
- */
-struct acpi_dev
-{
- struct acpi_dev_info info; /* static device info */
- unsigned long adr; /* bus address or unique id */
- acpi_dstate_t state; /* current D-state */
- unsigned long accessed; /* last access time */
- unsigned long idle; /* last idle time */
- struct list_head entry; /* linked list entry */
-};
-
-#ifdef CONFIG_ACPI
-
-extern wait_queue_head_t acpi_control_wait;
-
-/*
- * Register a device with the ACPI subsystem
- */
-struct acpi_dev *acpi_register(struct acpi_dev_info *info, unsigned long adr);
-
-/*
- * Unregister a device with ACPI
- */
-void acpi_unregister(struct acpi_dev *dev);
-
-/*
- * Update device access time and wake up device, if necessary
- */
-extern inline void acpi_access(struct acpi_dev *dev)
-{
- extern void acpi_wakeup(struct acpi_dev*);
- if (dev) {
- if (dev->state != ACPI_D0)
- acpi_wakeup(dev);
- dev->accessed = jiffies;
- }
-}
-
-/*
- * Identify device as currently being idle
- */
-extern inline void acpi_dev_idle(struct acpi_dev *dev)
-{
- if (dev) {
- dev->idle = jiffies;
- if (waitqueue_active(&acpi_control_wait))
- wake_up(&acpi_control_wait);
- }
-}
-
extern int acpi_active;
-#else /* CONFIG_ACPI */
-
-extern inline struct acpi_dev*
-acpi_register(struct acpi_dev_info *info, unsigned long adr)
-{
- return 0;
-}
-
-extern inline void acpi_unregister(struct acpi_dev *dev) {}
-extern inline void acpi_access(struct acpi_dev *dev) {}
-extern inline void acpi_dev_idle(struct acpi_dev *dev) {}
-
-#endif /* CONFIG_ACPI */
-
extern void (*acpi_idle)(void);
extern void (*acpi_power_off)(void);
diff --git a/include/linux/auto_fs.h b/include/linux/auto_fs.h
index 9a0ddd6c4..a8b313539 100644
--- a/include/linux/auto_fs.h
+++ b/include/linux/auto_fs.h
@@ -20,7 +20,8 @@
#include <linux/ioctl.h>
#include <asm/types.h>
-#define AUTOFS_PROTO_VERSION 3
+#define AUTOFS_MIN_PROTO_VERSION 3 /* Min version we support */
+#define AUTOFS_PROTO_VERSION 4 /* Current version */
/*
* Architectures where both 32- and 64-bit binaries can be executed
@@ -46,6 +47,7 @@ typedef unsigned long autofs_wqt_t;
enum autofs_packet_type {
autofs_ptype_missing, /* Missing entry (mount request) */
autofs_ptype_expire, /* Expire entry (umount request) */
+ autofs_ptype_expire_multi, /* Expire entry (umount request) */
};
struct autofs_packet_hdr {
@@ -60,18 +62,35 @@ struct autofs_packet_missing {
char name[NAME_MAX+1];
};
+/* v3 expire (via ioctl) */
struct autofs_packet_expire {
struct autofs_packet_hdr hdr;
int len;
char name[NAME_MAX+1];
};
+/* v4 multi expire (via pipe) */
+struct autofs_packet_expire_multi {
+ struct autofs_packet_hdr hdr;
+ autofs_wqt_t wait_queue_token;
+ int len;
+ char name[NAME_MAX+1];
+};
+
+union autofs_packet_union {
+ struct autofs_packet_hdr hdr;
+ struct autofs_packet_missing missing;
+ struct autofs_packet_expire expire;
+ struct autofs_packet_expire_multi expire_multi;
+};
+
#define AUTOFS_IOC_READY _IO(0x93,0x60)
#define AUTOFS_IOC_FAIL _IO(0x93,0x61)
#define AUTOFS_IOC_CATATONIC _IO(0x93,0x62)
#define AUTOFS_IOC_PROTOVER _IOR(0x93,0x63,int)
#define AUTOFS_IOC_SETTIMEOUT _IOWR(0x93,0x64,unsigned long)
#define AUTOFS_IOC_EXPIRE _IOR(0x93,0x65,struct autofs_packet_expire)
+#define AUTOFS_IOC_EXPIRE_MULTI _IOW(0x93,0x66,int)
#ifdef __KERNEL__
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index e8b4c0b9b..c86eecc9b 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -25,7 +25,8 @@ struct request {
int errors;
unsigned long sector;
unsigned long nr_sectors;
- unsigned long nr_segments;
+ unsigned int nr_segments;
+ unsigned int nr_hw_segments;
unsigned long current_nr_sectors;
void * special;
char * buffer;
diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h
index 13b877ec7..78f7d426b 100644
--- a/include/linux/cdrom.h
+++ b/include/linux/cdrom.h
@@ -872,6 +872,10 @@ typedef struct {
__u32 last_rec_address;
} track_information;
+extern int cdrom_get_disc_info(kdev_t dev, disc_information *di);
+extern int cdrom_get_track_info(kdev_t dev, __u16 track, __u8 type,
+ track_information *ti);
+
/* The SCSI spec says there could be 256 slots. */
#define CDROM_MAX_SLOTS 256
diff --git a/include/linux/cyclomx.h b/include/linux/cyclomx.h
index 2e387395e..983295c18 100644
--- a/include/linux/cyclomx.h
+++ b/include/linux/cyclomx.h
@@ -13,6 +13,8 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
* ============================================================================
+* 2000/01/21 acme rename cyclomx_open to cyclomx_mod_inc_use_count
+* and cyclomx_close to cyclomx_mod_dec_use_count
* 1999/05/19 acme wait_queue_head_t wait_stats(support for 2.3.*)
* 1999/01/03 acme judicious use of data types
* 1998/12/27 acme cleanup: PACKED not needed
@@ -80,8 +82,8 @@ typedef struct cycx {
} cycx_t;
/* Public Functions */
-void cyclomx_open (cycx_t *card); /* cycx_main.c */
-void cyclomx_close (cycx_t *card); /* cycx_main.c */
+void cyclomx_mod_inc_use_count (cycx_t *card); /* cycx_main.c */
+void cyclomx_mod_dec_use_count (cycx_t *card); /* cycx_main.c */
void cyclomx_set_state (cycx_t *card, int state); /* cycx_main.c */
#ifdef CONFIG_CYCLOMX_X25
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 56ace40e0..f008ca74f 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -24,7 +24,6 @@
#ifndef _LINUX_ETHERDEVICE_H
#define _LINUX_ETHERDEVICE_H
-#include <linux/config.h>
#include <linux/if_ether.h>
#ifdef __KERNEL__
@@ -41,7 +40,7 @@ extern int eth_header_parse(struct sk_buff *skb,
unsigned char *haddr);
extern struct net_device * init_etherdev(struct net_device *, int);
-#ifdef CONFIG_IP_ROUTER
+#if 1 /*def CONFIG_IP_ROUTER*/
static __inline__ void eth_copy_and_sum (struct sk_buff *dest, unsigned char *src, int len, int base)
{
memcpy (dest->data, src, len);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0046b3f7e..35530b777 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -19,6 +19,7 @@
#include <linux/dcache.h>
#include <linux/stat.h>
#include <linux/cache.h>
+#include <linux/stddef.h>
#include <asm/atomic.h>
#include <asm/bitops.h>
@@ -66,10 +67,6 @@ extern int max_super_blocks, nr_super_blocks;
#define WRITERAW 5 /* raw write - don't play with buffer lists */
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
-
#define NIL_FILP ((struct file *)0)
#define SEL_IN 1
#define SEL_OUT 2
@@ -783,9 +780,9 @@ extern int register_chrdev(unsigned int, const char *, struct file_operations *)
extern int unregister_chrdev(unsigned int, const char *);
extern int chrdev_open(struct inode *, struct file *);
extern struct file_operations def_chr_fops;
-extern char * bdevname(kdev_t);
-extern char * cdevname(kdev_t);
-extern char * kdevname(kdev_t);
+extern const char * bdevname(kdev_t);
+extern const char * cdevname(kdev_t);
+extern const char * kdevname(kdev_t);
extern void init_special_inode(struct inode *, umode_t, int);
extern struct inode_operations fifo_inode_operations;
@@ -1001,8 +998,8 @@ extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *);
extern ssize_t generic_file_write(struct file *, const char *, size_t, loff_t *, writepage_t);
extern void do_generic_file_read(struct file *, loff_t *, read_descriptor_t *, read_actor_t);
-extern int vfs_readlink(struct dentry *, char *, int, char *);
-extern struct dentry *vfs_follow_link(struct dentry *, struct dentry *, unsigned, char *);
+extern int vfs_readlink(struct dentry *, char *, int, const char *);
+extern struct dentry *vfs_follow_link(struct dentry *, struct dentry *, unsigned, const char *);
extern int page_readlink(struct dentry *, char *, int);
extern struct dentry *page_follow_link(struct dentry *, struct dentry *, unsigned);
diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h
index a2f08879c..fcac3cd06 100644
--- a/include/linux/hdreg.h
+++ b/include/linux/hdreg.h
@@ -49,6 +49,7 @@
#define WIN_SEEK 0x70
#define WIN_DIAGNOSE 0x90
#define WIN_SPECIFY 0x91 /* set drive geometry translation */
+#define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */
#define WIN_SETIDLE1 0xE3
#define WIN_SETIDLE2 0x97
diff --git a/include/linux/hfs_sysdep.h b/include/linux/hfs_sysdep.h
index c3b866f25..5172139ec 100644
--- a/include/linux/hfs_sysdep.h
+++ b/include/linux/hfs_sysdep.h
@@ -121,7 +121,7 @@ extern inline void hfs_mdb_dirty(hfs_sysmdb sys_mdb) {
sys_mdb->s_dirt = 1;
}
-extern inline char *hfs_mdb_name(hfs_sysmdb sys_mdb) {
+extern inline const char *hfs_mdb_name(hfs_sysmdb sys_mdb) {
return kdevname(sys_mdb->s_dev);
}
diff --git a/include/linux/highuid.h b/include/linux/highuid.h
index 40f121ca7..5d287bbb3 100644
--- a/include/linux/highuid.h
+++ b/include/linux/highuid.h
@@ -63,13 +63,6 @@ extern int overflowgid;
#define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
#define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
-/* specific to kernel/signal.c */
-#ifdef UID16_SIGINFO_COMPAT_NEEDED
-#define SET_SIGINFO_UID16(var, uid) var = high2lowuid(uid)
-#else
-#define SET_SIGINFO_UID16(var, uid) do { ; } while (0)
-#endif
-
#else
#define SET_UID16(var, uid) do { ; } while (0)
@@ -82,8 +75,6 @@ extern int overflowgid;
#define SET_STAT_UID(stat, uid) (stat).st_uid = uid
#define SET_STAT_GID(stat, gid) (stat).st_gid = gid
-#define SET_SIGINFO_UID16(var, uid) do { ; } while (0)
-
#endif /* CONFIG_UID16 */
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 1b438bf74..49ce1c179 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -373,7 +373,10 @@ typedef struct hwif_s {
ide_selectproc_t *selectproc; /* tweaks hardware to select drive */
ide_resetproc_t *resetproc; /* routine to reset controller after a disk reset */
ide_dmaproc_t *dmaproc; /* dma read/write/abort routine */
- unsigned long *dmatable; /* dma physical region descriptor table */
+ unsigned int *dmatable_cpu; /* dma physical region descriptor table (cpu view) */
+ u32 dmatable_dma; /* dma physical region descriptor table (dma view) */
+ struct scatterlist *sg_table; /* Scatter-gather list used to build the above */
+ int sg_nents; /* Current number of entries in it */
struct hwif_s *mate; /* other hwif from same PCI chip */
unsigned long dma_base; /* base addr for dma ports */
unsigned dma_extra; /* extra addr for dma ports */
@@ -836,6 +839,7 @@ void ide_scan_pcibus (int scan_direction) __init;
#define BAD_DMA_DRIVE 0
#define GOOD_DMA_DRIVE 1
int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func);
+void ide_destroy_dmatable (ide_drive_t *drive);
ide_startstop_t ide_dma_intr (ide_drive_t *drive);
int check_drive_lists (ide_drive_t *drive, int good_bad);
int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive);
diff --git a/include/linux/init.h b/include/linux/init.h
index 4d4e6e156..20fc892e9 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -90,7 +90,7 @@ extern struct kernel_param __setup_start, __setup_end;
#define __exit
#define __initdata
#define __exitdata
-#define __initcall
+#define __initcall(fn)
/* For assembly routines */
#define __INIT
#define __FINIT
diff --git a/include/linux/input.h b/include/linux/input.h
index 1e998c944..fefc77b51 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -285,11 +285,16 @@ struct input_event {
#define BTN_MODE 0x13c
#define BTN_DIGI 0x140
-#define BTN_PEN 0x140
-#define BTN_RUBBER 0x141
-#define BTN_PEN_SIDE 0x142
-#define BTN_PEN_SIDE2 0x143
-#define BTN_NEAR 0x144
+#define BTN_TOOL_PEN 0x140
+#define BTN_TOOL_RUBBER 0x141
+#define BTN_TOOL_BRUSH 0x142
+#define BTN_TOOL_PENCIL 0x143
+#define BTN_TOOL_AIRBRUSH 0x144
+#define BTN_TOOL_FINGER 0x145
+#define BTN_TOOL_MOUSE 0x146
+#define BTN_TOUCH 0x147
+#define BTN_STYLUS 0x148
+#define BTN_STYLUS2 0x149
#define KEY_MAX 0x1ff
diff --git a/include/linux/isapnp.h b/include/linux/isapnp.h
index 5a074285e..7a52a7c4d 100644
--- a/include/linux/isapnp.h
+++ b/include/linux/isapnp.h
@@ -128,7 +128,7 @@ struct isapnp_resources {
struct isapnp_resources *next; /* next resource */
};
-#if defined(CONFIG_ISAPNP) || defined(CONFIG_ISAPNP_MODULE)
+#if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE))
#define __ISAPNP__
diff --git a/include/linux/kdev_t.h b/include/linux/kdev_t.h
index a06cdb9ed..aeee1fbee 100644
--- a/include/linux/kdev_t.h
+++ b/include/linux/kdev_t.h
@@ -73,7 +73,7 @@ typedef unsigned short kdev_t;
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
#define B_FREE 0xffff /* yuk */
-extern char * kdevname(kdev_t); /* note: returns pointer to static data! */
+extern const char * kdevname(kdev_t); /* note: returns pointer to static data! */
/*
As long as device numbers in the outside world have 16 bits only,
diff --git a/include/linux/mm.h b/include/linux/mm.h
index d5daeba2c..0d7609741 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -451,25 +451,23 @@ extern struct page *filemap_nopage(struct vm_area_struct * area,
* GFP bitmasks..
*/
#define __GFP_WAIT 0x01
-#define __GFP_LOW 0x02
-#define __GFP_MED 0x04
-#define __GFP_HIGH 0x08
-#define __GFP_IO 0x10
-#define __GFP_SWAP 0x20
+#define __GFP_HIGH 0x02
+#define __GFP_IO 0x04
+#define __GFP_SWAP 0x08
#ifdef CONFIG_HIGHMEM
-#define __GFP_HIGHMEM 0x40
+#define __GFP_HIGHMEM 0x10
#else
#define __GFP_HIGHMEM 0x0 /* noop */
#endif
-#define __GFP_DMA 0x80
-#define __GFP_UNCACHED 0x100
+#define __GFP_DMA 0x20
+#define __GFP_UNCACHED 0x40
-#define GFP_BUFFER (__GFP_LOW | __GFP_WAIT)
+#define GFP_BUFFER (__GFP_WAIT)
#define GFP_ATOMIC (__GFP_HIGH)
-#define GFP_USER (__GFP_LOW | __GFP_WAIT | __GFP_IO)
+#define GFP_USER (__GFP_WAIT | __GFP_IO)
#define GFP_HIGHUSER (GFP_USER | __GFP_HIGHMEM)
-#define GFP_KERNEL (__GFP_MED | __GFP_WAIT | __GFP_IO)
+#define GFP_KERNEL (__GFP_HIGH | __GFP_WAIT | __GFP_IO)
#define GFP_NFS (__GFP_HIGH | __GFP_WAIT | __GFP_IO)
#define GFP_KSWAPD (__GFP_IO | __GFP_SWAP)
diff --git a/include/linux/parport_pc.h b/include/linux/parport_pc.h
index 6898c4e5f..9a25fea0d 100644
--- a/include/linux/parport_pc.h
+++ b/include/linux/parport_pc.h
@@ -37,6 +37,8 @@ struct parport_pc_private {
/* buffer suitable for DMA, if DMA enabled */
char *dma_buf;
+ dma_addr_t dma_handle;
+ struct pci_dev *dev;
};
extern __inline__ void parport_pc_write_data(struct parport *p, unsigned char d)
@@ -175,6 +177,7 @@ extern void parport_pc_dec_use_count(void);
/* PCMCIA code will want to get us to look at a port. Provide a mechanism. */
extern struct parport *parport_pc_probe_port (unsigned long base,
unsigned long base_hi,
- int irq, int dma);
+ int irq, int dma,
+ struct pci_dev *dev);
#endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 3c51b15e7..6472c3b59 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -315,6 +315,11 @@ struct pci_dev {
struct pci_driver *driver; /* which driver has allocated this device */
void *driver_data; /* data private to the driver */
+ dma_addr_t dma_mask; /* Mask of the bits of bus address this
+ device implements. Normally this is
+ 0xffffffff. You only need to change
+ this if your device has broken DMA
+ or supports 64-bit transfers. */
/* device is compatible with these IDs */
unsigned short vendor_compatible[DEVICE_COUNT_COMPATIBLE];
@@ -462,16 +467,16 @@ int pci_proc_detach_device(struct pci_dev *dev);
void pci_name_device(struct pci_dev *dev);
char *pci_class_name(u32 class);
void pci_read_bridge_bases(struct pci_bus *child);
-struct resource *pci_find_parent_resource(struct pci_dev *dev, struct resource *res);
+struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res);
int pci_setup_device(struct pci_dev * dev);
/* Generic PCI functions exported to card drivers */
-struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, struct pci_dev *from);
+struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from);
struct pci_dev *pci_find_subsys (unsigned int vendor, unsigned int device,
unsigned int ss_vendor, unsigned int ss_device,
- struct pci_dev *from);
-struct pci_dev *pci_find_class (unsigned int class, struct pci_dev *from);
+ const struct pci_dev *from);
+struct pci_dev *pci_find_class (unsigned int class, const struct pci_dev *from);
struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
int pci_find_capability (struct pci_dev *dev, int cap);
@@ -526,8 +531,8 @@ int pci_register_driver(struct pci_driver *);
void pci_unregister_driver(struct pci_driver *);
void pci_insert_device(struct pci_dev *, struct pci_bus *);
void pci_remove_device(struct pci_dev *);
-struct pci_driver *pci_dev_driver(struct pci_dev *);
-const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, struct pci_dev *dev);
+struct pci_driver *pci_dev_driver(const struct pci_dev *);
+const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev);
/*
* If the system does not have PCI, clearly these return errors. Define
@@ -548,17 +553,17 @@ extern inline int pcibios_present(void) { return 0; }
_PCI_NOP_ALL(read, *)
_PCI_NOP_ALL(write,)
-extern inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
+extern inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from)
{ return NULL; }
-extern inline struct pci_dev *pci_find_class(unsigned int class, struct pci_dev *from)
+extern inline struct pci_dev *pci_find_class(unsigned int class, const struct pci_dev *from)
{ return NULL; }
extern inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn)
{ return NULL; }
extern inline struct pci_dev *pci_find_subsys(unsigned int vendor, unsigned int device,
-unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from)
+unsigned int ss_vendor, unsigned int ss_device, const struct pci_dev *from)
{ return NULL; }
extern inline void pci_set_master(struct pci_dev *dev) { }
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 23e74d28b..ffc2aa7f3 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -829,6 +829,7 @@
#define PCI_VENDOR_ID_ATT 0x11c1
#define PCI_DEVICE_ID_ATT_L56XMF 0x0440
+#define PCI_DEVICE_ID_ATT_VENUS_MODEM 0x480
#define PCI_VENDOR_ID_SPECIALIX 0x11cb
#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000
@@ -1020,7 +1021,15 @@
#define PCI_DEVICE_ID_NETGEAR_GA620 0x620a
#define PCI_VENDOR_ID_LAVA 0x1407
-#define PCI_DEVICE_ID_LAVA_DUAL_SERIAL 0x0100
+#define PCI_DEVICE_ID_LAVA_DSERIAL 0x0100 /* 2x 16550 */
+#define PCI_DEVICE_ID_LAVA_QUATRO_A 0x0101 /* 2x 16550, half of 4 port */
+#define PCI_DEVICE_ID_LAVA_QUATRO_B 0x0102 /* 2x 16550, half of 4 port */
+#define PCI_DEVICE_ID_LAVA_PORT_PLUS 0x0200 /* 2x 16650 */
+#define PCI_DEVICE_ID_LAVA_QUAD_A 0x0201 /* 2x 16650, half of 4 port */
+#define PCI_DEVICE_ID_LAVA_QUAD_B 0x0202 /* 2x 16650, half of 4 port */
+#define PCI_DEVICE_ID_LAVA_SSERIAL 0x0500 /* 1x 16550 */
+#define PCI_DEVICE_ID_LAVA_PORT_650 0x0600 /* 1x 16650 */
+
#define PCI_DEVICE_ID_LAVA_PARALLEL 0x8000
#define PCI_DEVICE_ID_LAVA_DUAL_PAR_A 0x8002 /* The Lava Dual Parallel is */
#define PCI_DEVICE_ID_LAVA_DUAL_PAR_B 0x8003 /* two PCI devices on a card */
@@ -1031,6 +1040,8 @@
#define PCI_VENDOR_ID_OXSEMI 0x1415
#define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501
+#define PCI_DEVICE_ID_OXSEMI_16PCI952 0x950A
+#define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511
#define PCI_VENDOR_ID_PANACOM 0x14d4
#define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400
diff --git a/include/linux/pm.h b/include/linux/pm.h
new file mode 100644
index 000000000..8108f3764
--- /dev/null
+++ b/include/linux/pm.h
@@ -0,0 +1,157 @@
+/*
+ * pm.h - Power management interface
+ *
+ * Copyright (C) 2000 Andrew Henroid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 _LINUX_PM_H
+#define _LINUX_PM_H
+
+#include <linux/config.h>
+#include <linux/list.h>
+
+/*
+ * Power management requests
+ */
+enum
+{
+ PM_SUSPEND, /* enter D1-D3 */
+ PM_RESUME, /* enter D0 */
+
+ /* enable wake-on */
+ PM_SET_WAKEUP,
+
+ /* bus resource management */
+ PM_GET_RESOURCES,
+ PM_SET_RESOURCES,
+
+ /* base station management */
+ PM_EJECT,
+ PM_LOCK,
+};
+
+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 */
+};
+
+typedef int pm_dev_t;
+
+/*
+ * System device hardware ID (PnP) values
+ */
+enum
+{
+ PM_SYS_UNKNOWN = 0x00000000, /* generic */
+ PM_SYS_KBC = 0x41d00303, /* keyboard controller */
+ PM_SYS_COM = 0x41d00500, /* serial port */
+ PM_SYS_FDC = 0x41d00700, /* floppy controller */
+ PM_SYS_VGA = 0x41d00900, /* VGA controller */
+};
+
+/*
+ * Device identifier
+ */
+#define PM_PCI_ID(dev) ((dev)->bus->number << 16 | (dev)->devfn)
+
+/*
+ * Request handler callback
+ */
+struct pm_dev;
+
+typedef int (*pm_callback)(struct pm_dev *dev, pm_request_t rqst, void *data);
+
+/*
+ * Dynamic device information
+ */
+struct pm_dev
+{
+ pm_dev_t type;
+ unsigned long id;
+ pm_callback callback;
+ void *data;
+
+ unsigned long flags;
+ unsigned long status;
+
+ struct list_head entry;
+};
+
+#if defined(CONFIG_ACPI) || defined(CONFIG_APM)
+
+/*
+ * Register a device with power management
+ */
+struct pm_dev *pm_register(pm_dev_t type,
+ unsigned long id,
+ pm_callback callback);
+
+/*
+ * Unregister a device with power management
+ */
+void pm_unregister(struct pm_dev *dev);
+
+/*
+ * Send a request to all devices
+ */
+int pm_send_request(pm_request_t rqst, void *data);
+
+/*
+ * Find a device
+ */
+struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from);
+
+extern inline void pm_access(struct pm_dev *dev) {}
+extern inline void pm_dev_idle(struct pm_dev *dev) {}
+
+#else // CONFIG_ACPI || CONFIG_APM
+
+extern inline struct pm_dev *pm_register(pm_dev_t type,
+ unsigned long id,
+ pm_callback callback)
+{
+ return 0;
+}
+
+extern inline void pm_unregister(struct pm_dev *dev) {}
+
+extern inline int pm_send_request(pm_request_t rqst, void *data)
+{
+ return 0;
+}
+
+extern inline struct pm_dev *pm_find(pm_dev_t type, struct pm_dev *from)
+{
+ return 0;
+}
+
+extern inline void pm_access(struct pm_dev *dev) {}
+extern inline void pm_dev_idle(struct pm_dev *dev) {}
+
+#endif // CONFIG_ACPI || CONFIG_APM
+
+#endif /* _LINUX_PM_H */
diff --git a/include/linux/random.h b/include/linux/random.h
index 10a7fd810..b830c859c 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -46,6 +46,8 @@ extern void rand_initialize(void);
extern void rand_initialize_irq(int irq);
extern void rand_initialize_blkdev(int irq, int mode);
+extern void batch_entropy_store(u32 a, u32 b, int num);
+
extern void add_keyboard_randomness(unsigned char scancode);
extern void add_mouse_randomness(__u32 mouse_data);
extern void add_interrupt_randomness(int irq);
diff --git a/include/linux/sdla_chdlc.h b/include/linux/sdla_chdlc.h
new file mode 100644
index 000000000..c82fe14b0
--- /dev/null
+++ b/include/linux/sdla_chdlc.h
@@ -0,0 +1,808 @@
+/*************************************************************************
+ sdla_chdlc.h Sangoma Cisco HDLC firmware API definitions
+
+ Author: Gideon Hack
+ Nenad Corbic <ncorbic@sangoma.com>
+
+ Copyright: (c) 1995-1999 Sangoma Technologies Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the term of the GNU General Public License
+ as published by the Free Software Foundation; either version
+ 2 of the License, or (at your option) any later version.
+
+===========================================================================
+ Oct 04, 1999 Nenad Corbic Updated API support
+ Jun 02, 1999 Gideon Hack Changes for S514 usage.
+ Oct 28, 1998 Jaspreet Singh Made changes for Dual Port CHDLC.
+ Jun 11, 1998 David Fong Initial version.
+===========================================================================
+
+ Organization
+ - Compatibility notes
+ - Constants defining the shared memory control block (mailbox)
+ - Interface commands
+ - Return code from interface commands
+ - Constants for the commands (structures for casting data)
+ - UDP Management constants and structures
+
+*************************************************************************/
+
+#ifndef _SDLA_CHDLC_H
+# define _SDLC_CHDLC_H
+
+/*------------------------------------------------------------------------
+ Notes:
+
+ All structres defined in this file are byte-aligned.
+
+ Compiler Platform
+ ------------------------
+ GNU C Linux
+
+------------------------------------------------------------------------*/
+
+#ifndef PACKED
+#define PACKED __attribute__((packed))
+#endif /* PACKED */
+
+
+/* ----------------------------------------------------------------------------
+ * Constants defining the shared memory control block (mailbox)
+ * --------------------------------------------------------------------------*/
+
+#define PRI_BASE_ADDR_MB_STRUCT 0xE000 /* the base address of the mailbox structure on the adapter */
+#define SEC_BASE_ADDR_MB_STRUCT 0xE800 /* the base address of the mailbox structure on the adapter */
+#define SIZEOF_MB_DATA_BFR 2032 /* the size of the actual mailbox data area */
+#define NUMBER_MB_RESERVED_BYTES 0x0B /* the number of reserved bytes in the mailbox header area */
+
+
+#define MIN_LGTH_CHDLC_DATA_CFG 300 /* min length of the CHDLC data field (for configuration purposes) */
+#define PRI_MAX_NO_DATA_BYTES_IN_FRAME 15354 /* PRIMARY - max length of the CHDLC data field */
+
+typedef struct {
+ unsigned char opp_flag PACKED; /* the opp flag */
+ unsigned char command PACKED; /* the user command */
+ unsigned short buffer_length PACKED; /* the data length */
+ unsigned char return_code PACKED; /* the return code */
+ unsigned char MB_reserved[NUMBER_MB_RESERVED_BYTES] PACKED; /* reserved for later */
+ unsigned char data[SIZEOF_MB_DATA_BFR] PACKED; /* the data area */
+} CHDLC_MAILBOX_STRUCT;
+
+typedef struct {
+ pid_t pid_num PACKED;
+ CHDLC_MAILBOX_STRUCT cmdarea PACKED;
+
+} CMDBLOCK_STRUCT;
+
+
+
+
+/* ----------------------------------------------------------------------------
+ * Interface commands
+ * --------------------------------------------------------------------------*/
+
+/* global interface commands */
+#define READ_GLOBAL_EXCEPTION_CONDITION 0x01
+#define SET_GLOBAL_CONFIGURATION 0x02
+#define READ_GLOBAL_CONFIGURATION 0x03
+#define READ_GLOBAL_STATISTICS 0x04
+#define FLUSH_GLOBAL_STATISTICS 0x05
+#define SET_MODEM_STATUS 0x06 /* set status of DTR or RTS */
+#define READ_MODEM_STATUS 0x07 /* read status of CTS and DCD */
+#define READ_COMMS_ERROR_STATS 0x08
+#define FLUSH_COMMS_ERROR_STATS 0x09
+#define SET_TRACE_CONFIGURATION 0x0A /* set the line trace config */
+#define READ_TRACE_CONFIGURATION 0x0B /* read the line trace config */
+#define READ_TRACE_STATISTICS 0x0C /* read the trace statistics */
+#define FLUSH_TRACE_STATISTICS 0x0D /* flush the trace statistics */
+#define FT1_MONITOR_STATUS_CTRL 0x1C /* set the status of the S508/FT1 monitoring */
+#define SET_FT1_CONFIGURATION 0x18 /* set the FT1 configuration */
+#define READ_FT1_CONFIGURATION 0x19 /* read the FT1 configuration */
+#define TRANSMIT_ASYNC_DATA_TO_FT1 0x1A /* output asynchronous data to the FT1 */
+#define RECEIVE_ASYNC_DATA_FROM_FT1 0x1B /* receive asynchronous data from the FT1 */
+#define FT1_MONITOR_STATUS_CTRL 0x1C /* set the status of the FT1 monitoring */
+
+#define READ_FT1_OPERATIONAL_STATS 0x1D /* read the S508/FT1 operational statistics */
+#define SET_FT1_MODE 0x1E /* set the operational mode of the S508/FT1 module */
+
+/* CHDLC-level interface commands */
+#define READ_CHDLC_CODE_VERSION 0x20
+#define READ_CHDLC_EXCEPTION_CONDITION 0x21 /* read exception condition from the adapter */
+#define SET_CHDLC_CONFIGURATION 0x22
+#define READ_CHDLC_CONFIGURATION 0x23
+#define ENABLE_CHDLC_COMMUNICATIONS 0x24
+#define DISABLE_CHDLC_COMMUNICATIONS 0x25
+#define READ_CHDLC_LINK_STATUS 0x26
+#define READ_CHDLC_OPERATIONAL_STATS 0x27
+#define FLUSH_CHDLC_OPERATIONAL_STATS 0x28
+#define SET_CHDLC_INTERRUPT_TRIGGERS 0x30 /* set application interrupt triggers */
+#define READ_CHDLC_INTERRUPT_TRIGGERS 0x31 /* read application interrupt trigger configuration */
+
+/* Special UDP drivers management commands */
+#define CPIPE_ENABLE_TRACING 0x50
+#define CPIPE_DISABLE_TRACING 0x51
+#define CPIPE_GET_TRACE_INFO 0x52
+#define CPIPE_GET_IBA_DATA 0x53
+#define CPIPE_FT1_READ_STATUS 0x54
+#define CPIPE_DRIVER_STAT_IFSEND 0x55
+#define CPIPE_DRIVER_STAT_INTR 0x56
+#define CPIPE_DRIVER_STAT_GEN 0x57
+#define CPIPE_FLUSH_DRIVER_STATS 0x58
+#define CPIPE_ROUTER_UP_TIME 0x59
+
+/* Driver specific commands for API */
+#define CHDLC_READ_TRACE_DATA 0xE4 /* read trace data */
+#define TRACE_ALL 0x00
+#define TRACE_PROT 0x01
+#define TRACE_DATA 0x02
+
+/* ----------------------------------------------------------------------------
+ * Return codes from interface commands
+ * --------------------------------------------------------------------------*/
+
+#define COMMAND_OK 0x00
+
+/* return codes from global interface commands */
+#define NO_GLOBAL_EXCEP_COND_TO_REPORT 0x01 /* there is no CHDLC exception condition to report */
+#define LGTH_GLOBAL_CFG_DATA_INVALID 0x01 /* the length of the passed global configuration data is invalid */
+#define LGTH_TRACE_CFG_DATA_INVALID 0x01 /* the length of the passed trace configuration data is invalid */
+#define IRQ_TIMEOUT_VALUE_INVALID 0x02 /* an invalid application IRQ timeout value was selected */
+#define TRACE_CONFIG_INVALID 0x02 /* the passed line trace configuration is invalid */
+#define ADAPTER_OPERATING_FREQ_INVALID 0x03 /* an invalid adapter operating frequency was selected */
+#define TRC_DEAC_TMR_INVALID 0x03 /* the trace deactivation timer is invalid */
+#define S508_FT1_ADPTR_NOT_PRESENT 0x0C /* the S508/FT1 adapter is not present */
+#define INVALID_FT1_STATUS_SELECTION 0x0D /* the S508/FT1 status selection is invalid */
+#define FT1_OP_STATS_NOT_ENABLED 0x0D /* the FT1 operational statistics have not been enabled */
+#define FT1_OP_STATS_NOT_AVAILABLE 0x0E /* the FT1 operational statistics are not currently available */
+#define S508_FT1_MODE_SELECTION_BUSY 0x0E /* the S508/FT1 adapter is busy selecting the operational mode */
+
+/* return codes from command READ_GLOBAL_EXCEPTION_CONDITION */
+#define EXCEP_MODEM_STATUS_CHANGE 0x10 /* a modem status change occurred */
+#define EXCEP_TRC_DISABLED 0x11 /* the trace has been disabled */
+#define EXCEP_IRQ_TIMEOUT 0x12 /* IRQ timeout */
+
+/* return codes from CHDLC-level interface commands */
+#define NO_CHDLC_EXCEP_COND_TO_REPORT 0x21 /* there is no CHDLC exception condition to report */
+#define CHDLC_COMMS_DISABLED 0x21 /* communications are not currently enabled */
+#define CHDLC_COMMS_ENABLED 0x21 /* communications are currently enabled */
+#define DISABLE_CHDLC_COMMS_BEFORE_CFG 0x21 /* CHDLC communications must be disabled before setting the configuration */
+#define ENABLE_CHDLC_COMMS_BEFORE_CONN 0x21 /* communications must be enabled before using the CHDLC_CONNECT conmmand */
+#define CHDLC_CFG_BEFORE_COMMS_ENABLED 0x22 /* perform a SET_CHDLC_CONFIGURATION before enabling comms */
+#define LGTH_CHDLC_CFG_DATA_INVALID 0x22 /* the length of the passed CHDLC configuration data is invalid */
+#define LGTH_INT_TRIGGERS_DATA_INVALID 0x22 /* the length of the passed interrupt trigger data is invalid */
+#define INVALID_IRQ_SELECTED 0x23 /* in invalid IRQ was selected in the SET_CHDLC_INTERRUPT_TRIGGERS */
+#define INVALID_CHDLC_CFG_DATA 0x23 /* the passed CHDLC configuration data is invalid */
+#define IRQ_TMR_VALUE_INVALID 0x24 /* an invalid application IRQ timer value was selected */
+#define LARGER_PERCENT_TX_BFR_REQUIRED 0x24 /* a larger Tx buffer percentage is required */
+#define LARGER_PERCENT_RX_BFR_REQUIRED 0x25 /* a larger Rx buffer percentage is required */
+#define S514_BOTH_PORTS_SAME_CLK_MODE 0x26 /* S514 - both ports must have same clock mode */
+#define INVALID_CMND_HDLC_STREAM_MODE 0x4E /* the CHDLC interface command is invalid for HDLC streaming mode */
+#define INVALID_CHDLC_COMMAND 0x4F /* the defined CHDLC interface command is invalid */
+
+/* return codes from command READ_CHDLC_EXCEPTION_CONDITION */
+#define EXCEP_LINK_ACTIVE 0x30 /* the CHDLC link has become active */
+#define EXCEP_LINK_INACTIVE_MODEM 0x31 /* the CHDLC link has become inactive (modem status) */
+#define EXCEP_LINK_INACTIVE_KPALV 0x32 /* the CHDLC link has become inactive (keepalive status) */
+#define EXCEP_IP_ADDRESS_DISCOVERED 0x33 /* the IP address has been discovered */
+#define EXCEP_LOOPBACK_CONDITION 0x34 /* a loopback condition has occurred */
+
+
+/* return code from command CHDLC_SEND_WAIT and CHDLC_SEND_NO_WAIT */
+#define LINK_DISCONNECTED 0x21
+#define NO_TX_BFRS_AVAIL 0x24
+
+
+/* ----------------------------------------------------------------------------
+ * Constants for the SET_GLOBAL_CONFIGURATION/READ_GLOBAL_CONFIGURATION commands
+ * --------------------------------------------------------------------------*/
+
+/* the global configuration structure */
+typedef struct {
+ unsigned short adapter_config_options PACKED; /* adapter config options */
+ unsigned short app_IRQ_timeout PACKED; /* application IRQ timeout */
+ unsigned long adapter_operating_frequency PACKED; /* adapter operating frequency */
+} GLOBAL_CONFIGURATION_STRUCT;
+
+/* settings for the 'app_IRQ_timeout' */
+#define MAX_APP_IRQ_TIMEOUT_VALUE 5000 /* the maximum permitted IRQ timeout */
+
+
+
+/* ----------------------------------------------------------------------------
+ * Constants for the READ_GLOBAL_STATISTICS command
+ * --------------------------------------------------------------------------*/
+
+/* the global statistics structure */
+typedef struct {
+ unsigned short app_IRQ_timeout_count PACKED;
+} GLOBAL_STATS_STRUCT;
+
+
+
+/* ----------------------------------------------------------------------------
+ * Constants for the READ_COMMS_ERROR_STATS command
+ * --------------------------------------------------------------------------*/
+
+/* the communications error statistics structure */
+typedef struct {
+ unsigned short Rx_overrun_err_count PACKED;
+ unsigned short CRC_err_count PACKED; /* receiver CRC error count */
+ unsigned short Rx_abort_count PACKED; /* abort frames recvd count */
+ unsigned short Rx_dis_pri_bfrs_full_count PACKED;/* receiver disabled */
+ unsigned short comms_err_stat_reserved_1 PACKED;/* reserved for later */
+ unsigned short sec_Tx_abort_msd_Tx_int_count PACKED; /* secondary - abort frames transmitted count (missed Tx interrupt) */
+ unsigned short missed_Tx_und_int_count PACKED; /* missed tx underrun interrupt count */
+ unsigned short sec_Tx_abort_count PACKED; /*secondary-abort frames tx count */
+ unsigned short DCD_state_change_count PACKED; /* DCD state change */
+ unsigned short CTS_state_change_count PACKED; /* CTS state change */
+} COMMS_ERROR_STATS_STRUCT;
+
+
+
+/* ----------------------------------------------------------------------------
+ * Constants used for line tracing
+ * --------------------------------------------------------------------------*/
+
+/* the trace configuration structure (SET_TRACE_CONFIGURATION/READ_TRACE_CONFIGURATION commands) */
+typedef struct {
+ unsigned char trace_config PACKED; /* trace configuration */
+ unsigned short trace_deactivation_timer PACKED; /* trace deactivation timer */
+ unsigned long ptr_trace_stat_el_cfg_struct PACKED; /* a pointer to the line trace element configuration structure */
+} LINE_TRACE_CONFIG_STRUCT;
+
+/* 'trace_config' bit settings */
+#define TRACE_INACTIVE 0x00 /* trace is inactive */
+#define TRACE_ACTIVE 0x01 /* trace is active */
+#define TRACE_DELAY_MODE 0x04 /* operate the trace in delay mode */
+#define TRACE_DATA_FRAMES 0x08 /* trace Data frames */
+#define TRACE_SLARP_FRAMES 0x10 /* trace SLARP frames */
+#define TRACE_CDP_FRAMES 0x20 /* trace CDP frames */
+
+/* the line trace status element configuration structure */
+typedef struct {
+ unsigned short number_trace_status_elements PACKED; /* number of line trace elements */
+ unsigned long base_addr_trace_status_elements PACKED; /* base address of the trace element list */
+ unsigned long next_trace_element_to_use PACKED; /* pointer to the next trace element to be used */
+ unsigned long base_addr_trace_buffer PACKED; /* base address of the trace data buffer */
+ unsigned long end_addr_trace_buffer PACKED; /* end address of the trace data buffer */
+} TRACE_STATUS_EL_CFG_STRUCT;
+
+/* the line trace status element structure */
+typedef struct {
+ unsigned char opp_flag PACKED; /* opp flag */
+ unsigned short trace_length PACKED; /* trace length */
+ unsigned char trace_type PACKED; /* trace type */
+ unsigned short trace_time_stamp PACKED; /* time stamp */
+ unsigned short trace_reserved_1 PACKED; /* reserved for later use */
+ unsigned long trace_reserved_2 PACKED; /* reserved for later use */
+ unsigned long ptr_data_bfr PACKED; /* ptr to the trace data buffer */
+} TRACE_STATUS_ELEMENT_STRUCT;
+
+/* "trace_type" bit settings */
+#define TRACE_INCOMING 0x00
+#define TRACE_OUTGOINGING 0x01
+#define TRACE_INCOMING_ABORTED 0x10
+#define TRACE_INCOMING_CRC_ERROR 0x20
+#define TRACE_INCOMING_OVERRUN_ERROR 0x40
+
+
+
+/* the line trace statistics structure */
+typedef struct {
+ unsigned long frames_traced_count PACKED; /* number of frames traced */
+ unsigned long trc_frms_not_recorded_count PACKED; /* number of trace frames discarded */
+} LINE_TRACE_STATS_STRUCT;
+
+
+/* ----------------------------------------------------------------------------
+ * Constants for the FT1_MONITOR_STATUS_CTRL command
+ * --------------------------------------------------------------------------*/
+
+#define DISABLE_FT1_STATUS_STATISTICS 0x00 /* disable the FT1 status and statistics monitoring */
+#define ENABLE_READ_FT1_STATUS 0x01 /* read the FT1 operational status */
+#define ENABLE_READ_FT1_OP_STATS 0x02 /* read the FT1 operational statistics */
+#define FLUSH_FT1_OP_STATS 0x04 /* flush the FT1 operational statistics */
+
+
+
+
+/* ----------------------------------------------------------------------------
+ * Constants for the SET_CHDLC_CONFIGURATION command
+ * --------------------------------------------------------------------------*/
+
+/* the CHDLC configuration structure */
+typedef struct {
+ unsigned long baud_rate PACKED; /* the baud rate */
+ unsigned short line_config_options PACKED; /* line configuration options */
+ unsigned short modem_config_options PACKED; /* modem configration options */
+ unsigned short modem_status_timer PACKED; /* timer for monitoring modem status changes */
+ unsigned short CHDLC_API_options PACKED; /* CHDLC API options */
+ unsigned short CHDLC_protocol_options PACKED; /* CHDLC protocol options */
+ unsigned short percent_data_buffer_for_Tx PACKED; /* percentage data buffering used for Tx */
+ unsigned short CHDLC_statistics_options PACKED; /* CHDLC operational statistics options */
+ unsigned short max_CHDLC_data_field_length PACKED; /* the maximum length of the CHDLC Data field */
+ unsigned short transmit_keepalive_timer PACKED; /* the transmit keepalive timer */
+ unsigned short receive_keepalive_timer PACKED; /* the receive keepalive timer */
+ unsigned short keepalive_error_tolerance PACKED; /* the receive keepalive error tolerance */
+ unsigned short SLARP_request_timer PACKED; /* the SLARP request timer */
+ unsigned long IP_address PACKED; /* the IP address */
+ unsigned long IP_netmask PACKED; /* the IP netmask */
+ unsigned long ptr_shared_mem_info_struct PACKED; /* a pointer to the shared memory area information structure */
+ unsigned long ptr_CHDLC_Tx_stat_el_cfg_struct PACKED; /* a pointer to the transmit status element configuration structure */
+ unsigned long ptr_CHDLC_Rx_stat_el_cfg_struct PACKED; /* a pointer to the receive status element configuration structure */
+} CHDLC_CONFIGURATION_STRUCT;
+
+/* settings for the 'line_config_options' */
+#define INTERFACE_LEVEL_V35 0x0000 /* V.35 interface level */
+#define INTERFACE_LEVEL_RS232 0x0001 /* RS-232 interface level */
+
+/* settings for the 'modem_config_options' */
+
+#define DONT_RAISE_DTR_RTS_ON_EN_COMMS 0x0001
+/* don't automatically raise DTR and RTS when performing an
+ ENABLE_CHDLC_COMMUNICATIONS command */
+
+#define DONT_REPORT_CHG_IN_MODEM_STAT 0x0002
+/* don't report changes in modem status to the application */
+
+
+/* bit settings for the 'CHDLC_protocol_options' byte */
+
+#define IGNORE_DCD_FOR_LINK_STAT 0x0001
+/* ignore DCD in determining the CHDLC link status */
+
+#define IGNORE_CTS_FOR_LINK_STAT 0x0002
+/* ignore CTS in determining the CHDLC link status */
+
+#define IGNORE_KPALV_FOR_LINK_STAT 0x0004
+/* ignore keepalive frames in determining the CHDLC link status */
+
+#define HDLC_STREAMING_MODE 0x8000
+
+/* settings for the 'CHDLC_statistics_options' */
+
+#define CHDLC_TX_DATA_BYTE_COUNT_STAT 0x0001
+/* record the number of Data bytes transmitted */
+
+#define CHDLC_RX_DATA_BYTE_COUNT_STAT 0x0002
+/* record the number of Data bytes received */
+
+#define CHDLC_TX_THROUGHPUT_STAT 0x0004
+/* compute the Data frame transmit throughput */
+
+#define CHDLC_RX_THROUGHPUT_STAT 0x0008
+/* compute the Data frame receive throughput */
+
+
+/* permitted minimum and maximum values for setting the CHDLC configuration */
+#define PRI_MAX_BAUD_RATE_S508 2666666 /* PRIMARY - maximum baud rate (S508) */
+#define SEC_MAX_BAUD_RATE_S508 258064 /* SECONDARY - maximum baud rate (S508) */
+#define PRI_MAX_BAUD_RATE_S514 2750000 /* PRIMARY - maximum baud rate (S508) */
+#define SEC_MAX_BAUD_RATE_S514 515625 /* SECONDARY - maximum baud rate (S508) */
+
+#define MIN_MODEM_TIMER 0 /* minimum modem status timer */
+#define MAX_MODEM_TIMER 5000 /* maximum modem status timer */
+
+#define SEC_MAX_NO_DATA_BYTES_IN_FRAME 2048 /* SECONDARY - max length of the CHDLC data field */
+
+#define MIN_Tx_KPALV_TIMER 0 /* minimum transmit keepalive timer */
+#define MAX_Tx_KPALV_TIMER 60000 /* maximum transmit keepalive timer */
+#define DEFAULT_Tx_KPALV_TIMER 10000 /* default transmit keepalive timer */
+
+#define MIN_Rx_KPALV_TIMER 10 /* minimum receive keepalive timer */
+#define MAX_Rx_KPALV_TIMER 60000 /* maximum receive keepalive timer */
+#define DEFAULT_Rx_KPALV_TIMER 10000 /* default receive keepalive timer */
+
+#define MIN_KPALV_ERR_TOL 1 /* min kpalv error tolerance count */
+#define MAX_KPALV_ERR_TOL 20 /* max kpalv error tolerance count */
+#define DEFAULT_KPALV_ERR_TOL 3 /* default value */
+
+#define MIN_SLARP_REQ_TIMER 0 /* min transmit SLARP Request timer */
+#define MAX_SLARP_REQ_TIMER 60000 /* max transmit SLARP Request timer */
+#define DEFAULT_SLARP_REQ_TIMER 0 /* default value -- no SLARP */
+
+
+
+/* ----------------------------------------------------------------------------
+ * Constants for the READ_CHDLC_LINK_STATUS command
+ * --------------------------------------------------------------------------*/
+
+/* the CHDLC status structure */
+typedef struct {
+ unsigned char CHDLC_link_status PACKED; /* CHDLC link status */
+ unsigned char no_Data_frms_for_app PACKED; /* number of Data frames available for the application */
+ unsigned char receiver_status PACKED; /* enabled/disabled */
+ unsigned char SLARP_state PACKED; /* internal SLARP state */
+} CHDLC_LINK_STATUS_STRUCT;
+
+/* settings for the 'CHDLC_link_status' variable */
+#define CHDLC_LINK_INACTIVE 0x00 /* the CHDLC link is inactive */
+#define CHDLC_LINK_ACTIVE 0x01 /* the CHDLC link is active */
+
+
+
+/* ----------------------------------------------------------------------------
+ * Constants for the READ_CHDLC_OPERATIONAL_STATS command
+ * --------------------------------------------------------------------------*/
+
+/* the CHDLC operational statistics structure */
+typedef struct {
+
+ /* Data frame transmission statistics */
+ unsigned long Data_frames_Tx_count PACKED; /* # of frames transmitted */
+ unsigned long Data_bytes_Tx_count PACKED; /* # of bytes transmitted */
+ unsigned long Data_Tx_throughput PACKED; /* transmit throughput */
+ unsigned long no_ms_for_Data_Tx_thruput_comp PACKED; /* millisecond time used for the Tx throughput computation */
+ unsigned long Tx_Data_discard_lgth_err_count PACKED; /* number of Data frames discarded (length error) */
+ unsigned long reserved_Data_frm_Tx_stat1 PACKED; /* reserved for later */
+ unsigned long reserved_Data_frm_Tx_stat2 PACKED; /* reserved for later */
+ unsigned long reserved_Data_frm_Tx_stat3 PACKED; /* reserved for later */
+
+ /* Data frame reception statistics */
+ unsigned long Data_frames_Rx_count PACKED; /* number of frames received */
+ unsigned long Data_bytes_Rx_count PACKED; /* number of bytes received */
+ unsigned long Data_Rx_throughput PACKED; /* receive throughput */
+ unsigned long no_ms_for_Data_Rx_thruput_comp PACKED; /* millisecond time used for the Rx throughput computation */
+ unsigned long Rx_Data_discard_short_count PACKED; /* received Data frames discarded (too short) */
+ unsigned long Rx_Data_discard_long_count PACKED; /* received Data frames discarded (too long) */
+ unsigned long Rx_Data_discard_inactive_count PACKED; /* received Data frames discarded (link inactive) */
+ unsigned long reserved_Data_frm_Rx_stat1 PACKED; /* reserved for later */
+
+ /* SLARP frame transmission/reception statistics */
+ unsigned long CHDLC_SLARP_REQ_Tx_count PACKED; /* number of SLARP Request frames transmitted */
+ unsigned long CHDLC_SLARP_REQ_Rx_count PACKED; /* number of SLARP Request frames received */
+ unsigned long CHDLC_SLARP_REPLY_Tx_count PACKED; /* number of SLARP Reply frames transmitted */
+ unsigned long CHDLC_SLARP_REPLY_Rx_count PACKED; /* number of SLARP Reply frames received */
+ unsigned long CHDLC_SLARP_KPALV_Tx_count PACKED; /* number of SLARP keepalive frames transmitted */
+ unsigned long CHDLC_SLARP_KPALV_Rx_count PACKED; /* number of SLARP keepalive frames received */
+ unsigned long reserved_SLARP_stat1 PACKED; /* reserved for later */
+ unsigned long reserved_SLARP_stat2 PACKED; /* reserved for later */
+
+ /* CDP frame transmission/reception statistics */
+ unsigned long CHDLC_CDP_Tx_count PACKED; /* number of CDP frames transmitted */
+ unsigned long CHDLC_CDP_Rx_count PACKED; /* number of CDP frames received */
+ unsigned long reserved_CDP_stat1 PACKED; /* reserved for later */
+ unsigned long reserved_CDP_stat2 PACKED; /* reserved for later */
+ unsigned long reserved_CDP_stat3 PACKED; /* reserved for later */
+ unsigned long reserved_CDP_stat4 PACKED; /* reserved for later */
+ unsigned long reserved_CDP_stat5 PACKED; /* reserved for later */
+ unsigned long reserved_CDP_stat6 PACKED; /* reserved for later */
+
+ /* Incomming frames with a format error statistics */
+ unsigned short Rx_frm_incomp_CHDLC_hdr_count PACKED; /* frames received of with incomplete Cisco HDLC header */
+ unsigned short Rx_frms_too_long_count PACKED; /* frames received of excessive length count */
+ unsigned short Rx_invalid_CHDLC_addr_count PACKED; /* frames received with an invalid CHDLC address count */
+ unsigned short Rx_invalid_CHDLC_ctrl_count PACKED; /* frames received with an invalid CHDLC control field count */
+ unsigned short Rx_invalid_CHDLC_type_count PACKED; /* frames received of an invalid CHDLC frame type count */
+ unsigned short Rx_SLARP_invalid_code_count PACKED; /* SLARP frame received with an invalid packet code */
+ unsigned short Rx_SLARP_Reply_bad_IP_addr PACKED; /* SLARP Reply received - bad IP address */
+ unsigned short Rx_SLARP_Reply_bad_netmask PACKED; /* SLARP Reply received - bad netmask */
+ unsigned long reserved_frm_format_err1 PACKED; /* reserved for later */
+ unsigned long reserved_frm_format_err2 PACKED; /* reserved for later */
+ unsigned long reserved_frm_format_err3 PACKED; /* reserved for later */
+ unsigned long reserved_frm_format_err4 PACKED; /* reserved for later */
+
+ /* CHDLC timeout/retry statistics */
+ unsigned short SLARP_Rx_keepalive_TO_count PACKED; /* timeout count for incomming SLARP frames */
+ unsigned short SLARP_Request_TO_count PACKED; /* timeout count for SLARP Request frames */
+ unsigned long To_retry_reserved_stat1 PACKED; /* reserved for later */
+ unsigned long To_retry_reserved_stat2 PACKED; /* reserved for later */
+ unsigned long To_retry_reserved_stat3 PACKED; /* reserved for later */
+
+ /* CHDLC link active/inactive and loopback statistics */
+ unsigned short link_active_count PACKED; /* number of times that the link went active */
+ unsigned short link_inactive_modem_count PACKED; /* number of times that the link went inactive (modem failure) */
+ unsigned short link_inactive_keepalive_count PACKED; /* number of times that the link went inactive (keepalive failure) */
+ unsigned short link_looped_count PACKED; /* link looped count */
+ unsigned long link_status_reserved_stat1 PACKED; /* reserved for later use */
+ unsigned long link_status_reserved_stat2 PACKED; /* reserved for later use */
+
+ /* miscellaneous statistics */
+ unsigned long reserved_misc_stat1 PACKED; /* reserved for later */
+ unsigned long reserved_misc_stat2 PACKED; /* reserved for later */
+ unsigned long reserved_misc_stat3 PACKED; /* reserved for later */
+ unsigned long reserved_misc_stat4 PACKED; /* reserved for later */
+
+} CHDLC_OPERATIONAL_STATS_STRUCT;
+
+
+
+/* ----------------------------------------------------------------------------
+ * Constants for using application interrupts
+ * --------------------------------------------------------------------------*/
+
+/* the structure used for the SET_CHDLC_INTERRUPT_TRIGGERS/READ_CHDLC_INTERRUPT_TRIGGERS command */
+typedef struct {
+ unsigned char CHDLC_interrupt_triggers PACKED; /* CHDLC interrupt trigger configuration */
+ unsigned char IRQ PACKED; /* IRQ to be used */
+ unsigned short interrupt_timer PACKED; /* interrupt timer */
+ unsigned short misc_interrupt_bits PACKED; /* miscellaneous bits */
+} CHDLC_INT_TRIGGERS_STRUCT;
+
+/* 'CHDLC_interrupt_triggers' bit settings */
+#define APP_INT_ON_RX_FRAME 0x01 /* interrupt on Data frame reception */
+#define APP_INT_ON_TX_FRAME 0x02 /* interrupt when an Data frame may be transmitted */
+#define APP_INT_ON_COMMAND_COMPLETE 0x04 /* interrupt when an interface command is complete */
+#define APP_INT_ON_TIMER 0x08 /* interrupt on a defined millisecond timeout */
+#define APP_INT_ON_GLOBAL_EXCEP_COND 0x10 /* interrupt on a global exception condition */
+#define APP_INT_ON_CHDLC_EXCEP_COND 0x20 /* interrupt on an CHDLC exception condition */
+#define APP_INT_ON_TRACE_DATA_AVAIL 0x80 /* interrupt when trace data is available */
+
+/* interrupt types indicated at 'interrupt_type' byte of the INTERRUPT_INFORMATION_STRUCT */
+#define NO_APP_INTS_PEND 0x00 /* no interrups are pending */
+#define RX_APP_INT_PEND 0x01 /* a receive interrupt is pending */
+#define TX_APP_INT_PEND 0x02 /* a transmit interrupt is pending */
+#define COMMAND_COMPLETE_APP_INT_PEND 0x04 /* a 'command complete' interrupt is pending */
+#define TIMER_APP_INT_PEND 0x08 /* a timer interrupt is pending */
+#define GLOBAL_EXCEP_COND_APP_INT_PEND 0x10 /* a global exception condition interrupt is pending */
+#define CHDLC_EXCEP_COND_APP_INT_PEND 0x20 /* an CHDLC exception condition interrupt is pending */
+#define TRACE_DATA_AVAIL_APP_INT_PEND 0x80 /* a trace data available interrupt is pending */
+
+
+/* modem status changes */
+#define DCD_HIGH 0x08
+#define CTS_HIGH 0x20
+
+
+/* ----------------------------------------------------------------------------
+ * Constants for Data frame transmission
+ * --------------------------------------------------------------------------*/
+
+/* the Data frame transmit status element configuration structure */
+typedef struct {
+ unsigned short number_Tx_status_elements PACKED; /* number of transmit status elements */
+ unsigned long base_addr_Tx_status_elements PACKED; /* base address of the transmit element list */
+ unsigned long next_Tx_status_element_to_use PACKED; /* pointer to the next transmit element to be used */
+} CHDLC_TX_STATUS_EL_CFG_STRUCT;
+
+/* the Data frame transmit status element structure */
+typedef struct {
+ unsigned char opp_flag PACKED; /* opp flag */
+ unsigned short frame_length PACKED; /* length of the frame to be transmitted */
+ unsigned char reserved_1 PACKED; /* reserved for internal use */
+ unsigned long reserved_2 PACKED; /* reserved for internal use */
+ unsigned long reserved_3 PACKED; /* reserved for internal use */
+ unsigned long ptr_data_bfr PACKED; /* pointer to the data area */
+} CHDLC_DATA_TX_STATUS_EL_STRUCT;
+
+
+
+/* ----------------------------------------------------------------------------
+ * Constants for Data frame reception
+ * --------------------------------------------------------------------------*/
+
+/* the Data frame receive status element configuration structure */
+typedef struct {
+ unsigned short number_Rx_status_elements PACKED; /* number of receive status elements */
+ unsigned long base_addr_Rx_status_elements PACKED; /* base address of the receive element list */
+ unsigned long next_Rx_status_element_to_use PACKED; /* pointer to the next receive element to be used */
+ unsigned long base_addr_Rx_buffer PACKED; /* base address of the receive data buffer */
+ unsigned long end_addr_Rx_buffer PACKED; /* end address of the receive data buffer */
+} CHDLC_RX_STATUS_EL_CFG_STRUCT;
+
+/* the Data frame receive status element structure */
+typedef struct {
+ unsigned char opp_flag PACKED; /* opp flag */
+ unsigned short frame_length PACKED; /* length of the received frame */
+ unsigned char error_flag PACKED; /* frame errors (HDLC_STREAMING_MODE)*/
+ unsigned short time_stamp PACKED; /* receive time stamp (HDLC_STREAMING_MODE) */
+ unsigned long reserved_1 PACKED; /* reserved for internal use */
+ unsigned short reserved_2 PACKED; /* reserved for internal use */
+ unsigned long ptr_data_bfr PACKED; /* pointer to the data area */
+} CHDLC_DATA_RX_STATUS_EL_STRUCT;
+
+
+
+/* ----------------------------------------------------------------------------
+ * Constants defining the shared memory information area
+ * --------------------------------------------------------------------------*/
+
+/* the global information structure */
+typedef struct {
+ unsigned char global_status PACKED; /* global status */
+ unsigned char modem_status PACKED; /* current modem status */
+ unsigned char global_excep_conditions PACKED; /* global exception conditions */
+ unsigned char glob_info_reserved[5] PACKED; /* reserved */
+ unsigned char codename[4] PACKED; /* Firmware name */
+ unsigned char codeversion[4] PACKED; /* Firmware version */
+} GLOBAL_INFORMATION_STRUCT;
+
+/* the CHDLC information structure */
+typedef struct {
+ unsigned char CHDLC_status PACKED; /* CHDLC status */
+ unsigned char CHDLC_excep_conditions PACKED; /* CHDLC exception conditions */
+ unsigned char CHDLC_info_reserved[14] PACKED; /* reserved */
+} CHDLC_INFORMATION_STRUCT;
+
+/* the interrupt information structure */
+typedef struct {
+ unsigned char interrupt_type PACKED; /* type of interrupt triggered */
+ unsigned char interrupt_permission PACKED; /* interrupt permission mask */
+ unsigned char int_info_reserved[14] PACKED; /* reserved */
+} INTERRUPT_INFORMATION_STRUCT;
+
+/* the S508/FT1 information structure */
+typedef struct {
+ unsigned char parallel_port_A_input PACKED; /* input - parallel port A */
+ unsigned char parallel_port_B_input PACKED; /* input - parallel port B */
+ unsigned char FT1_info_reserved[14] PACKED; /* reserved */
+} FT1_INFORMATION_STRUCT;
+
+/* the shared memory area information structure */
+typedef struct {
+ GLOBAL_INFORMATION_STRUCT global_info_struct PACKED; /* the global information structure */
+ CHDLC_INFORMATION_STRUCT CHDLC_info_struct PACKED; /* the CHDLC information structure */
+ INTERRUPT_INFORMATION_STRUCT interrupt_info_struct PACKED; /* the interrupt information structure */
+ FT1_INFORMATION_STRUCT FT1_info_struct PACKED; /* the S508/FT1 information structure */
+} SHARED_MEMORY_INFO_STRUCT;
+
+/* ----------------------------------------------------------------------------
+ * UDP Management constants and structures
+ * --------------------------------------------------------------------------*/
+
+/* The embedded control block for UDP mgmt
+ This is essentially a mailbox structure, without the large data field */
+
+typedef struct {
+ unsigned char opp_flag PACKED; /* the opp flag */
+ unsigned char command PACKED; /* the user command */
+ unsigned short buffer_length PACKED; /* the data length */
+ unsigned char return_code PACKED; /* the return code */
+ unsigned char MB_reserved[NUMBER_MB_RESERVED_BYTES] PACKED; /* reserved for later */
+} cblock_t;
+
+
+/* UDP management packet layout (data area of ip packet) */
+/*
+typedef struct {
+ unsigned char signature[8] PACKED;
+ unsigned char request_reply PACKED;
+ unsigned char id PACKED;
+ unsigned char reserved[6] PACKED;
+ cblock_t cblock PACKED;
+ unsigned char num_frames PACKED;
+ unsigned char ismoredata PACKED;
+ unsigned char data[SIZEOF_MB_DATA_BFR] PACKED;
+} udp_management_packet_t;
+
+*/
+
+typedef struct {
+ unsigned char num_frames PACKED;
+ unsigned char ismoredata PACKED;
+} trace_info_t;
+
+typedef struct {
+ ip_pkt_t ip_pkt PACKED;
+ udp_pkt_t udp_pkt PACKED;
+ wp_mgmt_t wp_mgmt PACKED;
+ cblock_t cblock PACKED;
+ trace_info_t trace_info PACKED;
+ unsigned char data[SIZEOF_MB_DATA_BFR] PACKED;
+} chdlc_udp_pkt_t;
+
+typedef struct ft1_exec_cmd{
+ unsigned char command PACKED; /* the user command */
+ unsigned short buffer_length PACKED; /* the data length */
+ unsigned char return_code PACKED; /* the return code */
+ unsigned char MB_reserved[NUMBER_MB_RESERVED_BYTES] PACKED;
+} ft1_exec_cmd_t;
+
+typedef struct {
+ unsigned char opp_flag PACKED;
+ ft1_exec_cmd_t cmd PACKED;
+ unsigned char data[SIZEOF_MB_DATA_BFR] PACKED;
+} ft1_exec_t;
+
+#define UDPMGMT_SIGNATURE "CTPIPEAB"
+
+
+/* UDP/IP packet (for UDP management) layout */
+/*
+typedef struct {
+ unsigned char reserved[2] PACKED;
+ unsigned short ip_length PACKED;
+ unsigned char reserved2[4] PACKED;
+ unsigned char ip_ttl PACKED;
+ unsigned char ip_protocol PACKED;
+ unsigned short ip_checksum PACKED;
+ unsigned long ip_src_address PACKED;
+ unsigned long ip_dst_address PACKED;
+ unsigned short udp_src_port PACKED;
+ unsigned short udp_dst_port PACKED;
+ unsigned short udp_length PACKED;
+ unsigned short udp_checksum PACKED;
+ udp_management_packet_t um_packet PACKED;
+} ip_packet_t;
+*/
+
+/* valid ip_protocol for UDP management */
+#define UDPMGMT_UDP_PROTOCOL 0x11
+
+
+typedef struct {
+ unsigned char status PACKED;
+ unsigned char data_avail PACKED;
+ unsigned short real_length PACKED;
+ unsigned short time_stamp PACKED;
+ unsigned char data[1] PACKED;
+} trace_pkt_t;
+
+typedef struct {
+ unsigned char error_flag PACKED;
+ unsigned short time_stamp PACKED;
+ unsigned char reserved[13] PACKED;
+} api_rx_hdr_t;
+
+typedef struct {
+ api_rx_hdr_t api_rx_hdr PACKED;
+ void * data PACKED;
+} api_rx_element_t;
+
+typedef struct {
+ unsigned char attr PACKED;
+ unsigned char reserved[15] PACKED;
+} api_tx_hdr_t;
+
+typedef struct {
+ api_tx_hdr_t api_tx_hdr PACKED;
+ void * data PACKED;
+} api_tx_element_t;
+
+/* ----------------------------------------------------------------------------
+ * Constants for the SET_FT1_CONFIGURATION/READ_FT1_CONFIGURATION command
+ * --------------------------------------------------------------------------*/
+
+/* the FT1 configuration structure */
+typedef struct {
+ unsigned short framing_mode;
+ unsigned short encoding_mode;
+ unsigned short line_build_out;
+ unsigned short channel_base;
+ unsigned short baud_rate_kbps; /* the baud rate (in kbps) */
+ unsigned short clock_mode;
+} ft1_config_t;
+
+/* settings for the 'framing_mode' */
+#define ESF_FRAMING 0x00 /* ESF framing */
+#define D4_FRAMING 0x01 /* D4 framing */
+
+/* settings for the 'encoding_mode' */
+#define B8ZS_ENCODING 0x00 /* B8ZS encoding */
+#define AMI_ENCODING 0x01 /* AMI encoding */
+
+/* settings for the 'line_build_out' */
+#define LN_BLD_CSU_0dB_DSX1_0_to_133 0x00 /* set build out to CSU (0db) or DSX-1 (0-133ft) */
+#define LN_BLD_DSX1_133_to_266 0x01 /* set build out DSX-1 (133-266ft) */
+#define LN_BLD_DSX1_266_to_399 0x02 /* set build out DSX-1 (266-399ft) */
+#define LN_BLD_DSX1_399_to_533 0x03 /* set build out DSX-1 (399-533ft) */
+#define LN_BLD_DSX1_533_to_655 0x04 /* set build out DSX-1 (533-655ft) */
+#define LN_BLD_CSU_NEG_7dB 0x05 /* set build out to CSU (-7.5db) */
+#define LN_BLD_CSU_NEG_15dB 0x06 /* set build out to CSU (-15db) */
+#define LN_BLD_CSU_NEG_22dB 0x07 /* set build out to CSU (-22.5db) */
+
+/* settings for the 'channel_base' */
+#define MIN_CHANNEL_BASE_VALUE 1 /* the minimum permitted channel base value */
+#define MAX_CHANNEL_BASE_VALUE 24 /* the maximum permitted channel base value */
+
+/* settings for the 'baud_rate_kbps' */
+#define MIN_BAUD_RATE_KBPS 0 /* the minimum permitted baud rate (kbps) */
+#define MAX_BAUD_RATE_KBPS 1536 /* the maximum permitted baud rate (kbps) */
+#define BAUD_RATE_FT1_AUTO_CONFIG 0xFFFF /* the baud rate used to trigger an automatic FT1 configuration */
+
+/* settings for the 'clock_mode' */
+#define CLOCK_MODE_NORMAL 0x00 /* clock mode set to normal (slave) */
+#define CLOCK_MODE_MASTER 0x01 /* clock mode set to master */
+
+
+#define BAUD_RATE_FT1_AUTO_CONFIG 0xFFFF
+#define AUTO_FT1_CONFIG_NOT_COMPLETE 0x08
+#define AUTO_FT1_CFG_FAIL_OP_MODE 0x0C
+#define AUTO_FT1_CFG_FAIL_INVALID_LINE 0x0D
+
+
+#ifdef _MSC_
+# pragma pack()
+#endif
+#endif /* _SDLA_CHDLC_H */
diff --git a/include/linux/sdla_fr.h b/include/linux/sdla_fr.h
index 533f2acb0..f5aef96a5 100644
--- a/include/linux/sdla_fr.h
+++ b/include/linux/sdla_fr.h
@@ -1,16 +1,18 @@
/*****************************************************************************
* sdla_fr.h Sangoma frame relay firmware API definitions.
*
-* Author: Jaspreet Singh <jaspreet@sangoma.com>
-* Gene Kozin <74604.152@compuserve.com>
+* Author: Gideon Hack
+* Nenad Corbic <ncorbic@sangoma.com>
*
-* Copyright: (c) 1995-1996 Sangoma Technologies Inc.
+* Copyright: (c) 1995-1999 Sangoma Technologies 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.
* ============================================================================
+* Oct 04, 1999 Gideon Hack Updated API structures
+* Jun 02, 1999 Gideon Hack Modifications for S514 support
* Oct 12, 1997 Jaspreet Singh Added FR_READ_DLCI_IB_MAPPING
* Jul 21, 1997 Jaspreet Singh Changed FRRES_TOO_LONG and FRRES_TOO_MANY to
* 0x05 and 0x06 respectively.
@@ -24,26 +26,16 @@
/*----------------------------------------------------------------------------
* Notes:
* ------
- * 1. All structures defined in this file are byte-alined. To ensure
- * portability of this code between different platforms and compilers, one
- * of the following defines must be defined before including this file:
+ * 1. All structures defined in this file are byte-alined.
*
- * Compiler Platform Define Use option
- * -------- -------- ------ ----------
- * GNU C Linux _GNUC_ -
- * Microsoft C DOS/Windows _MSC_ -
+ * Compiler Platform
+ * -------- --------
+ * GNU C Linux
*/
-#ifdef _GNUC_
-# ifndef PACKED
+#ifndef PACKED
# define PACKED __attribute__((packed))
-# endif /* PACKED */
-#else
-# define PACKED
-#endif
-#ifdef _MSC_
-# pragma pack(1)
-#endif
+#endif /* PACKED */
/* Adapter memory layout */
#define FR_MB_VECTOR 0xE000 /* mailbox window vector */
@@ -59,6 +51,11 @@
/* Important constants */
#define FR502_MAX_DATA 4096 /* maximum data buffer length */
#define FR508_MAX_DATA 4080 /* maximum data buffer length */
+#define MIN_LGTH_FR_DATA_CFG 300 /* min Information frame length
+(for configuration purposes) */
+#define FR_MAX_NO_DATA_BYTES_IN_FRAME 15354 /* max Information frame length */
+
+#define HIGHEST_VALID_DLCI 991
/****** Data Structures *****************************************************/
@@ -90,6 +87,7 @@ typedef struct fr_cmd
#define FR_FLUSH_STATISTICS 0x16
#define FR_LIST_ACTIVE_DLCI 0x17
#define FR_FLUSH_DATA_BUFFERS 0x18
+#define FR_READ_ADD_DLC_STATS 0x19
#define FR_ADD_DLCI 0x20
#define FR_DELETE_DLCI 0x21
#define FR_ACTIVATE_DLCI 0x22
@@ -102,6 +100,20 @@ typedef struct fr_cmd
#define FR_READ_CODE_VERSION 0x40
#define FR_SET_INTR_MODE 0x50
#define FR_READ_INTR_MODE 0x51
+#define FR_SET_TRACE_CONFIG 0x60
+#define FR_FT1_STATUS_CTRL 0x80
+#define FR_SET_FT1_MODE 0x81
+
+/* Special UDP drivers management commands */
+#define FPIPE_ENABLE_TRACING 0x41
+#define FPIPE_DISABLE_TRACING 0x42
+#define FPIPE_GET_TRACE_INFO 0x43
+#define FPIPE_FT1_READ_STATUS 0x44
+#define FPIPE_DRIVER_STAT_IFSEND 0x45
+#define FPIPE_DRIVER_STAT_INTR 0x46
+#define FPIPE_DRIVER_STAT_GEN 0x47
+#define FPIPE_FLUSH_DRIVER_STATS 0x48
+#define FPIPE_ROUTER_UP_TIME 0x49
/* 'result' field defines */
#define FRRES_OK 0x00 /* command executed successfully */
@@ -169,7 +181,7 @@ typedef struct fr508_flags
} fr508_flags_t;
/* 'event' field defines */
-#define FR_EVENT_STATUS 0x01 /* channel status change ??? */
+#define FR_EVENT_STATUS 0x01 /* channel status change */
#define FR_EVENT_DLC_STATUS 0x02 /* DLC status change */
#define FR_EVENT_BAD_DLCI 0x04 /* FSR included wrong DLCI */
#define FR_EVENT_LINK_DOWN 0x40 /* DCD or CTS low */
@@ -185,6 +197,8 @@ typedef struct fr508_flags
#define FR_INTR_READY 0x08 /* interface command completed */
#define FR_INTR_DLC 0x10 /* DLC status change */
#define FR_INTR_TIMER 0x20 /* millisecond timer */
+#define FR_INTR_TX_MULT_DLCIs 0x80 /* Tx interrupt on multiple DLCIs */
+
/*----------------------------------------------------------------------------
* Receive Buffer Configuration Info. S508 only!
@@ -206,7 +220,7 @@ typedef struct fr_buf_info
* 'rse_base' field of the frBufInfo_t structure into absolute adapter
* memory address space.
*/
-typedef struct fr_buf_ctl
+typedef struct fr_rx_buf_ctl
{
unsigned char flag PACKED; /* 00h: ready flag */
unsigned short length PACKED; /* 01h: frame length */
@@ -215,7 +229,18 @@ typedef struct fr_buf_ctl
unsigned short tmstamp PACKED; /* 06h: time stamp */
unsigned short rsrv[2] PACKED; /* 08h: */
unsigned long offset PACKED; /* 0Ch: buffer absolute address */
-} fr_buf_ctl_t;
+} fr_rx_buf_ctl_t;
+
+typedef struct fr_tx_buf_ctl
+{
+ unsigned char flag PACKED; /* 00h: ready flag */
+ unsigned short rsrv0[2] PACKED; /* 01h: */
+ unsigned short length PACKED; /* 05h: frame length */
+ unsigned short dlci PACKED; /* 07h: DLCI */
+ unsigned char attr PACKED; /* 09h: FECN/BECN/DE/CR */
+ unsigned short rsrv1 PACKED; /* 0Ah: */
+ unsigned long offset PACKED; /* 0Ch: buffer absolute address */
+} fr_tx_buf_ctl_t;
/*----------------------------------------------------------------------------
* Global Configuration Block. Passed to FR_SET_CONFIG command when dlci == 0.
@@ -271,6 +296,52 @@ typedef struct fr_conf
#define FRCFG_MODE_V35 0x0000 /* S508 only */
#define FRCFG_MODE_RS232 0x0002 /* S508 only */
+/* defines for line tracing */
+
+/* the line trace status element presented by the frame relay code */
+typedef struct {
+ unsigned char flag PACKED; /* ready flag */
+ unsigned short length PACKED; /* trace length */
+ unsigned char rsrv0[2] PACKED; /* reserved */
+ unsigned char attr PACKED; /* trace attributes */
+ unsigned short tmstamp PACKED; /* time stamp */
+ unsigned char rsrv1[4] PACKED; /* reserved */
+ unsigned long offset PACKED; /* buffer absolute address */
+} fr_trc_el_t;
+
+typedef struct {
+ unsigned char status PACKED; /* status flag */
+ unsigned char data_passed PACKED; /* 0 if no data passed, 1 if */
+ /* data passed */
+ unsigned short length PACKED; /* frame length */
+ unsigned short tmstamp PACKED; /* time stamp */
+} fpipemon_trc_hdr_t;
+
+typedef struct {
+ fpipemon_trc_hdr_t fpipemon_trc_hdr PACKED;
+ unsigned char data[FR_MAX_NO_DATA_BYTES_IN_FRAME] PACKED;
+} fpipemon_trc_t;
+
+/* bit settings for the 'status' byte - note that bits 1, 2 and 3 are used */
+/* for returning the number of frames being passed to fpipemon */
+#define TRC_OUTGOING_FRM 0x01
+#define TRC_ABORT_ERROR 0x10
+#define TRC_CRC_ERROR 0x20
+#define TRC_OVERRUN_ERROR 0x40
+#define MORE_TRC_DATA 0x80
+
+#define MAX_FRMS_TRACED 0x07
+
+#define NO_TRC_ELEMENTS_OFF 0x9000
+#define BASE_TRC_ELEMENTS_OFF 0x9002
+#define TRC_ACTIVE 0x01
+#define FLUSH_TRC_BUFFERS 0x02
+#define FLUSH_TRC_STATISTICS 0x04
+#define TRC_SIGNALLING_FRMS 0x10
+#define TRC_INFO_FRMS 0x20
+#define ACTIVATE_TRC (TRC_ACTIVE | TRC_SIGNALLING_FRMS | TRC_INFO_FRMS)
+#define RESET_TRC (FLUSH_TRC_BUFFERS | FLUSH_TRC_STATISTICS)
+
/*----------------------------------------------------------------------------
* Channel configuration.
* This structure is passed to the FR_SET_CONFIG command when dlci != 0.
@@ -415,6 +486,151 @@ typedef struct fr_comm_stat
#define FR_ISF_LVE 2 /* issue Link Verification Enquiry */
#define FR_ISF_FSE 3 /* issue Full Status Enquiry */
+/*----------------------------------------------------------------------------
+ * Frame Relay ARP Header -- Used for Dynamic route creation with InvARP
+ */
+
+typedef struct arphdr_fr
+ {
+ unsigned short ar_hrd PACKED; /* format of hardware addr */
+ unsigned short ar_pro PACKED; /* format of protocol addr */
+ unsigned char ar_hln PACKED; /* length of hardware addr */
+ unsigned char ar_pln PACKED; /* length of protocol addr */
+ unsigned short ar_op PACKED; /* ARP opcode */
+ unsigned short ar_sha PACKED; /* Sender DLCI addr 2 bytes */
+ unsigned long ar_sip PACKED; /* Sender IP addr 4 bytes */
+ unsigned short ar_tha PACKED; /* Target DLCI addr 2 bytes */
+ unsigned long ar_tip PACKED; /* Target IP addr 4 bytes */
+ } arphdr_fr_t;
+
+/*----------------------------------------------------------------------------
+ * Frame Relay RFC 1490 SNAP Header -- Used to check for ARP packets
+ */
+typedef struct arphdr_1490
+ {
+ unsigned char control PACKED; /* UI, etc... */
+ unsigned char pad PACKED; /* Pad */
+ unsigned char NLPID PACKED; /* SNAP */
+ unsigned char OUI[3] PACKED; /* Ethertype, etc... */
+ unsigned short PID PACKED; /* ARP, IP, etc... */
+ } arphdr_1490_t;
+
+/* UDP/IP packet (for UDP management) layout */
+
+/* The embedded control block for UDP mgmt
+ This is essentially a mailbox structure, without the large data field */
+
+typedef struct {
+ unsigned char opp_flag PACKED; /* the opp flag */
+ unsigned char command PACKED; /* command code */
+ unsigned short length PACKED; /* length of data buffer */
+ unsigned char result PACKED; /* return code */
+ unsigned short dlci PACKED; /* DLCI number */
+ unsigned char attr PACKED; /* FECN, BECN, DE and C/R bits */
+ unsigned short rxlost1 PACKED; /* frames discarded at int. level */
+ unsigned long rxlost2 PACKED; /* frames discarded at app. level */
+ unsigned char rsrv[2] PACKED; /* reserved for future use */
+} cblock_t;
+
+
+/* UDP management packet layout (data area of ip packet) */
+
+typedef struct {
+ unsigned char control PACKED;
+ unsigned char NLPID PACKED;
+} fr_encap_hdr_t;
+
+typedef struct {
+ fr_encap_hdr_t fr_encap_hdr PACKED;
+ ip_pkt_t ip_pkt PACKED;
+ udp_pkt_t udp_pkt PACKED;
+ wp_mgmt_t wp_mgmt PACKED;
+ cblock_t cblock PACKED;
+ unsigned char data[4080] PACKED;
+} fr_udp_pkt_t;
+
+
+/* valid ip_protocol for UDP management */
+#define UDPMGMT_UDP_PROTOCOL 0x11
+
+#define UDPMGMT_FPIPE_SIGNATURE "FPIPE8ND"
+#define UDPMGMT_DRVRSTATS_SIGNATURE "DRVSTATS"
+
+/* values for request/reply byte */
+#define UDPMGMT_REQUEST 0x01
+#define UDPMGMT_REPLY 0x02
+#define UDP_OFFSET 12
+
+typedef struct {
+ unsigned long if_send_entry;
+ unsigned long if_send_skb_null;
+ unsigned long if_send_broadcast;
+ unsigned long if_send_multicast;
+ unsigned long if_send_critical_ISR;
+ unsigned long if_send_critical_non_ISR;
+ unsigned long if_send_busy;
+ unsigned long if_send_busy_timeout;
+ unsigned long if_send_DRVSTATS_request;
+ unsigned long if_send_FPIPE_request;
+ unsigned long if_send_wan_disconnected;
+ unsigned long if_send_dlci_disconnected;
+ unsigned long if_send_no_bfrs;
+ unsigned long if_send_adptr_bfrs_full;
+ unsigned long if_send_bfrs_passed_to_adptr;
+ unsigned long if_send_consec_send_fail;
+} drvstats_if_send_t;
+
+typedef struct {
+ unsigned long rx_intr_no_socket;
+ unsigned long rx_intr_dev_not_started;
+ unsigned long rx_intr_DRVSTATS_request;
+ unsigned long rx_intr_FPIPE_request;
+ unsigned long rx_intr_bfr_not_passed_to_stack;
+ unsigned long rx_intr_bfr_passed_to_stack;
+ } drvstats_rx_intr_t;
+
+typedef struct {
+ unsigned long UDP_FPIPE_mgmt_kmalloc_err;
+ unsigned long UDP_FPIPE_mgmt_direction_err;
+ unsigned long UDP_FPIPE_mgmt_adptr_type_err;
+ unsigned long UDP_FPIPE_mgmt_adptr_cmnd_OK;
+ unsigned long UDP_FPIPE_mgmt_adptr_cmnd_timeout;
+ unsigned long UDP_FPIPE_mgmt_adptr_send_passed;
+ unsigned long UDP_FPIPE_mgmt_adptr_send_failed;
+ unsigned long UDP_FPIPE_mgmt_not_passed_to_stack;
+ unsigned long UDP_FPIPE_mgmt_passed_to_stack;
+ unsigned long UDP_FPIPE_mgmt_no_socket;
+ unsigned long UDP_DRVSTATS_mgmt_kmalloc_err;
+ unsigned long UDP_DRVSTATS_mgmt_adptr_cmnd_OK;
+ unsigned long UDP_DRVSTATS_mgmt_adptr_cmnd_timeout;
+ unsigned long UDP_DRVSTATS_mgmt_adptr_send_passed;
+ unsigned long UDP_DRVSTATS_mgmt_adptr_send_failed;
+ unsigned long UDP_DRVSTATS_mgmt_not_passed_to_stack;
+ unsigned long UDP_DRVSTATS_mgmt_passed_to_stack;
+ unsigned long UDP_DRVSTATS_mgmt_no_socket;
+} drvstats_gen_t;
+
+typedef struct {
+ unsigned char attr PACKED;
+ unsigned short time_stamp PACKED;
+ unsigned char reserved[13] PACKED;
+} api_rx_hdr_t;
+
+typedef struct {
+ api_rx_hdr_t api_rx_hdr PACKED;
+ void * data PACKED;
+} api_rx_element_t;
+
+typedef struct {
+ unsigned char attr PACKED;
+ unsigned char reserved[15] PACKED;
+} api_tx_hdr_t;
+
+typedef struct {
+ api_tx_hdr_t api_tx_hdr PACKED;
+ void * data PACKED;
+} api_tx_element_t;
+
#ifdef _MSC_
# pragma pack()
#endif
diff --git a/include/linux/sdla_ppp.h b/include/linux/sdla_ppp.h
index 267986833..95d5c0fe0 100644
--- a/include/linux/sdla_ppp.h
+++ b/include/linux/sdla_ppp.h
@@ -19,38 +19,25 @@
/*----------------------------------------------------------------------------
* Notes:
* ------
- * 1. All structures defined in this file are byte-alined. To ensure
- * portability of this code between different platforms and compilers, one
- * of the following defines must be defined before including this file:
+ * 1. All structures defined in this file are byte-alined.
*
- * Compiler Platform Define Use option
- * -------- -------- ------ ----------
- * GNU C Linux _GNUC_ -
- * Microsoft C DOS/Windows _MSC_ -
+ * Compiler Platform
+ * -------- --------
+ * GNU C Linux
*/
-#ifdef _GNUC_
-# ifndef PACKED
+#ifndef PACKED
# define PACKED __attribute__((packed))
-# endif /* PACKED */
-#else
-# define PACKED
-#endif
-#ifdef _MSC_
-# pragma pack(1)
-#endif
+#endif /* PACKED */
/* Adapter memory layout and important constants */
-
-#define PPP502_MB_VECT 0xA000 /* mailbox window vector */
-#define PPP502_MB_OFFS 0x1C00 /* mailbox offset */
-#define PPP502_FLG_OFFS 0 /* status flags offset */
-#define PPP502_BUF_OFFS 0x0010 /* buffer info block offset */
-
#define PPP508_MB_VECT 0xE000 /* mailbox window vector */
-#define PPP508_MB_OFFS 0 /* mailbox offset */
+#define PPP508_MB_OFFS 0 /* mailbox offset */
#define PPP508_FLG_OFFS 0x1000 /* status flags offset */
#define PPP508_BUF_OFFS 0x1100 /* buffer info block offset */
+#define PPP514_MB_OFFS 0xE000 /* mailbox offset */
+#define PPP514_FLG_OFFS 0xF000 /* status flags offset */
+#define PPP514_BUF_OFFS 0xF100 /* buffer info block offset */
#define PPP_MAX_DATA 1008 /* command block data buffer length */
@@ -59,14 +46,46 @@
/*----------------------------------------------------------------------------
* PPP Command Block.
*/
-typedef struct ppp_cmd
-{
+typedef struct ppp_cmd{
unsigned char command PACKED; /* command code */
unsigned short length PACKED; /* length of data buffer */
unsigned char result PACKED; /* return code */
unsigned char rsrv[11] PACKED; /* reserved for future use */
} ppp_cmd_t;
+typedef struct cblock{
+ unsigned char opp_flag PACKED;
+ unsigned char command PACKED; /* command code */
+ unsigned short length PACKED; /* length of data buffer */
+ unsigned char result PACKED; /* return code */
+ unsigned char rsrv[11] PACKED; /* reserved for future use */
+} cblock_t;
+
+typedef struct ppp_udp_pkt{
+ ip_pkt_t ip_pkt PACKED;
+ udp_pkt_t udp_pkt PACKED;
+ wp_mgmt_t wp_mgmt PACKED;
+ cblock_t cblock PACKED;
+ unsigned char data[MAX_LGTH_UDP_MGNT_PKT] PACKED;
+} ppp_udp_pkt_t;
+
+typedef struct {
+ unsigned char status PACKED;
+ unsigned char data_avail PACKED;
+ unsigned short real_length PACKED;
+ unsigned short time_stamp PACKED;
+ unsigned char data[1] PACKED;
+} trace_pkt_t;
+
+
+typedef struct {
+ unsigned char opp_flag PACKED;
+ unsigned char trace_type PACKED;
+ unsigned short trace_length PACKED;
+ unsigned short trace_data_ptr PACKED;
+ unsigned short trace_time_stamp PACKED;
+} trace_element_t;
+
/* 'command' field defines */
#define PPP_READ_CODE_VERSION 0x10 /* configuration commands */
#define PPP_SET_CONFIG 0x05
@@ -145,26 +164,46 @@ typedef struct ppp_flags
#define PPP_INTR_DISC 0x10 /* data link disconnected */
#define PPP_INTR_OPEN 0x20 /* data link open */
#define PPP_INTR_DROP_DTR 0x40 /* DTR drop timeout expired */
+#define PPP_INTR_TIMER 0x80 /* timer interrupt */
+
/* 'mstatus' defines */
#define PPP_MDM_DCD 0x08 /* mdm_status: DCD */
#define PPP_MDM_CTS 0x20 /* mdm_status: CTS */
-/*----------------------------------------------------------------------------
- * PPP Buffer Info.
- * This structure is located at offset PPP502_BUF_OFFS into
- * PPP502_MB_VECT.
- */
-typedef struct ppp502_buf_info
-{
- unsigned short txb_num PACKED; /* 00: number of transmit buffers */
- unsigned short txb_offs PACKED; /* 02: offset of the buffer ctl. */
- unsigned char rsrv1[4] PACKED;
- unsigned short rxb_num PACKED; /* 08: number of receive buffers */
- unsigned short rxb_offs PACKED; /* 0A: offset of the buffer ctl. */
- unsigned char rsrv2[2] PACKED;
- unsigned short rxb_next PACKED; /* 0E: index of the next buffer */
-} ppp502_buf_info_t;
+/* 'disc_cause' defines */
+#define PPP_LOCAL_TERMINATION 0x0001 /* Local Request by PPP termination phase */
+#define PPP_DCD_CTS_DROP 0x0002 /* DCD and/or CTS dropped. Link down */
+#define PPP_REMOTE_TERMINATION 0x0800 /* Remote Request by PPP termination phase */
+
+/* 'misc_config_bits' defines */
+#define DONT_RE_TX_ABORTED_I_FRAMES 0x01
+#define TX_FRM_BYTE_COUNT_STATS 0x02
+#define RX_FRM_BYTE_COUNT_STATS 0x04
+#define TIME_STAMP_IN_RX_FRAMES 0x08
+#define NON_STD_ADPTR_FREQ 0x10
+#define INTERFACE_LEVEL_RS232 0x20
+#define AUTO_LINK_RECOVERY 0x100
+#define DONT_TERMINATE_LNK_MAX_CONFIG 0x200
+
+/* 'authentication options' defines */
+#define NO_AUTHENTICATION 0x00
+#define INBOUND_AUTH 0x80
+#define PAP_AUTH 0x01
+#define CHAP_AUTH 0x02
+
+/* 'ip options' defines */
+#define L_AND_R_IP_NO_ASSIG 0x00
+#define L_IP_LOCAL_ASSIG 0x01
+#define L_IP_REMOTE_ASSIG 0x02
+#define R_IP_LOCAL_ASSIG 0x04
+#define R_IP_REMOTE_ASSIG 0x08
+#define ENABLE_IP 0x80
+
+/* 'ipx options' defines */
+#define ROUTING_PROT_DEFAULT 0x20
+#define ENABLE_IPX 0x80
+#define DISABLE_IPX 0x00
/*----------------------------------------------------------------------------
* PPP Buffer Info.
@@ -203,37 +242,6 @@ typedef struct ppp_buf_ctl
} ppp_buf_ctl_t;
/*----------------------------------------------------------------------------
- * S502 Adapter Configuration Block (passed to the PPP_SET_CONFIG command).
- */
-typedef struct ppp502_conf
-{
- unsigned char line_speed PACKED; /* 00: 0 - external clk. */
- unsigned short txbuf_num PACKED; /* 01: number of Tx buffers */
- unsigned short conf_flags PACKED; /* 03: configuration bits */
- unsigned short mtu_local PACKED; /* 05: local MTU */
- unsigned short mtu_remote PACKED; /* 07: remote MTU */
- unsigned short restart_tmr PACKED; /* 09: restart timer */
- unsigned short auth_rsrt_tmr PACKED; /* 0B: authentication timer */
- unsigned short auth_wait_tmr PACKED; /* 0D: authentication timer */
- unsigned short mdm_fail_tmr PACKED; /* 0F: modem failure timer */
- unsigned short dtr_drop_tmr PACKED; /* 11: DTR drop timer */
- unsigned short connect_tmout PACKED; /* 13: connection timeout */
- unsigned short conf_retry PACKED; /* 15: max. retry */
- unsigned short term_retry PACKED; /* 17: max. retry */
- unsigned short fail_retry PACKED; /* 19: max. retry */
- unsigned short auth_retry PACKED; /* 1B: max. retry */
- unsigned char auth_options PACKED; /* 1D: authentication opt. */
- unsigned char ip_options PACKED; /* 1E: IP options */
- unsigned char ip_local[4] PACKED; /* 1F: local IP address */
- unsigned char ip_remote[4] PACKED; /* 23: remote IP address */
- unsigned char ipx_options PACKED; /* 27: IPX options */
- unsigned char ipx_netno[4] PACKED; /* 28: IPX net number */
- unsigned char ipx_local[6] PACKED; /* 2C: local IPX node number*/
- unsigned char ipx_remote[6] PACKED; /* 32: remote IPX node num.*/
- unsigned char ipx_router[48] PACKED; /* 38: IPX router name*/
-} ppp502_conf_t;
-
-/*----------------------------------------------------------------------------
* S508 Adapter Configuration Block (passed to the PPP_SET_CONFIG command).
*/
typedef struct ppp508_conf
@@ -255,8 +263,8 @@ typedef struct ppp508_conf
unsigned short auth_retry PACKED; /* 1E: max. retry */
unsigned char auth_options PACKED; /* 20: authentication opt. */
unsigned char ip_options PACKED; /* 21: IP options */
- unsigned char ip_local[4] PACKED; /* 22: local IP address */
- unsigned char ip_remote[4] PACKED; /* 26: remote IP address */
+ unsigned long ip_local PACKED; /* 22: local IP address */
+ unsigned long ip_remote PACKED; /* 26: remote IP address */
unsigned char ipx_options PACKED; /* 2A: IPX options */
unsigned char ipx_netno[4] PACKED; /* 2B: IPX net number */
unsigned char ipx_local[6] PACKED; /* 2F: local IPX node number*/
@@ -265,6 +273,25 @@ typedef struct ppp508_conf
unsigned long alt_cpu_clock PACKED; /* 6B: */
} ppp508_conf_t;
+/*----------------------------------------------------------------------------
+ * S508 Adapter Read Connection Information Block
+ * Returned by the PPP_GET_CONNECTION_INFO command
+ */
+typedef struct ppp508_connect_info
+{
+ unsigned short mru PACKED; /* 00-01 Remote Max Rec' Unit */
+ unsigned char ip_options PACKED; /* 02: Negotiated ip options */
+ unsigned long ip_local PACKED; /* 03-06: local IP address */
+ unsigned long ip_remote PACKED; /* 07-0A: remote IP address */
+ unsigned char ipx_options PACKED; /* 0B: Negotiated ipx options */
+ unsigned char ipx_netno[4] PACKED; /* 0C-0F: IPX net number */
+ unsigned char ipx_local[6] PACKED; /* 10-1F: local IPX node # */
+ unsigned char ipx_remote[6] PACKED; /* 16-1B: remote IPX node # */
+ unsigned char ipx_router[48] PACKED; /* 1C-4B: IPX router name */
+ unsigned char auth_status PACKED; /* 4C: Authentication Status */
+ unsigned char inbd_auth_peerID[1] PACKED; /* 4D: variable length inbound authenticated peer ID */
+} ppp508_connect_info_t;
+
/* 'line_speed' field */
#define PPP_BITRATE_1200 0x01
#define PPP_BITRATE_2400 0x02
@@ -303,16 +330,6 @@ typedef struct ppp508_conf
#define PPP_IPX_ENABLE 0x80
/*----------------------------------------------------------------------------
- * S502 Adapter Configuration Block (returned by the PPP_READ_CONFIG command).
- */
-typedef struct ppp502_get_conf
-{
- ppp502_conf_t conf PACKED; /* 00: requested config. */
- unsigned short txb_num PACKED; /* 68: number of Tx buffers */
- unsigned short rxb_num PACKED; /* 6A: number of Rx buffers */
-} ppp502_get_conf_t;
-
-/*----------------------------------------------------------------------------
* S508 Adapter Configuration Block (returned by the PPP_READ_CONFIG command).
*/
typedef struct ppp508_get_conf
@@ -324,20 +341,6 @@ typedef struct ppp508_get_conf
} ppp508_get_conf_t;
/*----------------------------------------------------------------------------
- * S502 Operational Statistics (returned by the PPP_READ_STATISTIC command).
- */
-typedef struct ppp502_Stats
-{
- unsigned short rx_lost_intr PACKED; /* 00: */
- unsigned short rx_lost_buff PACKED; /* 02: */
- unsigned short tx_abort PACKED; /* 04: */
- unsigned long tx_frames PACKED; /* 06: */
- unsigned long tx_bytes PACKED; /* 0A: */
- unsigned long rx_frames PACKED; /* 0E: */
- unsigned long rx_bytes PACKED; /* 12: */
-} ppp502_Stats_t;
-
-/*----------------------------------------------------------------------------
* S508 Operational Statistics (returned by the PPP_READ_STATISTIC command).
*/
typedef struct ppp508_stats
@@ -530,6 +533,40 @@ typedef struct ppp_conn_info
unsigned char peer_id[0] PACKED; /* 4D: */
} ppp_conn_info_t;
+/* Data structure for SET_TRIGGER_INTR command
+ */
+
+typedef struct ppp_intr_info{
+ unsigned char i_enable PACKED; /* 0 Interrupt enable bits */
+ unsigned char irq PACKED; /* 1 Irq number */
+ unsigned short timer_len PACKED; /* 2 Timer delay */
+} ppp_intr_info_t;
+
+
+#define FT1_MONITOR_STATUS_CTRL 0x80
+#define SET_FT1_MODE 0x81
+
+
+
+/* Special UDP drivers management commands */
+#define PPIPE_ENABLE_TRACING 0x20
+#define PPIPE_DISABLE_TRACING 0x21
+#define PPIPE_GET_TRACE_INFO 0x22
+#define PPIPE_GET_IBA_DATA 0x23
+#define PPIPE_KILL_BOARD 0x24
+#define PPIPE_FT1_READ_STATUS 0x25
+#define PPIPE_DRIVER_STAT_IFSEND 0x26
+#define PPIPE_DRIVER_STAT_INTR 0x27
+#define PPIPE_DRIVER_STAT_GEN 0x28
+#define PPIPE_FLUSH_DRIVER_STATS 0x29
+#define PPIPE_ROUTER_UP_TIME 0x30
+
+#define DISABLE_TRACING 0x00
+#define TRACE_SIGNALLING_FRAMES 0x01
+#define TRACE_DATA_FRAMES 0x02
+
+
+
#ifdef _MSC_
# pragma pack()
#endif
diff --git a/include/linux/sdladrv.h b/include/linux/sdladrv.h
index 23ae8a1e2..724fd6c75 100644
--- a/include/linux/sdladrv.h
+++ b/include/linux/sdladrv.h
@@ -1,15 +1,16 @@
/*****************************************************************************
* sdladrv.h SDLA Support Module. Kernel API Definitions.
*
-* Author: Gene Kozin <genek@compuserve.com>
+* Author: Gideon Hack
*
-* Copyright: (c) 1995-1996 Sangoma Technologies Inc.
+* Copyright: (c) 1995-1999 Sangoma Technologies 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.
* ============================================================================
+* Jun 02, 1999 Gideon Hack Added support for the S514 PCI adapter.
* Dec 11, 1996 Gene Kozin Complete overhaul.
* Oct 17, 1996 Gene Kozin Minor bug fixes.
* Jun 12, 1996 Gene Kozin Added support for S503 card.
@@ -18,6 +19,11 @@
#ifndef _SDLADRV_H
#define _SDLADRV_H
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= 0x020100
+#define LINUX_2_1
+#endif
+
#define SDLA_MAXIORANGE 4 /* maximum I/O port range */
#define SDLA_WINDOWSIZE 0x2000 /* default dual-port memory window size */
@@ -33,6 +39,14 @@ typedef struct sdlahw
unsigned fwid; /* firmware ID */
unsigned port; /* adapter I/O port base */
int irq; /* interrupt request level */
+ char S514_cpu_no[1]; /* PCI CPU Number */
+ unsigned char S514_slot_no; /* PCI Slot Number */
+#ifdef LINUX_2_1
+ struct pci_dev *pci_dev; /* PCI device */
+#else
+ unsigned char pci_bus; /* PCI bus number */
+ unsigned char pci_dev_func; /* PCI device/function number */
+#endif
void * dpmbase; /* dual-port memory base */
unsigned dpmsize; /* dual-port memory size */
unsigned pclk; /* CPU clock rate, kHz */
@@ -50,6 +64,8 @@ extern int sdla_down (sdlahw_t* hw);
extern int sdla_inten (sdlahw_t* hw);
extern int sdla_intde (sdlahw_t* hw);
extern int sdla_intack (sdlahw_t* hw);
+extern void S514_intack (sdlahw_t* hw, u32 int_status);
+extern void read_S514_int_stat (sdlahw_t* hw, u32* int_status);
extern int sdla_intr (sdlahw_t* hw);
extern int sdla_mapmem (sdlahw_t* hw, unsigned long addr);
extern int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf,
diff --git a/include/linux/sdlapci.h b/include/linux/sdlapci.h
new file mode 100644
index 000000000..857fd062c
--- /dev/null
+++ b/include/linux/sdlapci.h
@@ -0,0 +1,68 @@
+/*****************************************************************************
+* sdlapci.h WANPIPE(tm) Multiprotocol WAN Link Driver.
+* Definitions for the SDLA PCI adapter.
+*
+* Author: Gideon Hack <ghack@sangoma.com>
+*
+* Copyright: (c) 1999 Sangoma Technologies 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.
+* ============================================================================
+* Jun 02, 1999 Gideon Hack Initial version.
+*****************************************************************************/
+#ifndef _SDLAPCI_H
+#define _SDLAPCI_H
+
+/****** Defines *************************************************************/
+
+/* Definitions for identifying and finding S514 PCI adapters */
+#define V3_VENDOR_ID 0x11B0 /* V3 vendor ID number */
+#define V3_DEVICE_ID 0x0002 /* V3 device ID number */
+#define SANGOMA_SUBSYS_VENDOR 0x4753 /* ID for Sangoma */
+#define PCI_DEV_SLOT_MASK 0x1F /* mask for slot numbering */
+#define PCI_IRQ_NOT_ALLOCATED 0xFF /* interrupt line for no IRQ */
+
+/* Local PCI register offsets */
+#define PCI_VENDOR_ID_WORD 0x00 /* vendor ID */
+#define PCI_IO_BASE_DWORD 0x10 /* IO base */
+#define PCI_MEM_BASE0_DWORD 0x14 /* memory base - apperture 0 */
+#define PCI_MEM_BASE1_DWORD 0x18 /* memory base - apperture 1 */
+#define PCI_SUBSYS_VENDOR_WORD 0x2C /* subsystem vendor ID */
+#define PCI_INT_LINE_BYTE 0x3C /* interrupt line */
+#define PCI_INT_PIN_BYTE 0x3D /* interrupt pin */
+#define PCI_MAP0_DWORD 0x40 /* PCI to local bus address 0 */
+#define PCI_MAP1_DWORD 0x44 /* PCI to local bus address 1 */
+#define PCI_INT_STATUS 0x48 /* interrupt status */
+#define PCI_INT_CONFIG 0x4C /* interrupt configuration */
+
+/* Local PCI register usage */
+#define PCI_MEMORY_ENABLE 0x00000003 /* enable PCI memory */
+#define PCI_CPU_A_MEM_DISABLE 0x00000002 /* disable CPU A memory */
+#define PCI_CPU_B_MEM_DISABLE 0x00100002 /* disable CPU B memory */
+#define PCI_ENABLE_IRQ_CPU_A 0x005A0004 /* enable IRQ for CPU A */
+#define PCI_ENABLE_IRQ_CPU_B 0x005A0008 /* enable IRQ for CPU B */
+#define PCI_DISABLE_IRQ_CPU_A 0x00000004 /* disable IRQ for CPU A */
+#define PCI_DISABLE_IRQ_CPU_B 0x00000008 /* disable IRQ for CPU B */
+
+/* Setting for the Interrupt Status register */
+#define IRQ_CPU_A 0x04 /* IRQ for CPU A */
+#define IRQ_CPU_B 0x08 /* IRQ for CPU B */
+
+/* The maximum size of the S514 memory */
+#define MAX_SIZEOF_S514_MEMORY (256 * 1024)
+
+/* S514 control register offsets within the memory address space */
+#define S514_CTRL_REG_BYTE 0x80000
+
+/* S514 adapter control bytes */
+#define S514_CPU_HALT 0x00
+#define S514_CPU_START 0x01
+
+/* The maximum number of S514 adapters supported */
+#define MAX_S514_CARDS 8
+
+#endif /* _SDLAPCI_H */
+
diff --git a/include/linux/sdlasfm.h b/include/linux/sdlasfm.h
index 65e7f30a8..94aaa8ada 100644
--- a/include/linux/sdlasfm.h
+++ b/include/linux/sdlasfm.h
@@ -2,15 +2,16 @@
* sdlasfm.h WANPIPE(tm) Multiprotocol WAN Link Driver.
* Definitions for the SDLA Firmware Module (SFM).
*
-* Author: Gene Kozin <74604.152@compuserve.com>
+* Author: Gideon Hack
*
-* Copyright: (c) 1995-1996 Sangoma Technologies Inc.
+* Copyright: (c) 1995-1999 Sangoma Technologies 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.
* ============================================================================
+* Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
* Dec 11, 1996 Gene Kozin Cosmetic changes
* Apr 16, 1996 Gene Kozin Changed adapter & firmware IDs. Version 2
* Dec 15, 1995 Gene Kozin Structures chaned
@@ -36,6 +37,12 @@
#define SDLA_S508 5080
#define SDLA_S507 5070
#define SDLA_S509 5090
+#define SDLA_S514 5140
+
+/* S514 PCI adapter CPU numbers */
+#define S514_CPU_A 'A'
+#define S514_CPU_B 'B'
+
/* Firmware identification numbers:
* 0 .. 999 Test & Diagnostics
@@ -46,6 +53,7 @@
* 5000 .. 5999 X.25
* 6000 .. 6999 Frame Relay
* 7000 .. 7999 PPP
+ * 8000 .. 8999 Cisco HDLC
*/
#define SFID_CALIB502 200
#define SFID_STRM502 1200
@@ -53,12 +61,16 @@
#define SFID_BSC502 2200
#define SFID_SDLC502 3200
#define SFID_HDLC502 4200
+#define SFID_HDLC508 4800
#define SFID_X25_502 5200
#define SFID_X25_508 5800
#define SFID_FR502 6200
#define SFID_FR508 6800
#define SFID_PPP502 7200
#define SFID_PPP508 7800
+#define SFID_PPP514 7140
+#define SFID_CHDLC508 8800
+#define SFID_CHDLC514 8140
/****** Data Types **********************************************************/
diff --git a/include/linux/serial.h b/include/linux/serial.h
index bfeee939c..ffc8d9d49 100644
--- a/include/linux/serial.h
+++ b/include/linux/serial.h
@@ -38,20 +38,6 @@ struct serial_struct {
#define ASYNC_CLOSING_WAIT_NONE 65535
/*
- * The size of the serial xmit buffer is 1 page, or 4096 bytes
- */
-#define SERIAL_XMIT_SIZE 4096
-
-/*
- * Counters of the input lines (CTS, DSR, RI, CD) interrupts
- */
-struct async_icount {
- __u32 cts, dsr, rng, dcd, tx, rx;
- __u32 frame, parity, overrun, brk;
- __u32 buf_overrun;
-};
-
-/*
* These are the supported serial types.
*/
#define PORT_UNKNOWN 0
diff --git a/include/linux/serialP.h b/include/linux/serialP.h
index 3fdadb4a1..ffd52dd86 100644
--- a/include/linux/serialP.h
+++ b/include/linux/serialP.h
@@ -19,11 +19,18 @@
* For definitions of the flags field, see tty.h
*/
-#include <linux/config.h>
#include <linux/termios.h>
#include <linux/tqueue.h>
#include <linux/wait.h>
+/*
+ * Counters of the input lines (CTS, DSR, RI, CD) interrupts
+ */
+struct async_icount {
+ __u32 cts, dsr, rng, dcd, tx, rx;
+ __u32 frame, parity, overrun, brk;
+ __u32 buf_overrun;
+};
struct serial_state {
int magic;
@@ -158,7 +165,7 @@ struct pci_board {
};
struct pci_board_inst {
- struct pci_board *board;
+ struct pci_board board;
struct pci_dev *dev;
};
@@ -172,7 +179,28 @@ struct pci_board_inst {
#define SPCI_FL_BASE2 0x0002
#define SPCI_FL_BASE3 0x0003
#define SPCI_FL_BASE4 0x0004
-#define SPCI_FL_IOMEM 0x0008 /* Use I/O mapped memory */
-#define SPCI_FL_BASE_TABLE 0x0010 /* Use base address table for UART */
-
+#define SPCI_FL_GET_BASE(x) (x & SPCI_FL_BASE_MASK)
+
+#define SPCI_FL_IRQ_MASK (0x0007 << 4)
+#define SPCI_FL_IRQBASE0 (0x0000 << 4)
+#define SPCI_FL_IRQBASE1 (0x0001 << 4)
+#define SPCI_FL_IRQBASE2 (0x0002 << 4)
+#define SPCI_FL_IRQBASE3 (0x0003 << 4)
+#define SPCI_FL_IRQBASE4 (0x0004 << 4)
+#define SPCI_FL_GET_IRQBASE(x) ((x & SPCI_FL_IRQ_MASK) >> 4)
+
+/* Use sucessiveentries base resource table */
+#define SPCI_FL_BASE_TABLE 0x0100
+
+/* Use successive entries in the irq resource table */
+#define SPCI_FL_IRQ_TABLE 0x0200
+
+/* Use the irq resource table instead of dev->irq */
+#define SPCI_FL_IRQRESOURCE 0x0400
+
+/* Use the Base address register size to cap number of ports */
+#define SPCI_FL_REGION_SZ_CAP 0x0800
+
+#define SPCI_FL_PNPDEFAULT (SPCI_FL_IRQRESOURCE)
+
#endif /* _LINUX_SERIAL_H */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 7bea8a9a0..f2170ed5f 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -202,16 +202,25 @@ extern __inline__ int skb_queue_empty(struct sk_buff_head *list)
return (list->next == (struct sk_buff *) list);
}
+extern __inline__ struct sk_buff *skb_get(struct sk_buff *skb)
+{
+ atomic_inc(&skb->users);
+ return skb;
+}
+
+/* If users==1, we are the only owner and are can avoid redundant
+ * atomic change.
+ */
extern __inline__ void kfree_skb(struct sk_buff *skb)
{
- if (atomic_dec_and_test(&skb->users))
+ if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users))
__kfree_skb(skb);
}
/* Use this if you didn't touch the skb state [for fast switching] */
extern __inline__ void kfree_skb_fast(struct sk_buff *skb)
{
- if (atomic_dec_and_test(&skb->users))
+ if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users))
kfree_skbmem(skb);
}
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 97f6923da..36f1a6718 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -22,7 +22,8 @@ typedef struct kmem_cache_s kmem_cache_t;
#define SLAB_NFS GFP_NFS
#define SLAB_DMA GFP_DMA
-#define SLAB_LEVEL_MASK 0x0000007fUL
+#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_SWAP| \
+ __GFP_HIGHMEM)
#define SLAB_NO_GROW 0x00001000UL /* don't grow a cache */
/* flags to pass to kmem_cache_create().
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 2c6771a4f..5f8a10198 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -80,6 +80,7 @@ extern volatile int smp_msg_id;
#define smp_threads_ready 1
#define kernel_lock()
#define cpu_logical_map(cpu) 0
+#define cpu_number_map(cpu) 0
#define smp_call_function(func,info,retry,wait) ({ 0; })
#endif
diff --git a/include/linux/sockios.h b/include/linux/sockios.h
index 995e43e9a..fe38a2d40 100644
--- a/include/linux/sockios.h
+++ b/include/linux/sockios.h
@@ -20,6 +20,10 @@
#include <asm/sockios.h>
+/* Linux-specific socket ioctls */
+#define SIOCINQ FIONREAD
+#define SIOCOUTQ TIOCOUTQ
+
/* Routing table calls. */
#define SIOCADDRT 0x890B /* add routing table entry */
#define SIOCDELRT 0x890C /* delete routing table entry */
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index d0a68c502..03148253d 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -251,7 +251,12 @@ enum
NET_IPV4_INET_PEER_MINTTL=70,
NET_IPV4_INET_PEER_MAXTTL=71,
NET_IPV4_INET_PEER_GC_MINTIME=72,
- NET_IPV4_INET_PEER_GC_MAXTIME=73
+ NET_IPV4_INET_PEER_GC_MAXTIME=73,
+ NET_TCP_ORPHAN_RETRIES=74,
+ NET_TCP_ABORT_ON_OVERFLOW=75,
+ NET_TCP_SYNACK_RETRIES=76,
+ NET_TCP_MAX_ORPHANS=77,
+ NET_TCP_MAX_TW_BUCKETS=78,
};
enum {
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 1e78e322c..e030ee09f 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -124,5 +124,6 @@ enum {
#define TCP_SYNCNT 7 /* Number of SYN retransmits */
#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */
#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */
+#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */
#endif /* _LINUX_TCP_H */
diff --git a/include/linux/udf_fs.h b/include/linux/udf_fs.h
index e3dbdd5fd..162823404 100644
--- a/include/linux/udf_fs.h
+++ b/include/linux/udf_fs.h
@@ -1,7 +1,17 @@
/*
* udf_fs.h
*
- * Included by fs/filesystems.c
+ * PURPOSE
+ * Included by fs/filesystems.c
+ *
+ * DESCRIPTION
+ * OSTA-UDF(tm) = Optical Storage Technology Association
+ * Universal Disk Format.
+ *
+ * This code is based on version 2.00 of the UDF specification,
+ * and revision 3 of the ECMA 167 standard [equivalent to ISO 13346].
+ * http://www.osta.org/ * http://www.ecma.ch/
+ * http://www.iso.org/
*
* CONTACTS
* E-mail regarding any portion of the Linux UDF file system should be
@@ -14,15 +24,17 @@
* ftp://prep.ai.mit.edu/pub/gnu/GPL
* Each contributing author retains all rights to their own work.
*
+ * (C) 1999-2000 Ben Fennema
+ * (C) 1999-2000 Stelias Computing Inc
+ *
* HISTORY
- * July 21, 1997 - Andrew E. Mileski
- * Written, tested, and released.
*
- * 10/2/98 dgb rearranged all headers
- * 11/26/98 bf added byte order macros
- * 12/5/98 dgb removed other includes to reduce kernel namespace pollution.
+ * 10/02/98 dgb rearranged all headers
+ * 11/26/98 blf added byte order macros
+ * 12/05/98 dgb removed other includes to reduce kernel namespace pollution.
* This should only be included by the kernel now!
*/
+
#if !defined(_LINUX_UDF_FS_H)
#define _LINUX_UDF_FS_H
@@ -30,8 +42,8 @@
#define UDF_DEFAULT_PREALLOC_BLOCKS 8
#define UDF_DEFAULT_PREALLOC_DIR_BLOCKS 0
-#define UDFFS_DATE "99/11/18"
-#define UDFFS_VERSION "0.8.9.4"
+#define UDFFS_DATE "2000/01/17"
+#define UDFFS_VERSION "0.9.0"
#define UDFFS_DEBUG
#ifdef UDFFS_DEBUG
@@ -48,15 +60,6 @@
#define udf_info(f, a...) \
printk (KERN_INFO "UDF-fs INFO " ## f, ## a);
-struct udf_addr
-{
- __u32 block;
- __u16 partition;
- unsigned error : 1;
- unsigned reserved : 15;
-};
-
-
/* Prototype for fs/filesystem.c (the only thing really required in this file) */
extern int init_udf_fs(void);
diff --git a/include/linux/udf_fs_i.h b/include/linux/udf_fs_i.h
index c9d7b2fe7..a4bf4ba34 100644
--- a/include/linux/udf_fs_i.h
+++ b/include/linux/udf_fs_i.h
@@ -34,10 +34,7 @@ struct udf_inode_info
long i_umtime;
long i_uctime;
/* Physical address of inode */
- lb_addr i_ext0Location; /* partition relative */
lb_addr i_location;
- __u32 i_ext0Length; /* in blocks */
- __u32 i_ext0Offset; /* for short directories */
__u64 i_unique;
__u32 i_lenEAttr;
__u32 i_lenAlloc;
diff --git a/include/linux/udf_fs_sb.h b/include/linux/udf_fs_sb.h
index 87635c411..d160eed0a 100644
--- a/include/linux/udf_fs_sb.h
+++ b/include/linux/udf_fs_sb.h
@@ -29,14 +29,22 @@
struct udf_sparing_data
{
- __u32 s_spar_loc;
- __u16 s_spar_plen;
+ __u32 s_spar_loc[4];
+ __u8 s_spar_pshift;
+ __u8 s_spar_indexsize;
+ __u32 *s_spar_map;
+ union
+ {
+ __u8 *s_spar_remap8;
+ __u16 *s_spar_remap16;
+ __u32 *s_spar_remap32;
+ } s_spar_remap;
};
struct udf_virtual_data
{
- __u32 s_num_entries;
- __u16 s_start_offset;
+ __u32 s_num_entries;
+ __u16 s_start_offset;
};
struct udf_part_map
@@ -51,6 +59,7 @@ struct udf_part_map
struct udf_sparing_data s_sparing;
struct udf_virtual_data s_virtual;
} s_type_specific;
+ __u32 (*s_partition_func)(struct super_block *, __u32, __u16, __u32);
__u16 s_volumeseqnum;
};
@@ -72,8 +81,6 @@ struct udf_sb_info
struct buffer_head *s_lvidbh;
- lb_addr s_location;
-
__u16 s_loaded_block_bitmaps;
__u32 s_block_bitmap_number[UDF_MAX_BLOCK_LOADED];
struct buffer_head *s_block_bitmap[UDF_MAX_BLOCK_LOADED];
@@ -89,20 +96,11 @@ struct udf_sb_info
/* Fileset Info */
__u16 s_serialnum;
- /* Character Mapping Info */
- struct nls_table *s_nls_iocharset;
- __u8 s_utf8;
-
/* Miscellaneous flags */
__u32 s_flags;
/* VAT inode */
struct inode *s_vat;
-
-#if LINUX_VERSION_CODE < 0x020206
- int s_rename_lock;
- struct wait_queue * s_rename_wait;
-#endif
};
#endif /* !defined(_LINUX_UDF_FS_SB_H) */
diff --git a/include/linux/udf_udf.h b/include/linux/udf_udf.h
index b9778916a..e0f071ddd 100644
--- a/include/linux/udf_udf.h
+++ b/include/linux/udf_udf.h
@@ -101,8 +101,7 @@ struct SparablePartitionMap
Uint8 numSparingTables;
Uint8 reserved2[1]; /* #00 */
Uint32 sizeSparingTable;
- Uint32 locSparingTable[0];
- Uint8 pad[0];
+ Uint32 locSparingTable[4];
};
/* DVD Copyright Management Info, see UDF 1.02 3.3.4.5.1.2 */
diff --git a/include/linux/utsname.h b/include/linux/utsname.h
index a83503f99..13e1da0c5 100644
--- a/include/linux/utsname.h
+++ b/include/linux/utsname.h
@@ -32,5 +32,5 @@ struct new_utsname {
extern struct new_utsname system_utsname;
-extern struct semaphore uts_sem;
+extern struct rw_semaphore uts_sem;
#endif
diff --git a/include/linux/videodev.h b/include/linux/videodev.h
index 88465e567..e1ba268a7 100644
--- a/include/linux/videodev.h
+++ b/include/linux/videodev.h
@@ -370,6 +370,7 @@ struct video_code
#define VID_HARDWARE_CPIA 24
#define VID_HARDWARE_ZR36120 25 /* Zoran ZR36120/ZR36125 */
#define VID_HARDWARE_ZR36067 26 /* Zoran ZR36067/36060 */
+#define VID_HARDWARE_OV511 27
/*
* Initialiser list
diff --git a/include/linux/wanpipe.h b/include/linux/wanpipe.h
index 434ade5a2..830e48e43 100644
--- a/include/linux/wanpipe.h
+++ b/include/linux/wanpipe.h
@@ -2,16 +2,23 @@
* wanpipe.h WANPIPE(tm) Multiprotocol WAN Link Driver.
* User-level API definitions.
*
-* Author: Gene Kozin <genek@compuserve.com>
-* Jaspreet Singh <jaspreet@sangoma.com>
+* Author: Nenad Corbic <ncorbic@sangoma.com>
+* Gideon Hack
*
-* Copyright: (c) 1995-1997 Sangoma Technologies Inc.
+* Copyright: (c) 1995-1999 Sangoma Technologies 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.
* ============================================================================
+* Oct 04, 1999 Nenad Corbic New CHDLC and FRAME RELAY code, SMP support
+* Jun 02, 1999 Gideon Hack Added 'update_call_count' for Cisco HDLC
+* support
+* Jun 26, 1998 David Fong Added 'ip_mode' in sdla_t.u.p for dynamic IP
+* routing mode configuration
+* Jun 12, 1998 David Fong Added Cisco HDLC union member in sdla_t
+* Dec 08, 1997 Jaspreet Singh Added 'authenticator' in union of 'sdla_t'
* Nov 26, 1997 Jaspreet Singh Added 'load_sharing' structure. Also added
* 'devs_struct','dev_to_devtint_next' to 'sdla_t'
* Nov 24, 1997 Jaspreet Singh Added 'irq_dis_if_send_count',
@@ -28,6 +35,10 @@
#ifndef _WANPIPE_H
#define _WANPIPE_H
+#ifdef __SMP__
+#include <asm/spinlock.h> /* Support for SMP Locking */
+#endif
+
#include <linux/wanrouter.h>
/* Defines */
@@ -42,6 +53,16 @@
#define WANPIPE_DUMP (ROUTER_USER+0) /* dump adapter's memory */
#define WANPIPE_EXEC (ROUTER_USER+1) /* execute firmware command */
+#define TRACE_ALL 0x00
+#define TRACE_PROT 0x01
+#define TRACE_DATA 0x02
+
+/* values for request/reply byte */
+#define UDPMGMT_REQUEST 0x01
+#define UDPMGMT_REPLY 0x02
+#define UDP_OFFSET 12
+
+
/*
* Data structures for IOCTL calls.
*/
@@ -97,16 +118,86 @@ typedef struct global_stats
} global_stats_t;
-/* This structure is used for maitaining a circular linked list of all
- * interfaces(devices) per card. It is used in the Interrupt Service routine
- * for a transmit interrupt where the start of the loop to dev_tint all
- * interfaces changes.
- */
-typedef struct load_sharing
-{
- struct net_device* dev_ptr;
- struct load_sharing* next;
-} load_sharing_t;
+
+typedef struct{
+ unsigned short udp_src_port PACKED;
+ unsigned short udp_dst_port PACKED;
+ unsigned short udp_length PACKED;
+ unsigned short udp_checksum PACKED;
+} udp_pkt_t;
+
+
+typedef struct {
+ unsigned char ver_inet_hdr_length PACKED;
+ unsigned char service_type PACKED;
+ unsigned short total_length PACKED;
+ unsigned short identifier PACKED;
+ unsigned short flags_frag_offset PACKED;
+ unsigned char ttl PACKED;
+ unsigned char protocol PACKED;
+ unsigned short hdr_checksum PACKED;
+ unsigned long ip_src_address PACKED;
+ unsigned long ip_dst_address PACKED;
+} ip_pkt_t;
+
+
+typedef struct {
+ unsigned char signature[8] PACKED;
+ unsigned char request_reply PACKED;
+ unsigned char id PACKED;
+ unsigned char reserved[6] PACKED;
+} wp_mgmt_t;
+
+/*************************************************************************
+ Data Structure for if_send statistics
+*************************************************************************/
+typedef struct if_send_stat{
+ unsigned long if_send_entry;
+ unsigned long if_send_skb_null;
+ unsigned long if_send_broadcast;
+ unsigned long if_send_multicast;
+ unsigned long if_send_critical_ISR;
+ unsigned long if_send_critical_non_ISR;
+ unsigned long if_send_tbusy;
+ unsigned long if_send_tbusy_timeout;
+ unsigned long if_send_PIPE_request;
+ unsigned long if_send_wan_disconnected;
+ unsigned long if_send_dlci_disconnected;
+ unsigned long if_send_no_bfrs;
+ unsigned long if_send_adptr_bfrs_full;
+ unsigned long if_send_bfr_passed_to_adptr;
+ unsigned long if_send_protocol_error;
+ unsigned long if_send_bfr_not_passed_to_adptr;
+ unsigned long if_send_tx_int_enabled;
+ unsigned long if_send_consec_send_fail;
+} if_send_stat_t;
+
+typedef struct rx_intr_stat{
+ unsigned long rx_intr_no_socket;
+ unsigned long rx_intr_dev_not_started;
+ unsigned long rx_intr_PIPE_request;
+ unsigned long rx_intr_bfr_not_passed_to_stack;
+ unsigned long rx_intr_bfr_passed_to_stack;
+} rx_intr_stat_t;
+
+typedef struct pipe_mgmt_stat{
+ unsigned long UDP_PIPE_mgmt_kmalloc_err;
+ unsigned long UDP_PIPE_mgmt_direction_err;
+ unsigned long UDP_PIPE_mgmt_adptr_type_err;
+ unsigned long UDP_PIPE_mgmt_adptr_cmnd_OK;
+ unsigned long UDP_PIPE_mgmt_adptr_cmnd_timeout;
+ unsigned long UDP_PIPE_mgmt_adptr_send_passed;
+ unsigned long UDP_PIPE_mgmt_adptr_send_failed;
+ unsigned long UDP_PIPE_mgmt_not_passed_to_stack;
+ unsigned long UDP_PIPE_mgmt_passed_to_stack;
+ unsigned long UDP_PIPE_mgmt_no_socket;
+ unsigned long UDP_PIPE_mgmt_passed_to_adptr;
+} pipe_mgmt_stat_t;
+
+
+
+#define MAX_LGTH_UDP_MGNT_PKT 2000
+
/* This is used for interrupt testing */
#define INTR_TEST_MODE 0x02
@@ -154,23 +245,23 @@ typedef struct sdla
char in_isr; /* interrupt-in-service flag */
char buff_int_mode_unbusy; /* flag for carrying out dev_tint */
char dlci_int_mode_unbusy; /* flag for carrying out dev_tint */
+ char configured; /* flag for previous configurations */
unsigned short irq_dis_if_send_count; /* Disabling irqs in if_send*/
unsigned short irq_dis_poll_count; /* Disabling irqs in poll routine*/
+ unsigned short force_enable_irq;
+ char TracingEnabled; /* flag for enabling trace */
global_stats_t statistics; /* global statistics */
-
- /* The following is used as a pointer to the structure in our
- circular linked list which changes the start of the loop for
- dev_tint of all interfaces */
-
- load_sharing_t* dev_to_devtint_next;
- load_sharing_t* devs_struct;
-
+#ifdef __SMP__
+ spinlock_t lock; /* Support for SMP Locking */
+#endif
void* mbox; /* -> mailbox */
void* rxmb; /* -> receive mailbox */
void* flags; /* -> adapter status flags */
void (*isr)(struct sdla* card); /* interrupt service routine */
void (*poll)(struct sdla* card); /* polling routine */
int (*exec)(struct sdla* card, void* u_cmd, void* u_data);
+
+ struct sdla *next; /* Secondary Port Device: Piggibacking */
union
{
struct
@@ -188,6 +279,19 @@ typedef struct sdla
unsigned rx_top; /* S508 receive buffer end */
unsigned short node_dlci[100];
unsigned short dlci_num;
+ struct net_device *dlci_to_dev_map[991 + 1];
+ unsigned tx_interrupts_pending;
+ unsigned short timer_int_enabled;
+ unsigned short udp_pkt_lgth;
+ int udp_type;
+ char udp_pkt_src;
+ unsigned udp_dlci;
+ char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
+ void* trc_el_base; /* first trace element */
+ void* trc_el_last; /* last trace element */
+ void *curr_trc_el; /* current trace element */
+ unsigned short trc_bfr_space; /* trace buffer space */
+ unsigned char update_comms_stats;
} f;
struct /****** PPP-specific data ***********/
{
@@ -199,7 +303,53 @@ typedef struct sdla
void* rxbuf_last; /* -> last Rx buffer */
unsigned rx_base; /* S508 receive buffer base */
unsigned rx_top; /* S508 receive buffer end */
+ char ip_mode; /* STATIC/HOST/PEER IP Mode */
+ char authenticator; /* Authenticator for PAP/CHAP */
} p;
+ struct /* Cisco HDLC-specific data */
+ {
+ char if_name[WAN_IFNAME_SZ+1]; /* interface name */
+ unsigned char comm_port;/* Communication Port O or 1 */
+ unsigned char usedby; /* Used by WANPIPE or API */
+ void* rxmb; /* Receive mail box */
+ void* flags; /* flags */
+ void* tx_status; /* Tx status element */
+ void* rx_status; /* Rx status element */
+ void* txbuf; /* -> current Tx buffer */
+ void* txbuf_base; /* -> first Tx buffer */
+ void* txbuf_last; /* -> last Tx buffer */
+ void* rxbuf_base; /* -> first Rx buffer */
+ void* rxbuf_last; /* -> last Rx buffer */
+ unsigned rx_base; /* S508 receive buffer base */
+ unsigned rx_top; /* S508 receive buffer end */
+ unsigned short protocol_options;
+ unsigned short kpalv_tx; /* Tx kpalv timer */
+ unsigned short kpalv_rx; /* Rx kpalv timer */
+ unsigned short kpalv_err; /* Error tolerance */
+ unsigned short slarp_timer; /* SLARP req timer */
+ unsigned state; /* state of the link */
+ unsigned char api_status;
+ unsigned char update_call_count;
+ } c;
+ struct
+ {
+ void* tx_status; /* Tx status element */
+ void* rx_status; /* Rx status element */
+ void* trace_status; /* Trace status element */
+ void* txbuf; /* -> current Tx buffer */
+ void* txbuf_base; /* -> first Tx buffer */
+ void* txbuf_last; /* -> last Tx buffer */
+ void* rxbuf_base; /* -> first Rx buffer */
+ void* rxbuf_last; /* -> last Rx buffer */
+ void* tracebuf; /* -> current Trace buffer */
+ void* tracebuf_base; /* -> current Trace buffer */
+ void* tracebuf_last; /* -> current Trace buffer */
+ unsigned rx_base; /* receive buffer base */
+ unsigned rx_end; /* receive buffer end */
+ unsigned trace_base; /* trace buffer base */
+ unsigned trace_end; /* trace buffer end */
+
+ } h;
} u;
} sdla_t;
@@ -212,6 +362,10 @@ void wanpipe_set_state (sdla_t* card, int state); /* wpmain.c */
int wpx_init (sdla_t* card, wandev_conf_t* conf); /* wpx.c */
int wpf_init (sdla_t* card, wandev_conf_t* conf); /* wpf.c */
int wpp_init (sdla_t* card, wandev_conf_t* conf); /* wpp.c */
+int wpc_init (sdla_t* card, wandev_conf_t* conf); /* Cisco HDLC */
+int bsc_init (sdla_t* card, wandev_conf_t* conf); /* BSC streaming */
+int hdlc_init(sdla_t* card, wandev_conf_t* conf); /* HDLC support */
+int wpft1_init (sdla_t* card, wandev_conf_t* conf); /* FT1 Config support */
#endif /* __KERNEL__ */
#endif /* _WANPIPE_H */
diff --git a/include/linux/wanrouter.h b/include/linux/wanrouter.h
index accecf8d2..7efa6a9c1 100644
--- a/include/linux/wanrouter.h
+++ b/include/linux/wanrouter.h
@@ -1,21 +1,29 @@
/*****************************************************************************
-* router.h Definitions for the WAN Multiprotocol Router Module.
+* wanrouter.h Definitions for the WAN Multiprotocol Router Module.
* This module provides API and common services for WAN Link
* Drivers and is completely hardware-independent.
*
-* Author: Gene Kozin <genek@compuserve.com>
-* Jaspreet Singh <jaspreet@sangoma.com>
+* Author: Nenad Corbic <ncorbic@sangoma.com>
+* Gideon Hack
* Additions: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*
-* Copyright: (c) 1995-1997 Sangoma Technologies Inc.
+* Copyright: (c) 1995-1999 Sangoma Technologies 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.
* ============================================================================
+* Oct 04, 1999 Nenad Corbic Updated for 2.1.0 release
+* Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
* May 23, 1999 Arnaldo Melo Added local_addr to wanif_conf_t
* WAN_DISCONNECTING state added
+* Jul 20, 1998 David Fong Added Inverse ARP options to 'wanif_conf_t'
+* Jun 12, 1998 David Fong Added Cisco HDLC support.
+* Dec 16, 1997 Jaspreet Singh Moved 'enable_IPX' and 'network_number' to
+* 'wanif_conf_t'
+* Dec 05, 1997 Jaspreet Singh Added 'pap', 'chap' to 'wanif_conf_t'
+* Added 'authenticator' to 'wan_ppp_conf_t'
* Nov 06, 1997 Jaspreet Singh Changed Router Driver version to 1.1 from 1.0
* Oct 20, 1997 Jaspreet Singh Added 'cir','bc','be' and 'mc' to 'wanif_conf_t'
* Added 'enable_IPX' and 'network_number' to
@@ -32,6 +40,12 @@
* Jan 16, 1997 Gene Kozin router_devlist made public
* Jan 02, 1997 Gene Kozin Initial version (based on wanpipe.h).
*****************************************************************************/
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE >= 0x020100
+#define LINUX_2_1
+#endif
+
#ifndef _ROUTER_H
#define _ROUTER_H
@@ -54,6 +68,10 @@ enum router_ioctls
ROUTER_USER_MAX = (ROUTER_IOCTL<<8)+31
};
+/* identifiers for displaying proc file data for dual port adapters */
+#define PROC_DATA_PORT_0 0x8000 /* the data is for port 0 */
+#define PROC_DATA_PORT_1 0x8001 /* the data is for port 1 */
+
/* NLPID for packet encapsulation (ISO/IEC TR 9577) */
#define NLPID_IP 0xCC /* Internet Protocol Datagram */
#define NLPID_SNAP 0x80 /* IEEE Subnetwork Access Protocol */
@@ -66,12 +84,14 @@ enum router_ioctls
#define WAN_IFNAME_SZ 15 /* max length of the interface name */
#define WAN_DRVNAME_SZ 15 /* max length of the link driver name */
#define WAN_ADDRESS_SZ 31 /* max length of the WAN media address */
+#define USED_BY_FIELD 8 /* max length of the used by field */
/* Defines for UDP PACKET TYPE */
#define UDP_PTPIPE_TYPE 0x01
#define UDP_FPIPE_TYPE 0x02
-#define UDP_DRVSTATS_TYPE 0x03
-#define UDP_INVALID_TYPE 0x04
+#define UDP_CPIPE_TYPE 0x03
+#define UDP_DRVSTATS_TYPE 0x04
+#define UDP_INVALID_TYPE 0x05
/* Command return code */
#define CMD_OK 0 /* normal firmware return code */
@@ -129,7 +149,7 @@ typedef struct wan_fr_conf
unsigned n392; /* error threshold counter */
unsigned n393; /* monitored events counter */
unsigned dlci_num; /* number of DLCs (access node) */
- unsigned dlci[100]; /* List of all DLCIs */
+ unsigned dlci[100]; /* List of all DLCIs */
} wan_fr_conf_t;
/*----------------------------------------------------------------------------
@@ -149,9 +169,27 @@ typedef struct wan_ppp_conf
unsigned auth_retry; /* max. retry */
unsigned auth_options; /* authentication opt. */
unsigned ip_options; /* IP options */
+ char authenticator; /* AUTHENTICATOR or not */
+ char ip_mode; /* Static/Host/Peer */
} wan_ppp_conf_t;
/*----------------------------------------------------------------------------
+ * CHDLC-specific link-level configuration.
+ */
+typedef struct wan_chdlc_conf
+{
+ unsigned char ignore_dcd; /* Protocol options: */
+ unsigned char ignore_cts; /* Ignore these to determine */
+ unsigned char ignore_keepalive; /* link status (Yes or No) */
+ unsigned char hdlc_streaming; /* hdlc_streaming mode (Y/N) */
+ unsigned keepalive_tx_tmr; /* transmit keepalive timer */
+ unsigned keepalive_rx_tmr; /* receive keepalive timer */
+ unsigned keepalive_err_margin; /* keepalive_error_tolerance */
+ unsigned slarp_timer; /* SLARP request timer */
+} wan_chdlc_conf_t;
+
+
+/*----------------------------------------------------------------------------
* WAN device configuration. Passed to ROUTER_SETUP IOCTL.
*/
typedef struct wandev_conf
@@ -164,18 +202,21 @@ typedef struct wandev_conf
unsigned msize; /* dual-port memory size */
int irq; /* interrupt request level */
int dma; /* DMA request level */
+ char S514_CPU_no[1]; /* S514 PCI adapter CPU number ('A' or 'B') */
+ unsigned PCI_slot_no; /* S514 PCI adapter slot number */
+ char comm_port; /* Communication Port (PRI=0, SEC=1) */
unsigned bps; /* data transfer rate */
unsigned mtu; /* maximum transmit unit size */
unsigned udp_port; /* UDP port for management */
unsigned char ttl; /* Time To Live for UDP security */
+ unsigned char ft1; /* FT1 Configurator Option */
char interface; /* RS-232/V.35, etc. */
char clocking; /* external/internal */
char line_coding; /* NRZ/NRZI/FM0/FM1, etc. */
char station; /* DTE/DCE, primary/secondary, etc. */
char connection; /* permanent/switched/on-demand */
+ char read_mode; /* read mode: Polling or interrupt */
unsigned hw_opt[4]; /* other hardware options */
- unsigned char enable_IPX; /* Enable or Disable IPX */
- unsigned long network_number; /* Network Number for IPX */
unsigned reserved[4];
/****** arbitrary data ***************/
unsigned data_size; /* data buffer size */
@@ -185,6 +226,7 @@ typedef struct wandev_conf
wan_x25_conf_t x25; /* X.25 configuration */
wan_ppp_conf_t ppp; /* PPP configuration */
wan_fr_conf_t fr; /* frame relay configuration */
+ wan_chdlc_conf_t chdlc; /* Cisco HDLC configuration */
} u;
} wandev_conf_t;
@@ -192,6 +234,9 @@ typedef struct wandev_conf
#define WANCONFIG_X25 101 /* X.25 link */
#define WANCONFIG_FR 102 /* frame relay link */
#define WANCONFIG_PPP 103 /* synchronous PPP link */
+#define WANCONFIG_CHDLC 104 /* Cisco HDLC Link */
+#define WANCONFIG_BSC 105 /* BiSync Streaming */
+#define WANCONFIG_HDLC 106 /* HDLC Support */
/*
* Configuration options defines.
@@ -234,9 +279,29 @@ typedef struct wandev_conf
#define WANOPT_ONDEMAND 2 /* activate DTR only before sending */
/* frame relay in-channel signalling */
-#define WANOPT_FR_ANSI 0 /* ANSI T1.617 Annex D */
-#define WANOPT_FR_Q933 1 /* ITU Q.933A */
-#define WANOPT_FR_LMI 2 /* LMI */
+#define WANOPT_FR_ANSI 1 /* ANSI T1.617 Annex D */
+#define WANOPT_FR_Q933 2 /* ITU Q.933A */
+#define WANOPT_FR_LMI 3 /* LMI */
+
+/* PPP IP Mode Options */
+#define WANOPT_PPP_STATIC 0
+#define WANOPT_PPP_HOST 1
+#define WANOPT_PPP_PEER 2
+
+/* CHDLC Protocol Options */
+/* DF Commmented out for now.
+
+#define WANOPT_CHDLC_NO_DCD IGNORE_DCD_FOR_LINK_STAT
+#define WANOPT_CHDLC_NO_CTS IGNORE_CTS_FOR_LINK_STAT
+#define WANOPT_CHDLC_NO_KEEPALIVE IGNORE_KPALV_FOR_LINK_STAT
+*/
+
+/* Port options */
+#define WANOPT_PRI 0
+#define WANOPT_SEC 1
+/* read mode */
+#define WANOPT_INTR 0
+#define WANOPT_POLL 1
/*----------------------------------------------------------------------------
* WAN Link Status Info (for ROUTER_STAT IOCTL).
@@ -278,8 +343,9 @@ enum wan_states
WAN_DISCONNECTED, /* link/channel is disconnected */
WAN_CONNECTING, /* connection is in progress */
WAN_CONNECTED, /* link/channel is operational */
- WAN_DISCONNECTING, /* disconnection is in progress */
- WAN_LIMIT /* for verification only */
+ WAN_LIMIT, /* for verification only */
+ WAN_DUALPORT, /* for Dual Port cards */
+ WAN_DISCONNECTING /* link/channel is disconnecting */
};
/* 'modem_status' masks */
@@ -297,16 +363,38 @@ typedef struct wanif_conf
unsigned config_id; /* configuration identifier */
char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */
+ char usedby[USED_BY_FIELD]; /* used by API or WANPIPE */
unsigned idle_timeout; /* sec, before disconnecting */
unsigned hold_timeout; /* sec, before re-connecting */
unsigned cir; /* Committed Information Rate fwd,bwd*/
unsigned bc; /* Committed Burst Size fwd, bwd */
unsigned be; /* Excess Burst Size fwd, bwd */
+ unsigned char enable_IPX; /* Enable or Disable IPX */
+ unsigned char inarp; /* Send Inverse ARP requests Y/N */
+ unsigned inarp_interval; /* sec, between InARP requests */
+ unsigned long network_number; /* Network Number for IPX */
char mc; /* Multicast on or off */
char local_addr[WAN_ADDRESS_SZ+1];/* local media address, ASCIIZ */
unsigned char port; /* board port */
unsigned char protocol; /* prococol used in this channel (TCPOX25 or X25) */
- int reserved[8]; /* reserved for future extensions */
+ char pap; /* PAP enabled or disabled */
+ char chap; /* CHAP enabled or disabled */
+ unsigned char userid[511]; /* List of User Id */
+ unsigned char passwd[511]; /* List of passwords */
+ unsigned char sysname[31]; /* Name of the system */
+ unsigned char ignore_dcd; /* Protocol options: */
+ unsigned char ignore_cts; /* Ignore these to determine */
+ unsigned char ignore_keepalive; /* link status (Yes or No) */
+ unsigned char hdlc_streaming; /* Hdlc streaming mode (Y/N) */
+ unsigned keepalive_tx_tmr; /* transmit keepalive timer */
+ unsigned keepalive_rx_tmr; /* receive keepalive timer */
+ unsigned keepalive_err_margin; /* keepalive_error_tolerance */
+ unsigned slarp_timer; /* SLARP request timer */
+ unsigned char ttl; /* Time To Live for UDP security */
+ char interface; /* RS-232/V.35, etc. */
+ char clocking; /* external/internal */
+ unsigned bps; /* data transfer rate */
+ unsigned mtu; /* maximum transmit unit size */
} wanif_conf_t;
#ifdef __KERNEL__
@@ -316,7 +404,6 @@ typedef struct wanif_conf
#include <linux/proc_fs.h> /* proc filesystem pragmatics */
#include <linux/inet.h> /* in_aton(), in_ntoa() prototypes */
#include <linux/netdevice.h> /* support for network drivers */
-
/*----------------------------------------------------------------------------
* WAN device data space.
*/
@@ -325,9 +412,12 @@ typedef struct wan_device
unsigned magic; /* magic number */
char* name; /* -> WAN device name (ASCIIZ) */
void* private; /* -> driver private data */
+ unsigned config_id; /* Configuration ID */
/****** hardware configuration ******/
unsigned ioport; /* adapter I/O port base #1 */
- void * maddr; /* dual-port memory address */
+ char S514_cpu_no[1]; /* PCI CPU Number */
+ unsigned char S514_slot_no; /* PCI Slot Number */
+ unsigned long maddr; /* dual-port memory address */
unsigned msize; /* dual-port memory size */
int irq; /* interrupt request level */
int dma; /* DMA request level */
@@ -341,24 +431,31 @@ typedef struct wan_device
char line_coding; /* NRZ/NRZI/FM0/FM1, etc. */
char station; /* DTE/DCE, primary/secondary, etc. */
char connection; /* permanent/switched/on-demand */
+ char signalling; /* Signalling RS232 or V35 */
+ char read_mode; /* read mode: Polling or interrupt */
+ char new_if_cnt; /* Number of interfaces per wanpipe */
+ char del_if_cnt; /* Number of times del_if() gets called */
+ unsigned char piggyback; /* Piggibacking a port */
unsigned hw_opt[4]; /* other hardware options */
- unsigned char enable_IPX; /* Enable or Disable IPX */
- unsigned long network_number; /* Network Number for IPX */
/****** status and statistics *******/
char state; /* device state */
- unsigned modem_status; /* modem status */
+ char api_status; /* device api status */
+#ifdef LINUX_2_1
+ struct net_device_stats stats; /* interface statistics */
+#else
struct enet_statistics stats; /* interface statistics */
+#endif
unsigned reserved[16]; /* reserved for future use */
unsigned critical; /* critical section flag */
/****** device management methods ***/
- int (*setup) (struct wan_device* wandev, wandev_conf_t* conf);
- int (*shutdown) (struct wan_device* wandev);
- int (*update) (struct wan_device* wandev);
- int (*ioctl) (struct wan_device* wandev, unsigned cmd,
+ int (*setup) (struct wan_device *wandev, wandev_conf_t *conf);
+ int (*shutdown) (struct wan_device *wandev);
+ int (*update) (struct wan_device *wandev);
+ int (*ioctl) (struct wan_device *wandev, unsigned cmd,
unsigned long arg);
- int (*new_if) (struct wan_device* wandev, struct net_device* dev,
- wanif_conf_t* conf);
- int (*del_if) (struct wan_device* wandev, struct net_device* dev);
+ int (*new_if) (struct wan_device *wandev, struct net_device *dev,
+ wanif_conf_t *conf);
+ int (*del_if) (struct wan_device *wandev, struct net_device *dev);
/****** maintained by the router ****/
struct wan_device* next; /* -> next device */
struct net_device* dev; /* list of network interfaces */
@@ -367,23 +464,20 @@ typedef struct wan_device
} wan_device_t;
/* Public functions available for device drivers */
-extern int register_wan_device(wan_device_t* wandev);
-extern int unregister_wan_device(char* name);
-unsigned short wanrouter_type_trans(struct sk_buff* skb, struct net_device* dev);
-int wanrouter_encapsulate(struct sk_buff* skb, struct net_device* dev);
+extern int register_wan_device(wan_device_t *wandev);
+extern int unregister_wan_device(char *name);
+unsigned short wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev);
+int wanrouter_encapsulate(struct sk_buff *skb, struct net_device *dev);
/* Proc interface functions. These must not be called by the drivers! */
-extern int wanrouter_proc_init (void);
-extern void wanrouter_proc_cleanup (void);
-extern int wanrouter_proc_add (wan_device_t* wandev);
-extern int wanrouter_proc_delete (wan_device_t* wandev);
-extern int wanrouter_ioctl(
- struct inode* inode, struct file* file,
- unsigned int cmd, unsigned long arg)
-;
+extern int wanrouter_proc_init(void);
+extern void wanrouter_proc_cleanup(void);
+extern int wanrouter_proc_add(wan_device_t *wandev);
+extern int wanrouter_proc_delete(wan_device_t *wandev);
+extern int wanrouter_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
/* Public Data */
-extern wan_device_t* router_devlist; /* list of registered devices */
+extern wan_device_t *router_devlist; /* list of registered devices */
#endif /* __KERNEL__ */
#endif /* _ROUTER_H */
diff --git a/include/linux/zorro.h b/include/linux/zorro.h
index 9ec9ca719..26c7a460e 100644
--- a/include/linux/zorro.h
+++ b/include/linux/zorro.h
@@ -1,7 +1,7 @@
/*
* linux/zorro.h -- Amiga AutoConfig (Zorro) Bus Definitions
*
- * Copyright (C) 1995-1998 Geert Uytterhoeven
+ * Copyright (C) 1995-2000 Geert Uytterhoeven
*
* 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
@@ -39,6 +39,9 @@
typedef __u32 zorro_id;
+#define ZORRO_WILDCARD (0xffffffff) /* not official */
+
+
#define ZORRO_MANUF_PACIFIC_PERIPHERALS 0x00D3
#define ZORRO_PROD_PACIFIC_PERIPHERALS_SE_2000_A500 ZORRO_ID(PACIFIC_PERIPHERALS, 0x00, 0)
#define ZORRO_PROD_PACIFIC_PERIPHERALS_SCSI ZORRO_ID(PACIFIC_PERIPHERALS, 0x0A, 0)
@@ -694,8 +697,19 @@ CD_sizeof = CD_Unused+(4*4)
#ifdef __KERNEL__
+#include <linux/ioport.h>
+
+struct zorro_dev {
+ struct ExpansionRom rom;
+ zorro_id id;
+ u16 slotaddr;
+ u16 slotsize;
+ char name[48];
+ struct resource resource;
+};
+
extern unsigned int zorro_num_autocon; /* # of autoconfig devices found */
-extern struct ConfigDev zorro_autocon[ZORRO_NUM_AUTO];
+extern struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO];
/*
@@ -705,10 +719,18 @@ extern struct ConfigDev zorro_autocon[ZORRO_NUM_AUTO];
extern void zorro_init(void);
extern void zorro_proc_init(void);
-extern unsigned int zorro_find(zorro_id id, unsigned int part, unsigned int index);
-extern const struct ConfigDev *zorro_get_board(unsigned int key);
-extern void zorro_config_board(unsigned int key, unsigned int part);
-extern void zorro_unconfig_board(unsigned int key, unsigned int part);
+extern struct zorro_dev *zorro_find_device(zorro_id id,
+ struct zorro_dev *from);
+
+#define zorro_request_device(z, name) \
+ request_mem_region((z)->resource.start, \
+ (z)->resource.end-(z)->resource.start+1, (name))
+#define zorro_check_device(z) \
+ check_mem_region((z)->resource.start, \
+ (z)->resource.end-(z)->resource.start+1)
+#define zorro_release_device(z) \
+ release_mem_region((z)->resource.start, \
+ (z)->resource.end-(z)->resource.start+1)
/*
diff --git a/include/net/dst.h b/include/net/dst.h
index 79a3cd392..4bca9c092 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -29,10 +29,13 @@ struct dst_entry
struct dst_entry *next;
atomic_t __refcnt; /* client references */
int __use;
- struct net_device *dev;
+ struct net_device *dev;
int obsolete;
+ int flags;
+#define DST_HOST 1
unsigned long lastuse;
unsigned long expires;
+
unsigned mxlock;
unsigned pmtu;
unsigned window;
@@ -41,6 +44,7 @@ struct dst_entry
unsigned ssthresh;
unsigned cwnd;
unsigned advmss;
+
unsigned long rate_last; /* rate limiting for ICMP */
unsigned long rate_tokens;
diff --git a/include/net/ip.h b/include/net/ip.h
index eeb25ffea..a17c12bbd 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -84,7 +84,7 @@ extern int ip_mc_procinfo(char *, char **, off_t, int);
* Functions provided by ip.c
*/
-extern void ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
+extern int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
u32 saddr, u32 daddr,
struct ip_options *opt);
extern int ip_rcv(struct sk_buff *skb, struct net_device *dev,
diff --git a/include/net/route.h b/include/net/route.h
index 9ccfd3bea..180daad87 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -92,8 +92,7 @@ struct ip_rt_acct
__u32 i_packets;
};
-extern struct ip_rt_acct ip_rt_acct[256];
-extern rwlock_t ip_rt_acct_lock;
+extern struct ip_rt_acct *ip_rt_acct;
extern void ip_rt_init(void);
extern void ip_rt_redirect(u32 old_gw, u32 dst, u32 new_gw,
diff --git a/include/net/snmp.h b/include/net/snmp.h
index 4469fdcd1..5105fd220 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -182,7 +182,24 @@ struct linux_mib
unsigned long OfoPruned;
unsigned long OutOfWindowIcmps;
unsigned long LockDroppedIcmps;
- unsigned long __pad[32-9];
+ unsigned long TimeWaited;
+ unsigned long TimeWaitRecycled;
+ unsigned long TimeWaitKilled;
+ unsigned long PAWSPassiveRejected;
+ unsigned long PAWSActiveRejected;
+ unsigned long PAWSEstabRejected;
+ unsigned long DelayedACKs;
+ unsigned long DelayedACKLocked;
+ unsigned long DelayedACKLost;
+ unsigned long ListenOverflows;
+ unsigned long ListenDrops;
+ unsigned long TCPPrequeued;
+ unsigned long TCPDirectCopyFromBacklog;
+ unsigned long TCPDirectCopyFromPrequeue;
+ unsigned long TCPPrequeueDropped;
+ unsigned long TCPHPHits;
+ unsigned long TCPHPHitsToUser;
+ unsigned long __pad[32-26];
};
#define SNMP_INC_STATS(mib, field) ((mib)[2*smp_processor_id()+!in_interrupt()].field++)
diff --git a/include/net/sock.h b/include/net/sock.h
index 5aa0172c2..5dc9f5be3 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -96,7 +96,6 @@ struct atm_vcc;
#include <asm/atomic.h>
#include <net/dst.h>
-#define MIN_WRITE_SPACE 2048
/* The AF_UNIX specific socket options */
struct unix_opt {
@@ -229,41 +228,66 @@ struct tcp_opt {
__u32 snd_nxt; /* Next sequence we send */
__u32 snd_una; /* First byte we want an ack for */
- __u32 rcv_tstamp; /* timestamp of last received packet */
- __u32 lrcvtime; /* timestamp of last received data packet*/
- __u32 srtt; /* smothed round trip time << 3 */
+ __u32 snd_sml; /* Last byte of the most recently transmitted small packet */
+ __u32 rcv_tstamp; /* timestamp of last received ACK (for keepalives) */
+ __u32 lsndtime; /* timestamp of last sent data packet (for restart window) */
- __u32 ato; /* delayed ack timeout */
- __u32 snd_wl1; /* Sequence for window update */
+ /* Delayed ACK control data */
+ struct {
+ __u8 pending; /* ACK is pending */
+ __u8 quick; /* Scheduled number of quick acks */
+ __u8 pingpong; /* The session is interactive */
+ __u8 blocked; /* Delayed ACK was blocked by socket lock*/
+ __u32 ato; /* Predicted tick of soft clock */
+ __u32 lrcvtime; /* timestamp of last received data packet*/
+ __u16 last_seg_size; /* Size of last incoming segment */
+ __u16 rcv_mss; /* MSS used for delayed ACK decisions */
+ } ack;
+
+ /* Data for direct copy to user */
+ struct {
+ struct sk_buff_head prequeue;
+ int memory;
+ struct task_struct *task;
+ struct iovec *iov;
+ int len;
+ } ucopy;
+ __u32 snd_wl1; /* Sequence for window update */
__u32 snd_wl2; /* Ack sequence for update */
__u32 snd_wnd; /* The window we expect to receive */
- __u32 max_window;
+ __u32 max_window; /* Maximal window ever seen from peer */
__u32 pmtu_cookie; /* Last pmtu seen by socket */
__u16 mss_cache; /* Cached effective mss, not including SACKS */
__u16 mss_clamp; /* Maximal mss, negotiated at connection setup */
- __u16 ext_header_len; /* Dave, do you allow mw to use this hole? 8) --ANK */
- __u8 pending; /* pending events */
+ __u16 ext_header_len; /* Network protocol overhead (IP/IPv6 options) */
+ __u8 dup_acks; /* Consequetive duplicate acks seen from other end */
__u8 retransmits;
- __u32 last_ack_sent; /* last ack we sent */
- __u32 backoff; /* backoff */
+ __u16 __empty1;
+ __u8 defer_accept;
+
+/* RTT measurement */
+ __u8 backoff; /* backoff */
+ __u32 srtt; /* smothed round trip time << 3 */
__u32 mdev; /* medium deviation */
- __u32 snd_cwnd; /* Sending congestion window */
__u32 rto; /* retransmit timeout */
__u32 packets_out; /* Packets which are "in flight" */
__u32 fackets_out; /* Non-retrans SACK'd packets */
__u32 retrans_out; /* Fast-retransmitted packets out */
__u32 high_seq; /* snd_nxt at onset of congestion */
+
/*
* Slow start and congestion control (see also Nagle, and Karn & Partridge)
*/
__u32 snd_ssthresh; /* Slow start size threshold */
+ __u32 snd_cwnd; /* Sending congestion window */
__u16 snd_cwnd_cnt; /* Linear increase counter */
__u16 snd_cwnd_clamp; /* Do not allow snd_cwnd to grow above this */
- __u8 dup_acks; /* Consequetive duplicate acks seen from other end */
- __u8 delayed_acks;
+
+ __u8 nonagle; /* Disable Nagle algorithm? */
+ __u8 syn_retries; /* num of allowed syn retries */
__u16 user_mss; /* mss requested by user in ioctl */
/* Two commonly used timers in both sender and receiver paths. */
@@ -294,34 +318,49 @@ struct tcp_opt {
__u8 snd_wscale; /* Window scaling received from sender */
__u8 rcv_wscale; /* Window scaling to send to receiver */
__u8 rexmt_done; /* Retransmitted up to send head? */
+ __u8 keepalive_probes; /* num of allowed keep alive probes */
+
+/* PAWS/RTTM data */
__u32 rcv_tsval; /* Time stamp value */
__u32 rcv_tsecr; /* Time stamp echo reply */
__u32 ts_recent; /* Time stamp to echo next */
long ts_recent_stamp;/* Time we stored ts_recent (for aging) */
- int num_sacks; /* Number of SACK blocks */
+ __u32 last_ack_sent; /* last ack we sent (RTTM/PAWS) */
+
+/* SACKs data */
struct tcp_sack_block selective_acks[4]; /* The SACKS themselves*/
struct timer_list probe_timer; /* Probes */
- __u32 window_clamp; /* XXX Document this... -DaveM */
- __u32 probes_out; /* unanswered 0 window probes */
+ __u32 window_clamp; /* Maximal window to advertise */
+ __u8 probes_out; /* unanswered 0 window probes */
+ __u8 num_sacks; /* Number of SACK blocks */
+ __u16 advmss; /* Advertised MSS */
+
+ __u32 syn_stamp;
__u32 syn_seq;
__u32 fin_seq;
__u32 urg_seq;
__u32 urg_data;
- __u32 last_seg_size; /* Size of last incoming segment */
- __u32 rcv_mss; /* MSS used for delayed ACK decisions */
+ /* The syn_wait_lock is necessary only to avoid tcp_get_info having
+ * to grab the main lock sock while browsing the listening hash
+ * (otherwise it's deadlock prone).
+ * This lock is acquired in read mode only from tcp_get_info() and
+ * it's acquired in write mode _only_ from code that is actively
+ * changing the syn_wait_queue. All readers that are holding
+ * the master sock lock don't need to grab this lock in read mode
+ * too as the syn_wait_queue writes are always protected from
+ * the main sock lock.
+ */
+ rwlock_t syn_wait_lock;
+ struct tcp_listen_opt *listen_opt;
+ struct open_request *accept_queue; /* Established children */
- struct open_request *syn_wait_queue;
- struct open_request **syn_wait_last;
+ int write_pending; /* A write to socket waits to start. */
- int syn_backlog; /* Backlog of received SYNs */
- int write_pending;
-
unsigned int keepalive_time; /* time before keep alive takes place */
unsigned int keepalive_intvl; /* time interval between keep alive probes */
- unsigned char keepalive_probes; /* num of allowed keep alive probes */
- unsigned char syn_retries; /* num of allowed syn retries */
+ int linger2;
};
@@ -411,7 +450,7 @@ struct sock {
unsigned short family; /* Address family */
unsigned char reuse, /* SO_REUSEADDR setting */
- nonagle; /* Disable Nagle algorithm? */
+ __unused;
atomic_t refcnt; /* Reference count */
socket_lock_t lock; /* Synchronizer... */
@@ -498,6 +537,9 @@ struct sock {
unsigned char localroute; /* Route locally only */
unsigned char protocol;
struct ucred peercred;
+ int rcvlowat;
+ long rcvtimeo;
+ long sndtimeo;
#ifdef CONFIG_FILTER
/* Socket Filtering Instructions */
@@ -557,7 +599,7 @@ struct sock {
struct timer_list timer; /* This is the sock cleanup timer. */
struct timeval stamp;
- /* Identd */
+ /* Identd and reporting IO signals */
struct socket *socket;
/* RPC layer private data */
@@ -599,12 +641,6 @@ struct proto {
int (*disconnect)(struct sock *sk, int flags);
struct sock * (*accept) (struct sock *sk, int flags, int *err);
- void (*retransmit)(struct sock *sk, int all);
- void (*write_wakeup)(struct sock *sk);
- void (*read_wakeup)(struct sock *sk);
-
- unsigned int (*poll)(struct file * file, struct socket *sock,
- struct poll_table_struct *wait);
int (*ioctl)(struct sock *sk, int cmd,
unsigned long arg);
@@ -632,8 +668,6 @@ struct proto {
void (*unhash)(struct sock *sk);
int (*get_port)(struct sock *sk, unsigned short snum);
- unsigned short max_header;
- unsigned long retransmits;
char name[32];
struct {
@@ -672,6 +706,9 @@ static void __inline__ sock_prot_dec_use(struct proto *prot)
* While locked, BH processing will add new packets to
* the backlog queue. This queue is processed by the
* owner of the socket lock right before it is released.
+ *
+ * Since ~2.3.5 it is also exclusive sleep lock serializing
+ * accesses from user process context.
*/
extern void __lock_sock(struct sock *sk);
extern void __release_sock(struct sock *sk);
@@ -682,11 +719,12 @@ do { spin_lock_bh(&((__sk)->lock.slock)); \
(__sk)->lock.users = 1; \
spin_unlock_bh(&((__sk)->lock.slock)); \
} while(0)
+
#define release_sock(__sk) \
do { spin_lock_bh(&((__sk)->lock.slock)); \
- (__sk)->lock.users = 0; \
if ((__sk)->backlog.tail != NULL) \
__release_sock(__sk); \
+ (__sk)->lock.users = 0; \
wake_up(&((__sk)->lock.wq)); \
spin_unlock_bh(&((__sk)->lock.slock)); \
} while(0)
@@ -788,9 +826,6 @@ extern int sock_no_mmap(struct file *file,
* Default socket callbacks and setup code
*/
-extern void sock_def_callback1(struct sock *);
-extern void sock_def_callback2(struct sock *, int);
-extern void sock_def_callback3(struct sock *);
extern void sock_def_destruct(struct sock *);
/* Initialise core socket variables */
@@ -888,6 +923,34 @@ extern __inline__ void sock_put(struct sock *sk)
sk_free(sk);
}
+/* Detach socket from process context.
+ * Announce socket dead, detach it from wait queue and inode.
+ * Note that parent inode held reference count on this struct sock,
+ * we do not release it in this function, because protocol
+ * probably wants some additional cleanups or even continuing
+ * to work with this socket (TCP).
+ *
+ * NOTE: When softnet goes in replace _irq with _bh!
+ */
+extern __inline__ void sock_orphan(struct sock *sk)
+{
+ write_lock_irq(&sk->callback_lock);
+ sk->dead = 1;
+ sk->socket = NULL;
+ sk->sleep = NULL;
+ write_unlock_irq(&sk->callback_lock);
+}
+
+extern __inline__ void sock_graft(struct sock *sk, struct socket *parent)
+{
+ write_lock_irq(&sk->callback_lock);
+ sk->sleep = &parent->wait;
+ parent->sk = sk;
+ sk->socket = parent;
+ write_unlock_irq(&sk->callback_lock);
+}
+
+
extern __inline__ struct dst_entry *
__sk_dst_get(struct sock *sk)
{
@@ -1071,13 +1134,18 @@ extern __inline__ unsigned long sock_wspace(struct sock *sk)
return amt;
}
+#define SOCK_MIN_SNDBUF 2048
+#define SOCK_MIN_RCVBUF 128
+/* Must be less or equal SOCK_MIN_SNDBUF */
+#define SOCK_MIN_WRITE_SPACE SOCK_MIN_SNDBUF
+
/*
* Default write policy as shown to user space via poll/select/SIGIO
* Kernel internally doesn't use the MIN_WRITE_SPACE threshold.
*/
extern __inline__ int sock_writeable(struct sock *sk)
{
- return sock_wspace(sk) >= MIN_WRITE_SPACE;
+ return sock_wspace(sk) >= SOCK_MIN_WRITE_SPACE;
}
extern __inline__ int gfp_any(void)
@@ -1085,6 +1153,20 @@ extern __inline__ int gfp_any(void)
return in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
}
+extern __inline__ long sock_rcvtimeo(struct sock *sk, int noblock)
+{
+ return noblock ? 0 : sk->rcvtimeo;
+}
+
+extern __inline__ long sock_sndtimeo(struct sock *sk, int noblock)
+{
+ return noblock ? 0 : sk->sndtimeo;
+}
+
+extern __inline__ int sock_rcvlowat(struct sock *sk, int waitall, int len)
+{
+ return waitall ? len : min(sk->rcvlowat, len);
+}
/*
* Enable debug/info messages
@@ -1117,4 +1199,7 @@ extern __inline__ int gfp_any(void)
lock_sock(sk); \
}
+extern __u32 sysctl_wmem_max;
+extern __u32 sysctl_rmem_max;
+
#endif /* _SOCK_H */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index ef7da5368..1892cb30d 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -19,6 +19,7 @@
#define _TCP_H
#define TCP_DEBUG 1
+#undef TCP_FORMAL_WINDOW
#include <linux/config.h>
#include <linux/tcp.h>
@@ -130,27 +131,27 @@ struct tcp_tw_bucket {
struct sock *bind_next;
struct sock **bind_pprev;
unsigned char state,
- zapped;
+ substate; /* "zapped" is replaced with "substate" */
__u16 sport;
unsigned short family;
unsigned char reuse,
- nonagle;
+ rcv_wscale; /* It is also TW bucket specific */
atomic_t refcnt;
/* And these are ours. */
int hashent;
+ int timeout;
__u32 rcv_nxt;
__u32 snd_nxt;
+ __u32 rcv_wnd;
+ __u32 syn_seq;
__u32 ts_recent;
long ts_recent_stamp;
+ unsigned long ttd;
struct tcp_bind_bucket *tb;
struct tcp_tw_bucket *next_death;
struct tcp_tw_bucket **pprev_death;
- int death_slot;
-#ifdef CONFIG_TCP_TW_RECYCLE
- unsigned long ttd;
- int rto;
-#endif
+
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
struct in6_addr v6_daddr;
struct in6_addr v6_rcv_saddr;
@@ -169,10 +170,11 @@ extern __inline__ void tcp_tw_put(struct tcp_tw_bucket *tw)
}
}
-extern int tcp_tw_death_row_slot;
+extern atomic_t tcp_orphan_count;
+extern int tcp_tw_count;
+extern void tcp_time_wait(struct sock *sk, int state, int timeo);
extern void tcp_timewait_kill(struct tcp_tw_bucket *tw);
-extern void tcp_tw_schedule(struct tcp_tw_bucket *tw);
-extern void tcp_tw_reschedule(struct tcp_tw_bucket *tw);
+extern void tcp_tw_schedule(struct tcp_tw_bucket *tw, int timeo);
extern void tcp_tw_deschedule(struct tcp_tw_bucket *tw);
@@ -224,67 +226,81 @@ static __inline__ int tcp_sk_listen_hashfn(struct sock *sk)
return tcp_lhashfn(sk->num);
}
-/* Note, that it is > than ipv6 header */
-#define NETHDR_SIZE (sizeof(struct iphdr) + 40)
-
-/*
- * 40 is maximal IP options size
- * 20 is the maximum TCP options size we can currently construct on a SYN.
- * 40 is the maximum possible TCP options size.
- */
-
-#define MAX_SYN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + 20 + MAX_HEADER + 15)
-#define MAX_FIN_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15)
-#define BASE_ACK_SIZE (NETHDR_SIZE + MAX_HEADER + 15)
-#define MAX_ACK_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15)
-#define MAX_RESET_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + MAX_HEADER + 15)
-#define MAX_TCPHEADER_SIZE (NETHDR_SIZE + sizeof(struct tcphdr) + 20 + MAX_HEADER + 15)
+#define MAX_TCP_HEADER (128 + MAX_HEADER)
/*
* Never offer a window over 32767 without using window scaling. Some
* poor stacks do signed 16bit maths!
*/
-#define MAX_WINDOW 32767
-#define MAX_DELAY_ACK 2
+#define MAX_TCP_WINDOW 32767
+
+/* Minimal accepted MSS. It is (60+60+8) - (20+20). */
+#define TCP_MIN_MSS 88
+
+/* Minimal RCV_MSS. */
+#define TCP_MIN_RCVMSS 536
/*
* How much of the receive buffer do we advertize
* (the rest is reserved for headers and driver packet overhead)
* Use a power of 2.
*/
-#define WINDOW_ADVERTISE_DIVISOR 2
+#define TCP_WINDOW_ADVERTISE_DIVISOR 2
/* urg_data states */
-#define URG_VALID 0x0100
-#define URG_NOTYET 0x0200
-#define URG_READ 0x0400
+#define TCP_URG_VALID 0x0100
+#define TCP_URG_NOTYET 0x0200
+#define TCP_URG_READ 0x0400
-#define TCP_RETR1 7 /*
+#define TCP_RETR1 3 /*
* This is how many retries it does before it
* tries to figure out if the gateway is
- * down.
+ * down. Minimal RFC value is 3; it corresponds
+ * to ~3sec-8min depending on RTO.
*/
#define TCP_RETR2 15 /*
* This should take at least
* 90 minutes to time out.
+ * RFC1122 says that the limit is 100 sec.
+ * 15 is ~13-30min depending on RTO.
+ */
+
+#define TCP_SYN_RETRIES 5 /* number of times to retry active opening a
+ * connection: ~180sec is RFC minumum */
+
+#define TCP_SYNACK_RETRIES 5 /* number of times to retry passive opening a
+ * connection: ~180sec is RFC minumum */
+
+
+#define TCP_ORPHAN_RETRIES 7 /* number of times to retry on an orphaned
+ * socket. 7 is ~50sec-16min.
*/
-#define TCP_TIMEOUT_LEN (15*60*HZ) /* should be about 15 mins */
-#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to successfully
- * close the socket, about 60 seconds */
-#define TCP_FIN_TIMEOUT (3*60*HZ) /* BSD style FIN_WAIT2 deadlock breaker */
-
-#define TCP_ACK_TIME (3*HZ) /* time to delay before sending an ACK */
-#define TCP_WRITE_TIME (30*HZ) /* initial time to wait for an ACK,
- * after last transmit */
-#define TCP_TIMEOUT_INIT (3*HZ) /* RFC 1122 initial timeout value */
-#define TCP_SYN_RETRIES 10 /* number of times to retry opening a
- * connection (TCP_RETR2-....) */
-#define TCP_PROBEWAIT_LEN (1*HZ)/* time to wait between probes when
- * I've got something to write and
- * there is no window */
-#define TCP_KEEPALIVE_TIME (120*60*HZ) /* two hours */
+
+#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT
+ * state, about 60 seconds */
+#define TCP_FIN_TIMEOUT TCP_TIMEWAIT_LEN
+ /* BSD style FIN_WAIT2 deadlock breaker.
+ * It used to be 3min, new value is 60sec,
+ * to combine FIN-WAIT-2 timeout with
+ * TIME-WAIT timer.
+ */
+
+#define TCP_DELACK_MAX (HZ/2) /* maximal time to delay before sending an ACK */
+#define TCP_DELACK_MIN (2) /* minimal time to delay before sending an ACK,
+ * 2 scheduler ticks, not depending on HZ */
+#define TCP_ATO_MAX ((TCP_DELACK_MAX*4)/5) /* ATO producing TCP_DELACK_MAX */
+#define TCP_ATO_MIN 2
+#define TCP_RTO_MAX (120*HZ)
+#define TCP_RTO_MIN (HZ/5)
+#define TCP_TIMEOUT_INIT (3*HZ) /* RFC 1122 initial RTO value */
+
+#define TCP_RESOURCE_PROBE_INTERVAL (HZ/2) /* Maximal interval between probes
+ * for local resources.
+ */
+
+#define TCP_KEEPALIVE_TIME (120*60*HZ) /* two hours */
#define TCP_KEEPALIVE_PROBES 9 /* Max of 9 keepalive probes */
#define TCP_KEEPALIVE_INTVL (75*HZ)
@@ -293,14 +309,39 @@ static __inline__ int tcp_sk_listen_hashfn(struct sock *sk)
#define MAX_TCP_KEEPCNT 127
#define MAX_TCP_SYNCNT 127
-#define TCP_SYNACK_PERIOD (HZ/2) /* How often to run the synack slow timer */
-#define TCP_QUICK_TRIES 8 /* How often we try to retransmit, until
- * we tell the link layer that it is something
- * wrong (e.g. that it can expire redirects) */
-
/* TIME_WAIT reaping mechanism. */
#define TCP_TWKILL_SLOTS 8 /* Please keep this a power of 2. */
-#define TCP_TWKILL_PERIOD ((HZ*60)/TCP_TWKILL_SLOTS)
+#define TCP_TWKILL_PERIOD (TCP_TIMEWAIT_LEN/TCP_TWKILL_SLOTS)
+
+#define TCP_SYNQ_INTERVAL (HZ/5) /* Period of SYNACK timer */
+#define TCP_SYNQ_HSIZE 64 /* Size of SYNACK hash table */
+
+#define TCP_PAWS_24DAYS (60 * 60 * 24 * 24)
+#define TCP_PAWS_MSL 60 /* Per-host timestamps are invalidated
+ * after this time. It should be equal
+ * (or greater than) TCP_TIMEWAIT_LEN
+ * to provide reliability equal to one
+ * provided by timewait state.
+ */
+#define TCP_PAWS_WINDOW 1 /* Replay window for per-host
+ * timestamps. It must be less than
+ * minimal timewait lifetime.
+ */
+
+#define TCP_TW_RECYCLE_SLOTS_LOG 5
+#define TCP_TW_RECYCLE_SLOTS (1<<TCP_TW_RECYCLE_SLOTS_LOG)
+
+/* If time > 4sec, it is "slow" path, no recycling is required,
+ so that we select tick to get range about 4 seconds.
+ */
+
+#if HZ == 100
+#define TCP_TW_RECYCLE_TICK (7+2-TCP_TW_RECYCLE_SLOTS_LOG)
+#elif HZ == 1024
+#define TCP_TW_RECYCLE_TICK (10+2-TCP_TW_RECYCLE_SLOTS_LOG)
+#else
+#error HZ != 100 && HZ != 1024.
+#endif
/*
* TCP option
@@ -331,23 +372,40 @@ static __inline__ int tcp_sk_listen_hashfn(struct sock *sk)
#define TCPOLEN_SACK_BASE_ALIGNED 4
#define TCPOLEN_SACK_PERBLOCK 8
-#define TIME_WRITE 1 /* Not yet used */
-#define TIME_RETRANS 2 /* Retransmit timer */
-#define TIME_DACK 3 /* Delayed ack timer */
-#define TIME_PROBE0 4
-#define TIME_KEEPOPEN 5
+#define TCP_TIME_RETRANS 1 /* Retransmit timer */
+#define TCP_TIME_DACK 2 /* Delayed ack timer */
+#define TCP_TIME_PROBE0 3 /* Zero window probe timer */
+#define TCP_TIME_KEEPOPEN 4 /* Keepalive timer */
/* sysctl variables for tcp */
+extern int sysctl_max_syn_backlog;
+extern int sysctl_tcp_timestamps;
+extern int sysctl_tcp_window_scaling;
+extern int sysctl_tcp_sack;
+extern int sysctl_tcp_fin_timeout;
+extern int sysctl_tcp_tw_recycle;
extern int sysctl_tcp_keepalive_time;
extern int sysctl_tcp_keepalive_probes;
extern int sysctl_tcp_keepalive_intvl;
extern int sysctl_tcp_syn_retries;
+extern int sysctl_tcp_synack_retries;
+extern int sysctl_tcp_retries1;
+extern int sysctl_tcp_retries2;
+extern int sysctl_tcp_orphan_retries;
+extern int sysctl_tcp_syncookies;
+extern int sysctl_tcp_retrans_collapse;
+extern int sysctl_tcp_stdurg;
+extern int sysctl_tcp_rfc1337;
+extern int sysctl_tcp_tw_recycle;
+extern int sysctl_tcp_abort_on_overflow;
+extern int sysctl_tcp_max_orphans;
+extern int sysctl_tcp_max_tw_buckets;
struct open_request;
struct or_calltable {
int family;
- void (*rtx_syn_ack) (struct sock *sk, struct open_request *req);
+ int (*rtx_syn_ack) (struct sock *sk, struct open_request *req, struct dst_entry*);
void (*send_ack) (struct sk_buff *skb, struct open_request *req);
void (*destructor) (struct open_request *req);
void (*send_reset) (struct sk_buff *skb);
@@ -376,12 +434,14 @@ struct open_request {
__u16 rmt_port;
__u16 mss;
__u8 retrans;
- __u8 __pad;
- unsigned snd_wscale : 4,
+ __u8 index;
+ __u16 snd_wscale : 4,
rcv_wscale : 4,
tstamp_ok : 1,
sack_ok : 1,
- wscale_ok : 1;
+ wscale_ok : 1,
+ ecn_ok : 1,
+ acked : 1;
/* The following two fields can be easily recomputed I think -AK */
__u32 window_clamp; /* window clamp at creation time */
__u32 rcv_wnd; /* rcv_wnd offered first time */
@@ -400,8 +460,14 @@ struct open_request {
/* SLAB cache for open requests. */
extern kmem_cache_t *tcp_openreq_cachep;
-#define tcp_openreq_alloc() kmem_cache_alloc(tcp_openreq_cachep, SLAB_ATOMIC)
-#define tcp_openreq_free(req) kmem_cache_free(tcp_openreq_cachep, req)
+#define tcp_openreq_alloc() kmem_cache_alloc(tcp_openreq_cachep, SLAB_ATOMIC)
+#define tcp_openreq_fastfree(req) kmem_cache_free(tcp_openreq_cachep, req)
+
+extern __inline__ void tcp_openreq_free(struct open_request *req)
+{
+ req->class->destructor(req);
+ tcp_openreq_fastfree(req);
+}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#define TCP_INET_FAMILY(fam) ((fam) == AF_INET)
@@ -441,9 +507,9 @@ struct tcp_func {
int (*hash_connecting) (struct sock *sk);
- __u16 net_header_len;
-
+ int (*remember_stamp) (struct sock *sk);
+ __u16 net_header_len;
int (*setsockopt) (struct sock *sk,
int level,
@@ -506,7 +572,11 @@ extern void tcp_shutdown (struct sock *sk, int how);
extern int tcp_v4_rcv(struct sk_buff *skb,
unsigned short len);
-extern int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg);
+extern int tcp_v4_remember_stamp(struct sock *sk);
+
+extern int tcp_v4_tw_remember_stamp(struct tcp_tw_bucket *tw);
+
+extern int tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size);
extern int tcp_ioctl(struct sock *sk,
int cmd,
@@ -522,6 +592,23 @@ extern int tcp_rcv_established(struct sock *sk,
struct tcphdr *th,
unsigned len);
+static __inline__ void tcp_dec_quickack_mode(struct tcp_opt *tp)
+{
+ if (tp->ack.quick && --tp->ack.quick == 0 && !tp->ack.pingpong) {
+ /* Leaving quickack mode we deflate ATO to give peer
+ * a time to adapt to new worse(!) RTO. It is not required
+ * in pingpong mode, when ACKs were delayed in any case.
+ */
+ tp->ack.ato = TCP_ATO_MIN;
+ }
+}
+
+static __inline__ void tcp_delack_init(struct tcp_opt *tp)
+{
+ memset(&tp->ack, 0, sizeof(tp->ack));
+}
+
+
enum tcp_tw_status
{
TCP_TW_SUCCESS = 0,
@@ -530,6 +617,7 @@ enum tcp_tw_status
TCP_TW_SYN = 3
};
+
extern enum tcp_tw_status tcp_timewait_state_process(struct tcp_tw_bucket *tw,
struct sk_buff *skb,
struct tcphdr *th,
@@ -537,7 +625,10 @@ extern enum tcp_tw_status tcp_timewait_state_process(struct tcp_tw_bucket *tw,
extern struct sock * tcp_check_req(struct sock *sk,struct sk_buff *skb,
struct open_request *req,
- struct open_request *prev);
+ struct open_request **prev);
+extern int tcp_child_process(struct sock *parent,
+ struct sock *child,
+ struct sk_buff *skb);
extern void tcp_close(struct sock *sk,
long timeout);
@@ -557,6 +648,8 @@ extern int tcp_recvmsg(struct sock *sk,
int len, int nonblock,
int flags, int *addr_len);
+extern int tcp_listen_start(struct sock *sk);
+
extern void tcp_parse_options(struct sock *sk, struct tcphdr *th,
struct tcp_opt *tp, int no_fancy);
@@ -614,9 +707,7 @@ extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb,
/* tcp_output.c */
-extern void tcp_read_wakeup(struct sock *);
-extern void tcp_write_xmit(struct sock *);
-extern void tcp_time_wait(struct sock *);
+extern int tcp_write_xmit(struct sock *);
extern int tcp_retransmit_skb(struct sock *, struct sk_buff *);
extern void tcp_fack_retransmit(struct sock *);
extern void tcp_xmit_retransmit_queue(struct sock *);
@@ -624,46 +715,22 @@ extern void tcp_simple_retransmit(struct sock *);
extern void tcp_send_probe0(struct sock *);
extern void tcp_send_partial(struct sock *);
-extern void tcp_write_wakeup(struct sock *);
+extern int tcp_write_wakeup(struct sock *);
extern void tcp_send_fin(struct sock *sk);
extern void tcp_send_active_reset(struct sock *sk, int priority);
extern int tcp_send_synack(struct sock *);
-extern void tcp_transmit_skb(struct sock *, struct sk_buff *);
-extern void tcp_send_skb(struct sock *, struct sk_buff *, int force_queue);
+extern int tcp_transmit_skb(struct sock *, struct sk_buff *);
+extern void tcp_send_skb(struct sock *, struct sk_buff *, int force_queue, unsigned mss_now);
extern void tcp_send_ack(struct sock *sk);
-extern void tcp_send_delayed_ack(struct sock *sk, int max_timeout);
+extern void tcp_send_delayed_ack(struct sock *sk);
/* tcp_timer.c */
extern void tcp_reset_xmit_timer(struct sock *, int, unsigned long);
extern void tcp_init_xmit_timers(struct sock *);
extern void tcp_clear_xmit_timers(struct sock *);
-extern void tcp_retransmit_timer(unsigned long);
-extern void tcp_delack_timer(unsigned long);
-extern void tcp_probe_timer(unsigned long);
-
extern void tcp_delete_keepalive_timer (struct sock *);
extern void tcp_reset_keepalive_timer (struct sock *, unsigned long);
-extern void tcp_keepalive_timer (unsigned long);
-
-/*
- * TCP slow timer
- */
-extern struct timer_list tcp_slow_timer;
-
-struct tcp_sl_timer {
- atomic_t count;
- unsigned long period;
- unsigned long last;
- void (*handler) (unsigned long);
-};
-
-#define TCP_SLT_SYNACK 0
-#define TCP_SLT_TWKILL 1
-#define TCP_SLT_MAX 2
-
-extern struct tcp_sl_timer tcp_slt_array[TCP_SLT_MAX];
-
extern int tcp_sync_mss(struct sock *sk, u32 pmtu);
/* Compute the current effective MSS, taking SACKs and IP options,
@@ -673,7 +740,7 @@ extern int tcp_sync_mss(struct sock *sk, u32 pmtu);
static __inline__ unsigned int tcp_current_mss(struct sock *sk)
{
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
- struct dst_entry *dst = sk->dst_cache;
+ struct dst_entry *dst = __sk_dst_get(sk);
int mss_now = tp->mss_cache;
if (dst && dst->pmtu != tp->pmtu_cookie)
@@ -682,7 +749,7 @@ static __inline__ unsigned int tcp_current_mss(struct sock *sk)
if(tp->sack_ok && tp->num_sacks)
mss_now -= (TCPOLEN_SACK_BASE_ALIGNED +
(tp->num_sacks * TCPOLEN_SACK_PERBLOCK));
- return mss_now > 8 ? mss_now : 8;
+ return mss_now;
}
/* Initialize RCV_MSS value.
@@ -704,9 +771,24 @@ extern __inline__ void tcp_initialize_rcv_mss(struct sock *sk)
else
mss = tp->mss_cache;
- tp->rcv_mss = max(min(mss, 536), 8);
+ tp->ack.rcv_mss = max(min(mss, TCP_MIN_RCVMSS), TCP_MIN_MSS);
+}
+
+static __inline__ void __tcp_fast_path_on(struct tcp_opt *tp, u32 snd_wnd)
+{
+ tp->pred_flags = htonl((tp->tcp_header_len << 26) |
+ ntohl(TCP_FLAG_ACK) |
+ snd_wnd);
+}
+
+static __inline__ void tcp_fast_path_on(struct tcp_opt *tp)
+{
+ __tcp_fast_path_on(tp, tp->snd_wnd>>tp->snd_wscale);
}
+
+
+
/* Compute the actual receive window we are currently advertising.
* Rcv_nxt can be after the window if our peer push more data
* than the offered window.
@@ -751,23 +833,26 @@ extern __inline__ u16 tcp_select_window(struct sock *sk)
}
/* RFC1323 scaling applied */
- return new_win >> tp->rcv_wscale;
-}
-
-/* See if we can advertise non-zero, and if so how much we
- * can increase our advertisement. If it becomes more than
- * twice what we are talking about right now, return true.
- */
-extern __inline__ int tcp_raise_window(struct sock *sk)
-{
- struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
- u32 cur_win = tcp_receive_window(tp);
- u32 new_win = __tcp_select_window(sk);
+ new_win >>= tp->rcv_wscale;
+
+#ifdef TCP_FORMAL_WINDOW
+ if (new_win == 0) {
+ /* If we advertise zero window, disable fast path. */
+ tp->pred_flags = 0;
+ } else if (cur_win == 0 && tp->pred_flags == 0 &&
+ skb_queue_len(&tp->out_of_order_queue) == 0 &&
+ !tp->urg_data) {
+ /* If we open zero window, enable fast path.
+ Without this it will be open by the first data packet,
+ it is too late to merge checksumming to copy.
+ */
+ tcp_fast_path_on(tp);
+ }
+#endif
- return (new_win && (new_win > (cur_win << 1)));
+ return new_win;
}
-
/* TCP timestamps are only 32-bits, this causes a slight
* complication on 64-bit systems since we store a snapshot
* of jiffies in the buffer control blocks below. We decidely
@@ -804,6 +889,8 @@ struct tcp_skb_cb {
#define TCPCB_FLAG_PSH 0x08
#define TCPCB_FLAG_ACK 0x10
#define TCPCB_FLAG_URG 0x20
+#define TCPCB_FLAG_ECE 0x40
+#define TCPCB_FLAG_CWR 0x80
__u8 sacked; /* State flags for SACK/FACK. */
#define TCPCB_SACKED_ACKED 0x01 /* SKB ACK'd by a SACK block */
@@ -860,13 +947,91 @@ extern __inline__ __u32 tcp_recalc_ssthresh(struct tcp_opt *tp)
return max(min(FlightSize, tp->snd_cwnd) >> 1, 2);
}
+/* Set slow start threshould and cwnd not falling to slow start */
+extern __inline__ void __tcp_enter_cong_avoid(struct tcp_opt *tp)
+{
+ tp->snd_ssthresh = tcp_recalc_ssthresh(tp);
+ if (tp->snd_ssthresh > tp->snd_cwnd_clamp)
+ tp->snd_ssthresh = tp->snd_cwnd_clamp;
+ tp->snd_cwnd = tp->snd_ssthresh;
+ tp->snd_cwnd_cnt = 0;
+ tp->high_seq = tp->snd_nxt;
+}
+
+extern __inline__ void tcp_enter_cong_avoid(struct tcp_opt *tp)
+{
+ if (!tp->high_seq || after(tp->snd_nxt, tp->high_seq))
+ __tcp_enter_cong_avoid(tp);
+}
+
+
+/* Increase initial CWND conservatively, i.e. only if estimated
+ RTT is low enough. It is not quite correct, we should use
+ POWER i.e. RTT*BANDWIDTH, but we still cannot estimate this.
+
+ Numbers are taken from RFC1414.
+ */
+static __inline__ __u32 tcp_init_cwnd(struct tcp_opt *tp)
+{
+ __u32 cwnd;
+
+ if (!tp->srtt || tp->srtt > ((HZ/50)<<3) || tp->mss_cache > 1460)
+ cwnd = 2;
+ else if (tp->mss_cache > 1095)
+ cwnd = 3;
+ else
+ cwnd = 4;
+
+ return min(cwnd, tp->snd_cwnd_clamp);
+}
+
+
+static __inline__ int tcp_minshall_check(struct tcp_opt *tp)
+{
+ return after(tp->snd_sml,tp->snd_una) &&
+ !after(tp->snd_sml, tp->snd_nxt);
+}
+
+static __inline__ void tcp_minshall_update(struct tcp_opt *tp, int mss, int len)
+{
+ if (len < mss)
+ tp->snd_sml = tp->snd_nxt;
+}
+
+/* Return 0, if packet can be sent now without violation Nagle's rules:
+ 1. It is full sized.
+ 2. Or it contains FIN or URG.
+ 3. Or TCP_NODELAY was set.
+ 4. Or TCP_CORK is not set, and all sent packets are ACKed.
+ With Minshall's modification: all sent small packets are ACKed.
+ */
+
+static __inline__ int tcp_nagle_check(struct tcp_opt *tp, struct sk_buff *skb, unsigned mss_now)
+{
+ return (skb->len < mss_now &&
+ !(TCP_SKB_CB(skb)->flags & (TCPCB_FLAG_URG|TCPCB_FLAG_FIN)) &&
+ (tp->nonagle == 2 ||
+ (!tp->nonagle &&
+ tp->packets_out &&
+ tcp_minshall_check(tp))));
+}
+
/* This checks if the data bearing packet SKB (usually tp->send_head)
* should be put on the wire right now.
*/
-static __inline__ int tcp_snd_test(struct sock *sk, struct sk_buff *skb)
+static __inline__ int tcp_snd_test(struct tcp_opt *tp, struct sk_buff *skb,
+ unsigned cur_mss, int tail)
{
- struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
- int nagle_check = 1;
+ /*
+ * Reset CWND after idle period longer RTO to "restart window".
+ * It is "side" effect of the function, which is _not_ good
+ * from viewpoint of clarity. But we have to make it before
+ * checking congestion window below. Alternative is to prepend
+ * all the calls with this test.
+ */
+ if (tp->packets_out==0 &&
+ (s32)(tcp_time_stamp - tp->lsndtime) > tp->rto)
+ tp->snd_cwnd = min(tp->snd_cwnd, tcp_init_cwnd(tp));
/* RFC 1122 - section 4.2.3.4
*
@@ -876,97 +1041,126 @@ static __inline__ int tcp_snd_test(struct sock *sk, struct sk_buff *skb)
* b) There are packets in flight and we have a small segment
* [SWS avoidance and Nagle algorithm]
* (part of SWS is done on packetization)
+ * Minshall version sounds: there are no _small_
+ * segments in flight. (tcp_nagle_check)
* c) We are retransmiting [Nagle]
* d) We have too many packets 'in flight'
*
* Don't use the nagle rule for urgent data (or
* for the final FIN -DaveM).
+ *
+ * Also, Nagle rule does not apply to frames, which
+ * sit in the middle of queue (they have no chances
+ * to get new data) and if room at tail of skb is
+ * not enough to save something seriously (<32 for now).
*/
- if ((sk->nonagle == 2 && (skb->len < tp->mss_cache)) ||
- (!sk->nonagle &&
- skb->len < (tp->mss_cache >> 1) &&
- tp->packets_out &&
- !(TCP_SKB_CB(skb)->flags & (TCPCB_FLAG_URG|TCPCB_FLAG_FIN))))
- nagle_check = 0;
-
- /*
- * Reset CWND after idle period longer rto. Actually, it would
- * be better to save last send time, but VJ in SIGCOMM'88 proposes
- * to use keepalive timestamp. Well, it is not good, certainly,
- * because SMTP is still broken, but it is better than nothing yet.
- */
- if (tp->packets_out==0 && (s32)(tcp_time_stamp - tp->rcv_tstamp) > tp->rto)
- tp->snd_cwnd = min(tp->snd_cwnd, 2);
/* Don't be strict about the congestion window for the
* final FIN frame. -DaveM
*/
- return (nagle_check &&
+ return ((!tail || !tcp_nagle_check(tp, skb, cur_mss) ||
+ skb_tailroom(skb) < 32) &&
((tcp_packets_in_flight(tp) < tp->snd_cwnd) ||
(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) &&
!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) &&
tp->retransmits == 0);
}
+static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_opt *tp)
+{
+ if (!tp->packets_out && !tp->probe_timer.prev)
+ tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, tp->rto);
+}
+
+static __inline__ int tcp_skb_is_last(struct sock *sk, struct sk_buff *skb)
+{
+ return (skb->next == (struct sk_buff*)&sk->write_queue);
+}
+
/* Push out any pending frames which were held back due to
* TCP_CORK or attempt at coalescing tiny packets.
* The socket must be locked by the caller.
*/
-static __inline__ void tcp_push_pending_frames(struct sock *sk, struct tcp_opt *tp)
+static __inline__ void __tcp_push_pending_frames(struct sock *sk,
+ struct tcp_opt *tp,
+ unsigned cur_mss)
{
- if(tp->send_head) {
- if(tcp_snd_test(sk, tp->send_head))
- tcp_write_xmit(sk);
- else if(tp->packets_out == 0 && !tp->pending) {
- /* We held off on this in tcp_send_skb() */
- tp->pending = TIME_PROBE0;
- tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto);
- }
+ struct sk_buff *skb = tp->send_head;
+
+ if (skb) {
+ if (!tcp_snd_test(tp, skb, cur_mss, tcp_skb_is_last(sk, skb)) ||
+ tcp_write_xmit(sk))
+ tcp_check_probe_timer(sk, tp);
}
}
-/* This tells the input processing path that an ACK should go out
- * right now.
- */
-#define tcp_enter_quickack_mode(__tp) ((__tp)->ato |= (1<<31))
-#define tcp_exit_quickack_mode(__tp) ((__tp)->ato &= ~(1<<31))
-#define tcp_in_quickack_mode(__tp) (((__tp)->ato & (1 << 31)) != 0)
+static __inline__ void tcp_push_pending_frames(struct sock *sk,
+ struct tcp_opt *tp)
+{
+ __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk));
+}
+
+extern void tcp_destroy_sock(struct sock *sk);
+
/*
- * List all states of a TCP socket that can be viewed as a "connected"
- * state. This now includes TCP_SYN_RECV, although I am not yet fully
- * convinced that this is the solution for the 'getpeername(2)'
- * problem. Thanks to Stephen A. Wood <saw@cebaf.gov> -FvK
+ * Calculate(/check) TCP checksum
*/
+static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len,
+ unsigned long saddr, unsigned long daddr,
+ unsigned long base)
+{
+ return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base);
+}
-extern __inline const int tcp_connected(const int state)
+static __inline__ int __tcp_checksum_complete(struct sk_buff *skb)
{
- return ((1 << state) &
- (TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_FIN_WAIT1|
- TCPF_FIN_WAIT2|TCPF_SYN_RECV));
+ return (unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum));
}
-extern __inline const int tcp_established(const int state)
+static __inline__ int tcp_checksum_complete(struct sk_buff *skb)
{
- return ((1 << state) &
- (TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_FIN_WAIT1|
- TCPF_FIN_WAIT2));
+ return skb->ip_summed != CHECKSUM_UNNECESSARY &&
+ __tcp_checksum_complete(skb);
}
-extern void tcp_destroy_sock(struct sock *sk);
+/* Prequeue for VJ style copy to user, combined with checksumming. */
+static __inline__ void tcp_prequeue_init(struct tcp_opt *tp)
+{
+ tp->ucopy.task = NULL;
+ tp->ucopy.len = 0;
+ tp->ucopy.memory = 0;
+ skb_queue_head_init(&tp->ucopy.prequeue);
+}
-/*
- * Calculate(/check) TCP checksum
+/* Packet is added to VJ-style prequeue for processing in process
+ * context, if a reader task is waiting. Apparently, this exciting
+ * idea (VJ's mail "Re: query about TCP header on tcp-ip" of 07 Sep 93)
+ * failed somewhere. Latency? Burstiness? Well, at least now we will
+ * see, why it failed. 8)8) --ANK
*/
-static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len,
- unsigned long saddr, unsigned long daddr,
- unsigned long base)
+static __inline__ int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
{
- return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base);
+ struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
+
+ if (tp->ucopy.task) {
+ if ((tp->ucopy.memory += skb->truesize) <= (sk->rcvbuf<<1)) {
+ __skb_queue_tail(&tp->ucopy.prequeue, skb);
+ if (skb_queue_len(&tp->ucopy.prequeue) == 1)
+ wake_up_interruptible(sk->sleep);
+ } else {
+ NET_INC_STATS_BH(TCPPrequeueDropped);
+ tp->ucopy.memory -= skb->truesize;
+ kfree_skb(skb);
+ }
+ return 1;
+ }
+ return 0;
}
+
#undef STATE_TRACE
#ifdef STATE_TRACE
@@ -1007,9 +1201,12 @@ static __inline__ void tcp_set_state(struct sock *sk, int state)
static __inline__ void tcp_done(struct sock *sk)
{
+ tcp_set_state(sk, TCP_CLOSE);
+ tcp_clear_xmit_timers(sk);
+
sk->shutdown = SHUTDOWN_MASK;
- if (!sk->dead)
+ if (!sk->dead)
sk->state_change(sk);
else
tcp_destroy_sock(sk);
@@ -1106,7 +1303,7 @@ extern __inline__ void tcp_select_initial_window(int space, __u32 mss,
* our initial window offering to 32k. There should also
* be a sysctl option to stop being nice.
*/
- (*rcv_wnd) = min(space, MAX_WINDOW);
+ (*rcv_wnd) = min(space, MAX_TCP_WINDOW);
(*rcv_wscale) = 0;
if (wscale_ok) {
/* See RFC1323 for an explanation of the limit to 14 */
@@ -1123,52 +1320,127 @@ extern __inline__ void tcp_select_initial_window(int space, __u32 mss,
extern __inline__ int tcp_space(struct sock *sk)
{
return (sk->rcvbuf - atomic_read(&sk->rmem_alloc)) /
- WINDOW_ADVERTISE_DIVISOR;
+ TCP_WINDOW_ADVERTISE_DIVISOR;
}
extern __inline__ int tcp_full_space( struct sock *sk)
{
- return sk->rcvbuf / WINDOW_ADVERTISE_DIVISOR;
+ return sk->rcvbuf / TCP_WINDOW_ADVERTISE_DIVISOR;
}
-extern __inline__ void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req, struct open_request *prev)
+extern __inline__ void tcp_init_buffer_space(struct sock *sk)
{
- if(!req->dl_next)
- tp->syn_wait_last = (struct open_request **)prev;
- prev->dl_next = req->dl_next;
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ int rcvbuf = tp->advmss+MAX_TCP_HEADER+16+sizeof(struct sk_buff);
+ int sndbuf = tp->mss_clamp+MAX_TCP_HEADER+16+sizeof(struct sk_buff);
+
+ if (sk->rcvbuf < 3*rcvbuf)
+ sk->rcvbuf = min (3*rcvbuf, sysctl_rmem_max);
+ if (sk->sndbuf < 3*sndbuf)
+ sk->sndbuf = min (3*sndbuf, sysctl_wmem_max);
}
-extern __inline__ void tcp_synq_queue(struct tcp_opt *tp, struct open_request *req)
-{
- req->dl_next = NULL;
- *tp->syn_wait_last = req;
- tp->syn_wait_last = &req->dl_next;
+extern __inline__ void tcp_acceptq_removed(struct sock *sk)
+{
+ sk->ack_backlog--;
}
-extern __inline__ void tcp_synq_init(struct tcp_opt *tp)
+extern __inline__ void tcp_acceptq_added(struct sock *sk)
{
- tp->syn_wait_queue = NULL;
- tp->syn_wait_last = &tp->syn_wait_queue;
+ sk->ack_backlog++;
}
-extern void __tcp_inc_slow_timer(struct tcp_sl_timer *slt);
-extern __inline__ void tcp_inc_slow_timer(int timer)
+extern __inline__ int tcp_acceptq_is_full(struct sock *sk)
{
- struct tcp_sl_timer *slt = &tcp_slt_array[timer];
-
- if (atomic_read(&slt->count) == 0)
- {
- __tcp_inc_slow_timer(slt);
- }
+ return sk->ack_backlog > sk->max_ack_backlog;
+}
+
+extern __inline__ void tcp_acceptq_queue(struct sock *sk, struct open_request *req,
+ struct sock *child)
+{
+ struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
+
+ req->sk = child;
+ tcp_acceptq_added(sk);
+
+ req->dl_next = tp->accept_queue;
+ tp->accept_queue = req;
+}
+
+struct tcp_listen_opt
+{
+ u8 max_qlen_log; /* log_2 of maximal queued SYNs */
+ int qlen;
+ int qlen_young;
+ int clock_hand;
+ struct open_request *syn_table[TCP_SYNQ_HSIZE];
+};
+
+extern __inline__ void
+tcp_synq_removed(struct sock *sk, struct open_request *req)
+{
+ struct tcp_listen_opt *lopt = sk->tp_pinfo.af_tcp.listen_opt;
+
+ if (--lopt->qlen == 0)
+ tcp_delete_keepalive_timer(sk);
+ if (req->retrans == 0)
+ lopt->qlen_young--;
+}
+
+extern __inline__ void tcp_synq_added(struct sock *sk)
+{
+ struct tcp_listen_opt *lopt = sk->tp_pinfo.af_tcp.listen_opt;
+
+ if (lopt->qlen++ == 0)
+ tcp_reset_keepalive_timer(sk, TCP_TIMEOUT_INIT);
+ lopt->qlen_young++;
+}
+
+extern __inline__ int tcp_synq_len(struct sock *sk)
+{
+ return sk->tp_pinfo.af_tcp.listen_opt->qlen;
+}
+
+extern __inline__ int tcp_synq_young(struct sock *sk)
+{
+ return sk->tp_pinfo.af_tcp.listen_opt->qlen_young;
+}
- atomic_inc(&slt->count);
+extern __inline__ int tcp_synq_is_full(struct sock *sk)
+{
+ return tcp_synq_len(sk)>>sk->tp_pinfo.af_tcp.listen_opt->max_qlen_log;
}
-extern __inline__ void tcp_dec_slow_timer(int timer)
+extern __inline__ void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req,
+ struct open_request **prev)
{
- struct tcp_sl_timer *slt = &tcp_slt_array[timer];
+ write_lock(&tp->syn_wait_lock);
+ *prev = req->dl_next;
+ write_unlock(&tp->syn_wait_lock);
+}
- atomic_dec(&slt->count);
+extern __inline__ void tcp_synq_drop(struct sock *sk, struct open_request *req,
+ struct open_request **prev)
+{
+ tcp_synq_unlink(&sk->tp_pinfo.af_tcp, req, prev);
+ tcp_synq_removed(sk, req);
+ tcp_openreq_free(req);
+}
+
+static __inline__ void tcp_openreq_init(struct open_request *req,
+ struct tcp_opt *tp,
+ struct sk_buff *skb)
+{
+ req->rcv_wnd = 0; /* So that tcp_send_synack() knows! */
+ req->rcv_isn = TCP_SKB_CB(skb)->seq;
+ req->mss = tp->mss_clamp;
+ req->ts_recent = tp->saw_tstamp ? tp->rcv_tsval : 0;
+ req->tstamp_ok = tp->tstamp_ok;
+ req->sack_ok = tp->sack_ok;
+ req->snd_wscale = tp->snd_wscale;
+ req->wscale_ok = tp->wscale_ok;
+ req->acked = 0;
+ req->rmt_port = skb->h.th->source;
}
extern const char timer_bug_msg[];
@@ -1179,13 +1451,14 @@ static inline void tcp_clear_xmit_timer(struct sock *sk, int what)
struct timer_list *timer;
switch (what) {
- case TIME_RETRANS:
+ case TCP_TIME_RETRANS:
timer = &tp->retransmit_timer;
break;
- case TIME_DACK:
+ case TCP_TIME_DACK:
+ tp->ack.blocked = 0;
timer = &tp->delack_timer;
break;
- case TIME_PROBE0:
+ case TCP_TIME_PROBE0:
timer = &tp->probe_timer;
break;
default:
@@ -1199,7 +1472,7 @@ static inline void tcp_clear_xmit_timer(struct sock *sk, int what)
spin_unlock_bh(&sk->timer_lock);
}
-/* This function does not return reliable answer. You is only as advice.
+/* This function does not return reliable answer. Use it only as advice.
*/
static inline int tcp_timer_is_set(struct sock *sk, int what)
@@ -1208,13 +1481,13 @@ static inline int tcp_timer_is_set(struct sock *sk, int what)
int ret;
switch (what) {
- case TIME_RETRANS:
+ case TCP_TIME_RETRANS:
ret = tp->retransmit_timer.prev != NULL;
break;
- case TIME_DACK:
+ case TCP_TIME_DACK:
ret = tp->delack_timer.prev != NULL;
break;
- case TIME_PROBE0:
+ case TCP_TIME_PROBE0:
ret = tp->probe_timer.prev != NULL;
break;
default:
@@ -1248,18 +1521,46 @@ extern __inline__ void tcp_listen_unlock(void)
static inline int keepalive_intvl_when(struct tcp_opt *tp)
{
- if (tp->keepalive_intvl)
- return tp->keepalive_intvl;
- else
- return sysctl_tcp_keepalive_intvl;
+ return tp->keepalive_intvl ? : sysctl_tcp_keepalive_intvl;
}
static inline int keepalive_time_when(struct tcp_opt *tp)
{
- if (tp->keepalive_time)
- return tp->keepalive_time;
- else
- return sysctl_tcp_keepalive_time;
+ return tp->keepalive_time ? : sysctl_tcp_keepalive_time;
}
+static inline int tcp_fin_time(struct tcp_opt *tp)
+{
+ int fin_timeout = tp->linger2 ? : sysctl_tcp_fin_timeout;
+
+ if (fin_timeout < (tp->rto<<2) - (tp->rto>>1))
+ fin_timeout = (tp->rto<<2) - (tp->rto>>1);
+
+ return fin_timeout;
+}
+
+#if 0 /* TCP_DEBUG */
+#define TCP_CHECK_TIMER(sk) \
+do { struct tcp_opt *__tp = &sk->tp_pinfo.af_tcp; \
+ if (sk->state != TCP_CLOSE) { \
+ if (__tp->packets_out) { \
+ if (!tcp_timer_is_set(sk, TCP_TIME_RETRANS) && !timer_is_running(&__tp->retransmit_timer) && net_ratelimit()) \
+ printk(KERN_DEBUG "sk=%p RETRANS" __FUNCTION__ "(%d) %d\n", sk, __LINE__, sk->state); \
+ } else if (__tp->send_head) { \
+ if (!tcp_timer_is_set(sk, TCP_TIME_PROBE0) && !timer_is_running(&__tp->probe_timer) && net_ratelimit()) \
+ printk(KERN_DEBUG "sk=%p PROBE0" __FUNCTION__ "(%d) %d\n", sk, __LINE__, sk->state); \
+ } \
+ if (__tp->ack.pending) { \
+ if (!tcp_timer_is_set(sk, TCP_TIME_DACK) && !timer_is_running(&__tp->delack_timer) && net_ratelimit()) \
+ printk(KERN_DEBUG "sk=%p DACK" __FUNCTION__ "(%d) %d\n", sk, __LINE__, sk->state); \
+ } \
+ if (__tp->packets_out > skb_queue_len(&sk->write_queue) || \
+ (__tp->send_head && skb_queue_len(&sk->write_queue) == 0)) { \
+ printk(KERN_DEBUG "sk=%p QUEUE" __FUNCTION__ "(%d) %d %d %d %p\n", sk, __LINE__, sk->state, __tp->packets_out, skb_queue_len(&sk->write_queue), __tp->send_head); \
+ } \
+ } } while (0)
+#else
+#define TCP_CHECK_TIMER(sk) do { } while (0);
+#endif
+
#endif /* _TCP_H */
diff --git a/ipc/shm.c b/ipc/shm.c
index 8b4976195..1b3855450 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -584,15 +584,10 @@ out_unlock:
*/
static struct vm_operations_struct shm_vm_ops = {
- shm_open, /* open - callback for a new vm-area open */
- shm_close, /* close - callback for when the vm-area is released */
- NULL, /* no need to sync pages at unmap */
- NULL, /* protect */
- NULL, /* sync */
- NULL, /* advise */
- shm_nopage, /* nopage */
- NULL, /* wppage */
- shm_swapout /* swapout */
+ open: shm_open, /* open - callback for a new vm-area open */
+ close: shm_close, /* close - callback for when the vm-area is released */
+ nopage: shm_nopage,
+ swapout: shm_swapout,
};
/* Insert shmd into the list shp->attaches */
diff --git a/kernel/dma.c b/kernel/dma.c
index e9f0f7a52..983dedb60 100644
--- a/kernel/dma.c
+++ b/kernel/dma.c
@@ -16,6 +16,7 @@
#include <asm/dma.h>
#include <asm/system.h>
+
/* A note on resource allocation:
*
@@ -35,6 +36,12 @@
spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED;
+/*
+ * If our port doesn't define this it has no PC like DMA
+ */
+
+#ifdef MAX_DMA_CHANNELS
+
/* Channel n is busy iff dma_chan_busy[n].lock != 0.
* DMA0 used to be reserved for DRAM refresh, but apparently not any more...
@@ -100,3 +107,22 @@ void free_dma(unsigned int dmanr)
}
} /* free_dma */
+
+#else
+
+int request_dma(unsigned int dmanr, const char *device_id)
+{
+ return -EINVAL;
+}
+
+int free_dma(unsigned int dmanr)
+{
+ return -EINVAL;
+}
+
+int get_dma_list(char *buf)
+{
+ strcpy(buf, "No DMA\n");
+ return 7;
+}
+#endif
diff --git a/kernel/exit.c b/kernel/exit.c
index 374241c67..0537ff06d 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -416,9 +416,6 @@ fake_volatile:
tsk->exit_code = code;
exit_notify();
task_unlock(tsk);
-#ifdef DEBUG_PROC_TREE
- audit_ptree();
-#endif
if (tsk->exec_domain && tsk->exec_domain->module)
__MOD_DEC_USE_COUNT(tsk->exec_domain->module);
if (tsk->binfmt && tsk->binfmt->module)
@@ -508,9 +505,6 @@ repeat:
notify_parent(p, SIGCHLD);
} else
release(p);
-#ifdef DEBUG_PROC_TREE
- audit_ptree();
-#endif
goto end_wait4;
default:
continue;
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 31bc6edc0..dea3c38a5 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -183,7 +183,6 @@ EXPORT_SYMBOL(__bforget);
EXPORT_SYMBOL(ll_rw_block);
EXPORT_SYMBOL(__wait_on_buffer);
EXPORT_SYMBOL(___wait_on_page);
-EXPORT_SYMBOL(add_blkdev_randomness);
EXPORT_SYMBOL(block_read_full_page);
EXPORT_SYMBOL(block_write_full_page);
EXPORT_SYMBOL(block_write_partial_page);
@@ -270,7 +269,6 @@ EXPORT_SYMBOL(tq_disk);
EXPORT_SYMBOL(init_buffer);
EXPORT_SYMBOL(refile_buffer);
EXPORT_SYMBOL(max_sectors);
-EXPORT_SYMBOL(max_segments);
EXPORT_SYMBOL(max_readahead);
EXPORT_SYMBOL(file_moveto);
@@ -434,11 +432,14 @@ EXPORT_SYMBOL(__down_trylock);
EXPORT_SYMBOL(__up);
EXPORT_SYMBOL(brw_page);
+#ifdef CONFIG_UID16
+EXPORT_SYMBOL(overflowuid);
+EXPORT_SYMBOL(overflowgid);
+#endif
EXPORT_SYMBOL(fs_overflowuid);
EXPORT_SYMBOL(fs_overflowgid);
/* all busmice */
-EXPORT_SYMBOL(add_mouse_randomness);
EXPORT_SYMBOL(fasync_helper);
#ifdef CONFIG_BLK_DEV_MD
diff --git a/kernel/sched.c b/kernel/sched.c
index 09817384f..ce72ecc7b 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -477,7 +477,7 @@ handle_bh_back:
goto move_rr_last;
move_rr_back:
- switch (prev->state) {
+ switch (prev->state & ~TASK_EXCLUSIVE) {
case TASK_INTERRUPTIBLE:
if (signal_pending(prev)) {
prev->state = TASK_RUNNING;
diff --git a/kernel/signal.c b/kernel/signal.c
index dfc65edc6..dca49b492 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -12,7 +12,6 @@
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/sched.h>
-#include <linux/highuid.h>
#include <asm/param.h>
#include <asm/uaccess.h>
@@ -167,7 +166,6 @@ printk("SIG dequeue (%s:%d): %d ", current->comm, current->pid,
info->si_code = 0;
info->si_pid = 0;
info->si_uid = 0;
- SET_SIGINFO_UID16(info->si_uid16, 0);
}
if (reset)
@@ -326,7 +324,6 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
q->info.si_code = SI_USER;
q->info.si_pid = current->pid;
q->info.si_uid = current->uid;
- SET_SIGINFO_UID16(q->info.si_uid16, current->uid);
break;
case 1:
q->info.si_signo = sig;
@@ -334,7 +331,6 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
q->info.si_code = SI_KERNEL;
q->info.si_pid = 0;
q->info.si_uid = 0;
- SET_SIGINFO_UID16(q->info.si_uid16, 0);
break;
default:
q->info = *info;
@@ -784,7 +780,6 @@ sys_kill(int pid, int sig)
info.si_code = SI_USER;
info.si_pid = current->pid;
info.si_uid = current->uid;
- SET_SIGINFO_UID16(info.si_uid16, current->uid);
return kill_something_info(sig, &info, pid);
}
diff --git a/kernel/sys.c b/kernel/sys.c
index cc368de01..57940edea 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -828,21 +828,16 @@ out:
return 1;
}
-/*
- * This should really be a blocking read-write lock
- * rather than a semaphore. Anybody want to implement
- * one?
- */
-DECLARE_MUTEX(uts_sem);
+DECLARE_RWSEM(uts_sem);
asmlinkage long sys_newuname(struct new_utsname * name)
{
int errno = 0;
- down(&uts_sem);
+ down_read(&uts_sem);
if (copy_to_user(name,&system_utsname,sizeof *name))
errno = -EFAULT;
- up(&uts_sem);
+ up_read(&uts_sem);
return errno;
}
@@ -854,13 +849,13 @@ asmlinkage long sys_sethostname(char *name, int len)
return -EPERM;
if (len < 0 || len > __NEW_UTS_LEN)
return -EINVAL;
- down(&uts_sem);
+ down_write(&uts_sem);
errno = -EFAULT;
if (!copy_from_user(system_utsname.nodename, name, len)) {
system_utsname.nodename[len] = 0;
errno = 0;
}
- up(&uts_sem);
+ up_write(&uts_sem);
return errno;
}
@@ -870,14 +865,14 @@ asmlinkage long sys_gethostname(char *name, int len)
if (len < 0)
return -EINVAL;
- down(&uts_sem);
+ down_read(&uts_sem);
i = 1 + strlen(system_utsname.nodename);
if (i > len)
i = len;
errno = 0;
if (copy_to_user(name, system_utsname.nodename, i))
errno = -EFAULT;
- up(&uts_sem);
+ up_read(&uts_sem);
return errno;
}
@@ -894,13 +889,13 @@ asmlinkage long sys_setdomainname(char *name, int len)
if (len < 0 || len > __NEW_UTS_LEN)
return -EINVAL;
- down(&uts_sem);
+ down_write(&uts_sem);
errno = -EFAULT;
if (!copy_from_user(system_utsname.domainname, name, len)) {
errno = 0;
system_utsname.domainname[len] = 0;
}
- up(&uts_sem);
+ up_write(&uts_sem);
return errno;
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index fd4970e58..50ba37060 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -43,7 +43,7 @@ extern int sysctl_overcommit_memory;
extern int max_threads;
extern int nr_queued_signals, max_queued_signals;
-/* this is needed for the proc_dointvec_minmax for overflow UID and GID */
+/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
static int maxolduid = 65535;
static int minolduid = 0;
@@ -722,9 +722,16 @@ static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp)
{
int r;
- down(&uts_sem);
- r=proc_dostring(table,write,filp,buffer,lenp);
- up(&uts_sem);
+
+ if (!write) {
+ down_read(&uts_sem);
+ r=proc_dostring(table,0,filp,buffer,lenp);
+ up_read(&uts_sem);
+ } else {
+ down_write(&uts_sem);
+ r=proc_dostring(table,1,filp,buffer,lenp);
+ up_write(&uts_sem);
+ }
return r;
}
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 9f72e7453..c4a6619db 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -152,6 +152,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
number of chars for from string */
int qualifier; /* 'h', 'l', or 'L' for integer fields */
/* 'z' support added 23/7/1999 S.H. */
+ /* 'z' changed to 'Z' --davidm 1/25/99 */
for (str=buf ; *fmt ; ++fmt) {
@@ -203,7 +204,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
/* get the conversion qualifier */
qualifier = -1;
- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='z') {
+ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
qualifier = *fmt;
++fmt;
}
@@ -252,7 +253,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
if (qualifier == 'l') {
long * ip = va_arg(args, long *);
*ip = (str - buf);
- } else if (qualifier == 'z') {
+ } else if (qualifier == 'Z') {
size_t * ip = va_arg(args, size_t *);
*ip = (str - buf);
} else {
@@ -296,7 +297,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
num = va_arg(args, unsigned long);
if (flags & SIGN)
num = (signed long) num;
- } else if (qualifier == 'z') {
+ } else if (qualifier == 'Z') {
num = va_arg(args, size_t);
} else if (qualifier == 'h') {
num = (unsigned short) va_arg(args, int);
diff --git a/mm/filemap.c b/mm/filemap.c
index 63a50b7e6..2ef865555 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1627,15 +1627,10 @@ static void filemap_unmap(struct vm_area_struct *vma, unsigned long start, size_
* backing-store for swapping..
*/
static struct vm_operations_struct file_shared_mmap = {
- NULL, /* no special open */
- NULL, /* no special close */
- filemap_unmap, /* unmap - we need to sync the pages */
- NULL, /* no special protect */
- filemap_sync, /* sync */
- NULL, /* advise */
- filemap_nopage, /* nopage */
- NULL, /* wppage */
- filemap_swapout /* swapout */
+ unmap: filemap_unmap, /* unmap - we need to sync the pages */
+ sync: filemap_sync,
+ nopage: filemap_nopage,
+ swapout: filemap_swapout,
};
/*
@@ -1645,15 +1640,7 @@ static struct vm_operations_struct file_shared_mmap = {
* know they can't ever get write permissions..)
*/
static struct vm_operations_struct file_private_mmap = {
- NULL, /* open */
- NULL, /* close */
- NULL, /* unmap */
- NULL, /* protect */
- NULL, /* sync */
- NULL, /* advise */
- filemap_nopage, /* nopage */
- NULL, /* wppage */
- NULL /* swapout */
+ nopage: filemap_nopage,
};
/* This is used for a general mmap of a disk file */
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 1c6ced2be..b6d174188 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6,6 +6,7 @@
* Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
* Reshaped it to be a zoned allocator, Ingo Molnar, Red Hat, 1999
* Discontiguous memory support, Kanoj Sarcar, SGI, Nov 1999
+ * Zone balancing, Kanoj Sarcar, SGI, Jan 2000
*/
#include <linux/config.h>
@@ -28,6 +29,7 @@ int nr_lru_pages;
LIST_HEAD(lru_cache);
static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
+static int zone_balance_ratio[MAX_NR_ZONES] = { 128, 128, 128 };
/*
* Free_page() adds the page to the free lists. This is optimized for
@@ -197,18 +199,32 @@ static inline struct page * rmqueue (zone_t *zone, unsigned long order)
#define ZONE_BALANCED(zone) \
(((zone)->free_pages > (zone)->pages_low) && (!(zone)->low_on_memory))
+static inline unsigned long classfree(zone_t *zone)
+{
+ unsigned long free = 0;
+ zone_t *z = zone->zone_pgdat->node_zones;
+
+ while (z != zone) {
+ free += z->free_pages;
+ z++;
+ }
+ free += zone->free_pages;
+ return(free);
+}
+
static inline int zone_balance_memory (zone_t *zone, int gfp_mask)
{
int freed;
+ unsigned long free = classfree(zone);
- if (zone->free_pages >= zone->pages_low) {
+ if (free >= zone->pages_low) {
if (!zone->low_on_memory)
return 1;
/*
* Simple hysteresis: exit 'low memory mode' if
* the upper limit has been reached:
*/
- if (zone->free_pages >= zone->pages_high) {
+ if (free >= zone->pages_high) {
zone->low_on_memory = 0;
return 1;
}
@@ -220,18 +236,14 @@ static inline int zone_balance_memory (zone_t *zone, int gfp_mask)
* state machine, but do not try to free pages
* ourselves.
*/
- if (!(gfp_mask & __GFP_WAIT))
- return 1;
-
- current->flags |= PF_MEMALLOC;
freed = try_to_free_pages(gfp_mask, zone);
- current->flags &= ~PF_MEMALLOC;
- if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH)))
+ if (!freed && !(gfp_mask & __GFP_HIGH))
return 0;
return 1;
}
+#if 0
/*
* We are still balancing memory in a global way:
*/
@@ -260,17 +272,13 @@ static inline int balance_memory (zone_t *zone, int gfp_mask)
* state machine, but do not try to free pages
* ourselves.
*/
- if (!(gfp_mask & __GFP_WAIT))
- return 1;
-
- current->flags |= PF_MEMALLOC;
freed = try_to_free_pages(gfp_mask, zone);
- current->flags &= ~PF_MEMALLOC;
- if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH)))
+ if (!freed && !(gfp_mask & __GFP_HIGH))
return 0;
return 1;
}
+#endif
/*
* This is the 'heart' of the zoned buddy allocator:
@@ -340,7 +348,7 @@ nopage:
* The main chunk of the balancing code is in this offline branch:
*/
balance:
- if (!balance_memory(z, gfp_mask))
+ if (!zone_balance_memory(z, gfp_mask))
goto nopage;
goto ready;
}
@@ -513,6 +521,7 @@ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
unsigned long i, j;
unsigned long map_size;
unsigned int totalpages, offset;
+ unsigned int cumulative = 0;
totalpages = 0;
for (i = 0; i < MAX_NR_ZONES; i++) {
@@ -565,7 +574,7 @@ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
offset = lmem_map - mem_map;
for (j = 0; j < MAX_NR_ZONES; j++) {
zone_t *zone = pgdat->node_zones + j;
- unsigned long mask = -1;
+ unsigned long mask;
unsigned long size;
size = zones_size[j];
@@ -579,13 +588,11 @@ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
continue;
zone->offset = offset;
- /*
- * It's unnecessery to balance the high memory zone
- */
- if (j != ZONE_HIGHMEM) {
- zone->pages_low = freepages.low;
- zone->pages_high = freepages.high;
- }
+ cumulative += size;
+ mask = (cumulative / zone_balance_ratio[j]);
+ if (mask < 1) mask = 1;
+ zone->pages_low = mask*2;
+ zone->pages_high = mask*3;
zone->low_on_memory = 0;
for (i = 0; i < size; i++) {
@@ -598,6 +605,7 @@ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
}
offset += size;
+ mask = -1;
for (i = 0; i < MAX_ORDER; i++) {
unsigned long bitmap_size;
@@ -618,3 +626,16 @@ void __init free_area_init(unsigned int *zones_size)
{
free_area_init_core(0, NODE_DATA(0), &mem_map, zones_size, 0);
}
+
+static int __init setup_mem_frac(char *str)
+{
+ int j = 0;
+
+ while (get_option(&str, &zone_balance_ratio[j++]) == 2);
+ printk("setup_mem_frac: ");
+ for (j = 0; j < MAX_NR_ZONES; j++) printk("%d ", zone_balance_ratio[j]);
+ printk("\n");
+ return 1;
+}
+
+__setup("memfrac=", setup_mem_frac);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 3a5f4fbbe..231cbf8f7 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -33,7 +33,7 @@
* using a process that no longer actually exists (it might
* have died while we slept).
*/
-static int try_to_swap_out(struct vm_area_struct* vma, unsigned long address, pte_t * page_table, int gfp_mask, zone_t *zone)
+static int try_to_swap_out(struct vm_area_struct* vma, unsigned long address, pte_t * page_table, int gfp_mask)
{
pte_t pte;
swp_entry_t entry;
@@ -58,9 +58,7 @@ static int try_to_swap_out(struct vm_area_struct* vma, unsigned long address, pt
goto out_failed;
}
- if (PageReserved(page)
- || PageLocked(page)
- || (zone && (!memclass(page->zone, zone))))
+ if (PageReserved(page) || PageLocked(page))
goto out_failed;
/*
@@ -195,7 +193,7 @@ out_failed:
* (C) 1993 Kai Petzke, wpp@marie.physik.tu-berlin.de
*/
-static inline int swap_out_pmd(struct vm_area_struct * vma, pmd_t *dir, unsigned long address, unsigned long end, int gfp_mask, zone_t *zone)
+static inline int swap_out_pmd(struct vm_area_struct * vma, pmd_t *dir, unsigned long address, unsigned long end, int gfp_mask)
{
pte_t * pte;
unsigned long pmd_end;
@@ -217,7 +215,7 @@ static inline int swap_out_pmd(struct vm_area_struct * vma, pmd_t *dir, unsigned
do {
int result;
vma->vm_mm->swap_address = address + PAGE_SIZE;
- result = try_to_swap_out(vma, address, pte, gfp_mask, zone);
+ result = try_to_swap_out(vma, address, pte, gfp_mask);
if (result)
return result;
address += PAGE_SIZE;
@@ -226,7 +224,7 @@ static inline int swap_out_pmd(struct vm_area_struct * vma, pmd_t *dir, unsigned
return 0;
}
-static inline int swap_out_pgd(struct vm_area_struct * vma, pgd_t *dir, unsigned long address, unsigned long end, int gfp_mask, zone_t *zone)
+static inline int swap_out_pgd(struct vm_area_struct * vma, pgd_t *dir, unsigned long address, unsigned long end, int gfp_mask)
{
pmd_t * pmd;
unsigned long pgd_end;
@@ -246,7 +244,7 @@ static inline int swap_out_pgd(struct vm_area_struct * vma, pgd_t *dir, unsigned
end = pgd_end;
do {
- int result = swap_out_pmd(vma, pmd, address, end, gfp_mask, zone);
+ int result = swap_out_pmd(vma, pmd, address, end, gfp_mask);
if (result)
return result;
address = (address + PMD_SIZE) & PMD_MASK;
@@ -255,7 +253,7 @@ static inline int swap_out_pgd(struct vm_area_struct * vma, pgd_t *dir, unsigned
return 0;
}
-static int swap_out_vma(struct vm_area_struct * vma, unsigned long address, int gfp_mask, zone_t *zone)
+static int swap_out_vma(struct vm_area_struct * vma, unsigned long address, int gfp_mask)
{
pgd_t *pgdir;
unsigned long end;
@@ -270,7 +268,7 @@ static int swap_out_vma(struct vm_area_struct * vma, unsigned long address, int
if (address >= end)
BUG();
do {
- int result = swap_out_pgd(vma, pgdir, address, end, gfp_mask, zone);
+ int result = swap_out_pgd(vma, pgdir, address, end, gfp_mask);
if (result)
return result;
address = (address + PGDIR_SIZE) & PGDIR_MASK;
@@ -279,7 +277,7 @@ static int swap_out_vma(struct vm_area_struct * vma, unsigned long address, int
return 0;
}
-static int swap_out_mm(struct mm_struct * mm, int gfp_mask, zone_t *zone)
+static int swap_out_mm(struct mm_struct * mm, int gfp_mask)
{
unsigned long address;
struct vm_area_struct* vma;
@@ -300,7 +298,7 @@ static int swap_out_mm(struct mm_struct * mm, int gfp_mask, zone_t *zone)
address = vma->vm_start;
for (;;) {
- int result = swap_out_vma(vma, address, gfp_mask, zone);
+ int result = swap_out_vma(vma, address, gfp_mask);
if (result)
return result;
vma = vma->vm_next;
@@ -322,7 +320,7 @@ static int swap_out_mm(struct mm_struct * mm, int gfp_mask, zone_t *zone)
* N.B. This function returns only 0 or 1. Return values != 1 from
* the lower level routines result in continued processing.
*/
-static int swap_out(unsigned int priority, int gfp_mask, zone_t *zone)
+static int swap_out(unsigned int priority, int gfp_mask)
{
struct task_struct * p;
int counter;
@@ -383,7 +381,7 @@ static int swap_out(unsigned int priority, int gfp_mask, zone_t *zone)
int ret;
atomic_inc(&best->mm_count);
- ret = swap_out_mm(best, gfp_mask, zone);
+ ret = swap_out_mm(best, gfp_mask);
mmdrop(best);
if (!ret)
@@ -424,16 +422,18 @@ static int do_try_to_free_pages(unsigned int gfp_mask, zone_t *zone)
goto done;
}
- /* don't be too light against the d/i cache since
- shrink_mmap() almost never fail when there's
- really plenty of memory free. */
- count -= shrink_dcache_memory(priority, gfp_mask, zone);
- count -= shrink_icache_memory(priority, gfp_mask, zone);
- if (count <= 0)
- goto done;
/* Try to get rid of some shared memory pages.. */
if (gfp_mask & __GFP_IO) {
+ /*
+ * don't be too light against the d/i cache since
+ * shrink_mmap() almost never fail when there's
+ * really plenty of memory free.
+ */
+ count -= shrink_dcache_memory(priority, gfp_mask, zone);
+ count -= shrink_icache_memory(priority, gfp_mask, zone);
+ if (count <= 0)
+ goto done;
while (shm_swap(priority, gfp_mask, zone)) {
if (!--count)
goto done;
@@ -441,7 +441,7 @@ static int do_try_to_free_pages(unsigned int gfp_mask, zone_t *zone)
}
/* Then, try to page stuff out.. */
- while (swap_out(priority, gfp_mask, zone)) {
+ while (swap_out(priority, gfp_mask)) {
if (!--count)
goto done;
}
@@ -534,8 +534,11 @@ int try_to_free_pages(unsigned int gfp_mask, zone_t *zone)
int retval = 1;
wake_up_process(kswapd_process);
- if (gfp_mask & __GFP_WAIT)
+ if (gfp_mask & __GFP_WAIT) {
+ current->flags |= PF_MEMALLOC;
retval = do_try_to_free_pages(gfp_mask, zone);
+ current->flags &= ~PF_MEMALLOC;
+ }
return retval;
}
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 51e74cab8..2941951df 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1313,7 +1313,7 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
int lv;
int addr_len = msg->msg_namelen;
- if (msg->msg_flags & ~MSG_DONTWAIT)
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR))
return -EINVAL;
if (sk->zapped)
diff --git a/net/core/datagram.c b/net/core/datagram.c
index bb3208729..bda174519 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -60,14 +60,14 @@ static inline int connection_based(struct sock *sk)
* Wait for a packet..
*/
-static int wait_for_packet(struct sock * sk, int *err)
+static int wait_for_packet(struct sock * sk, int *err, long *timeo_p)
{
int error;
DECLARE_WAITQUEUE(wait, current);
- __set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(sk->sleep, &wait);
+ __set_current_state(TASK_INTERRUPTIBLE|TASK_EXCLUSIVE);
+ add_wait_queue_exclusive(sk->sleep, &wait);
/* Socket errors? */
error = sock_error(sk);
@@ -91,7 +91,7 @@ static int wait_for_packet(struct sock * sk, int *err)
if (signal_pending(current))
goto out;
- schedule();
+ *timeo_p = schedule_timeout(*timeo_p);
ready:
current->state = TASK_RUNNING;
@@ -132,12 +132,15 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, int noblock,
{
int error;
struct sk_buff *skb;
+ long timeo;
/* Caller is allowed not to check sk->err before skb_recv_datagram() */
error = sock_error(sk);
if (error)
goto no_packet;
+ timeo = sock_rcvtimeo(sk, noblock);
+
do {
/* Again only user level code calls this function, so nothing interrupt level
will suddenly eat the receive_queue.
@@ -162,10 +165,10 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, int noblock,
/* User doesn't want to wait */
error = -EAGAIN;
- if (noblock)
+ if (!timeo)
goto no_packet;
- } while (wait_for_packet(sk, err) == 0);
+ } while (wait_for_packet(sk, err, &timeo) == 0);
return NULL;
@@ -225,11 +228,11 @@ unsigned int datagram_poll(struct file * file, struct socket *sock, poll_table *
/* exceptional events? */
if (sk->err || !skb_queue_empty(&sk->error_queue))
mask |= POLLERR;
- if (sk->shutdown & RCV_SHUTDOWN)
+ if (sk->shutdown == SHUTDOWN_MASK)
mask |= POLLHUP;
/* readable? */
- if (!skb_queue_empty(&sk->receive_queue))
+ if (!skb_queue_empty(&sk->receive_queue) || (sk->shutdown&RCV_SHUTDOWN))
mask |= POLLIN | POLLRDNORM;
/* Connection-based need to check for termination and startup */
diff --git a/net/core/iovec.c b/net/core/iovec.c
index 5ba18150d..4ebad506e 100644
--- a/net/core/iovec.c
+++ b/net/core/iovec.c
@@ -104,6 +104,11 @@ out:
/* Copy and checkum skb to user iovec. Caller _must_ check that
skb will fit to this iovec.
+
+ Returns: 0 - success.
+ -EINVAL - checksum failure.
+ -EFAULT - fault during copy. Beware, in this case iovec can be
+ modified!
*/
int copy_and_csum_toiovec(struct iovec *iov, struct sk_buff *skb, int hlen)
@@ -111,7 +116,7 @@ int copy_and_csum_toiovec(struct iovec *iov, struct sk_buff *skb, int hlen)
unsigned int csum;
int chunk = skb->len - hlen;
- /* Skip filled elements. Pretty silly, look at mecpy_toiove, though 8) */
+ /* Skip filled elements. Pretty silly, look at memcpy_toiovec, though 8) */
while (iov->iov_len == 0)
iov++;
@@ -119,7 +124,7 @@ int copy_and_csum_toiovec(struct iovec *iov, struct sk_buff *skb, int hlen)
if ((unsigned short)csum_fold(csum_partial(skb->h.raw, chunk+hlen, skb->csum)))
goto csum_error;
if (memcpy_toiovec(iov, skb->h.raw + hlen, chunk))
- goto csum_error;
+ goto fault;
} else {
int err = 0;
csum = csum_partial(skb->h.raw, hlen, skb->csum);
@@ -133,6 +138,9 @@ int copy_and_csum_toiovec(struct iovec *iov, struct sk_buff *skb, int hlen)
return 0;
csum_error:
+ return -EINVAL;
+
+fault:
return -EFAULT;
}
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 12a8f8d72..3528c7510 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -4,7 +4,7 @@
* Authors: Alan Cox <iiitac@pyr.swan.ac.uk>
* Florian La Roche <rzsfl@rz.uni-sb.de>
*
- * Version: $Id: skbuff.c,v 1.63 2000/01/02 09:15:17 davem Exp $
+ * Version: $Id: skbuff.c,v 1.64 2000/01/16 05:11:03 davem Exp $
*
* Fixes:
* Alan Cox : Fixed the worst of the load balancer bugs.
@@ -61,10 +61,6 @@
#include <asm/uaccess.h>
#include <asm/system.h>
-#ifdef CONFIG_ATM
-#include <linux/atmdev.h>
-#endif
-
/*
* Resource tracking variables
*/
@@ -165,10 +161,6 @@ struct sk_buff *alloc_skb(unsigned int size,int gfp_mask)
skb->is_clone = 0;
skb->cloned = 0;
-#ifdef CONFIG_ATM
- ATM_SKB(skb)->iovcnt = 0;
-#endif
-
atomic_set(&skb->users, 1);
atomic_set(skb_datarefp(skb), 1);
return skb;
@@ -206,6 +198,9 @@ static inline void skb_headerinit(void *p, kmem_cache_t *cache,
skb->nf_debug = 0;
#endif
#endif
+#ifdef CONFIG_NET_SCHED
+ skb->tc_index = 0;
+#endif
memset(skb->cb, 0, sizeof(skb->cb));
skb->priority = 0;
}
@@ -308,6 +303,9 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->nf_debug=old->nf_debug;
#endif
#endif
+#ifdef CONFIG_NET_SCHED
+ new->tc_index = old->tc_index;
+#endif
}
/*
diff --git a/net/core/sock.c b/net/core/sock.c
index e069ca898..c5781c6e3 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -7,7 +7,7 @@
* handler for protocols to use and generic option handler.
*
*
- * Version: $Id: sock.c,v 1.87 1999/11/23 08:56:59 davem Exp $
+ * Version: $Id: sock.c,v 1.89 2000/01/18 08:24:13 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -140,6 +140,23 @@ __u32 sysctl_rmem_default = SK_RMEM_MAX;
/* Maximal space eaten by iovec or ancilliary data plus some space */
int sysctl_optmem_max = sizeof(unsigned long)*(2*UIO_MAXIOV + 512);
+static int sock_set_timeout(long *timeo_p, char *optval, int optlen)
+{
+ struct timeval tv;
+
+ if (optlen < sizeof(tv))
+ return -EINVAL;
+ if (copy_from_user(&tv, optval, sizeof(tv)))
+ return -EFAULT;
+
+ *timeo_p = MAX_SCHEDULE_TIMEOUT;
+ if (tv.tv_sec == 0 && tv.tv_usec == 0)
+ return 0;
+ if (tv.tv_sec < (MAX_SCHEDULE_TIMEOUT/HZ - 1))
+ *timeo_p = tv.tv_sec*HZ + (tv.tv_usec+(1000000/HZ-1))/(1000000/HZ);
+ return 0;
+}
+
/*
* This is meant for all protocols to use and covers goings on
* at the socket level. Everything here is generic.
@@ -214,7 +231,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
if (val > sysctl_wmem_max)
val = sysctl_wmem_max;
- sk->sndbuf = max(val*2,2048);
+ sk->sndbuf = max(val*2,SOCK_MIN_SNDBUF);
/*
* Wake up sending tasks if we
@@ -233,7 +250,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
val = sysctl_rmem_max;
/* FIXME: is this lower bound the right one? */
- sk->rcvbuf = max(val*2,256);
+ sk->rcvbuf = max(val*2,SOCK_MIN_RCVBUF);
break;
case SO_KEEPALIVE:
@@ -266,16 +283,19 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
ret = -EINVAL; /* 1003.1g */
break;
}
- if (copy_from_user(&ling,optval,sizeof(ling)))
- {
+ if (copy_from_user(&ling,optval,sizeof(ling))) {
ret = -EFAULT;
break;
}
- if(ling.l_onoff==0)
+ if(ling.l_onoff==0) {
sk->linger=0;
- else
- {
- sk->lingertime=ling.l_linger;
+ } else {
+#if (BITS_PER_LONG == 32)
+ if (ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ)
+ sk->lingertime=MAX_SCHEDULE_TIMEOUT;
+ else
+#endif
+ sk->lingertime=ling.l_linger*HZ;
sk->linger=1;
}
break;
@@ -287,8 +307,21 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
case SO_PASSCRED:
sock->passcred = valbool;
break;
-
-
+
+ case SO_RCVLOWAT:
+ if (val < 0)
+ val = INT_MAX;
+ sk->rcvlowat = val ? : 1;
+ break;
+
+ case SO_RCVTIMEO:
+ ret = sock_set_timeout(&sk->rcvtimeo, optval, optlen);
+ break;
+
+ case SO_SNDTIMEO:
+ ret = sock_set_timeout(&sk->sndtimeo, optval, optlen);
+ break;
+
#ifdef CONFIG_NETDEVICES
case SO_BINDTODEVICE:
{
@@ -446,7 +479,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
case SO_LINGER:
lv=sizeof(v.ling);
v.ling.l_onoff=sk->linger;
- v.ling.l_linger=sk->lingertime;
+ v.ling.l_linger=sk->lingertime/HZ;
break;
case SO_BSDCOMPAT:
@@ -454,13 +487,31 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
break;
case SO_RCVTIMEO:
+ lv=sizeof(struct timeval);
+ if (sk->rcvtimeo == MAX_SCHEDULE_TIMEOUT) {
+ v.tm.tv_sec = 0;
+ v.tm.tv_usec = 0;
+ } else {
+ v.tm.tv_sec = sk->rcvtimeo/HZ;
+ v.tm.tv_usec = ((sk->rcvtimeo%HZ)*1000)/HZ;
+ }
+ break;
+
case SO_SNDTIMEO:
lv=sizeof(struct timeval);
- v.tm.tv_sec=0;
- v.tm.tv_usec=0;
+ if (sk->sndtimeo == MAX_SCHEDULE_TIMEOUT) {
+ v.tm.tv_sec = 0;
+ v.tm.tv_usec = 0;
+ } else {
+ v.tm.tv_sec = sk->sndtimeo/HZ;
+ v.tm.tv_usec = ((sk->sndtimeo%HZ)*1000)/HZ;
+ }
break;
case SO_RCVLOWAT:
+ v.val = sk->rcvlowat;
+ break;
+
case SO_SNDLOWAT:
v.val=1;
break;
@@ -663,7 +714,7 @@ unsigned long sock_rspace(struct sock *sk)
/* It is almost wait_for_tcp_memory minus release_sock/lock_sock.
I think, these locks should be removed for datagram sockets.
*/
-static void sock_wait_for_wmem(struct sock * sk)
+static long sock_wait_for_wmem(struct sock * sk, long timeo)
{
DECLARE_WAITQUEUE(wait, current);
@@ -679,10 +730,11 @@ static void sock_wait_for_wmem(struct sock * sk)
break;
if (sk->err)
break;
- schedule();
+ timeo = schedule_timeout(timeo);
}
__set_current_state(TASK_RUNNING);
remove_wait_queue(sk->sleep, &wait);
+ return timeo;
}
@@ -695,6 +747,9 @@ struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size,
{
int err;
struct sk_buff *skb;
+ long timeo;
+
+ timeo = sock_sndtimeo(sk, noblock);
while (1) {
unsigned long try_size = size;
@@ -736,12 +791,12 @@ struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size,
sk->socket->flags |= SO_NOSPACE;
err = -EAGAIN;
- if (noblock)
+ if (!timeo)
goto failure;
err = -ERESTARTSYS;
if (signal_pending(current))
goto failure;
- sock_wait_for_wmem(sk);
+ timeo = sock_wait_for_wmem(sk, timeo);
}
return skb;
@@ -771,13 +826,21 @@ void __lock_sock(struct sock *sk)
void __release_sock(struct sock *sk)
{
struct sk_buff *skb = sk->backlog.head;
+
do {
- struct sk_buff *next = skb->next;
- skb->next = NULL;
- sk->backlog_rcv(sk, skb);
- skb = next;
- } while(skb != NULL);
- sk->backlog.head = sk->backlog.tail = NULL;
+ sk->backlog.head = sk->backlog.tail = NULL;
+ bh_unlock_sock(sk);
+
+ do {
+ struct sk_buff *next = skb->next;
+
+ skb->next = NULL;
+ sk->backlog_rcv(sk, skb);
+ skb = next;
+ } while (skb != NULL);
+
+ bh_lock_sock(sk);
+ } while((skb = sk->backlog.head) != NULL);
}
/*
@@ -1004,7 +1067,7 @@ void sock_def_wakeup(struct sock *sk)
{
read_lock(&sk->callback_lock);
if(!sk->dead)
- wake_up_interruptible(sk->sleep);
+ wake_up_interruptible_all(sk->sleep);
read_unlock(&sk->callback_lock);
}
@@ -1087,6 +1150,9 @@ void sock_init_data(struct socket *sock, struct sock *sk)
sk->peercred.pid = 0;
sk->peercred.uid = -1;
sk->peercred.gid = -1;
+ sk->rcvlowat = 1;
+ sk->rcvtimeo = MAX_SCHEDULE_TIMEOUT;
+ sk->sndtimeo = MAX_SCHEDULE_TIMEOUT;
atomic_set(&sk->refcnt, 1);
}
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index f7972b7df..a1b402672 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -207,7 +207,7 @@ unsigned short eth_type_trans(struct sk_buff *skb, struct net_device *dev)
* seems to set IFF_PROMISC.
*/
- else if(dev->flags&(IFF_PROMISC/*|IFF_ALLMULTI*/))
+ else if(1 /*dev->flags&IFF_PROMISC*/)
{
if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN))
skb->pkt_type=PACKET_OTHERHOST;
@@ -265,7 +265,8 @@ void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsign
memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len);
}
-#ifndef CONFIG_IP_ROUTER
+#if 0 /*ndef CONFIG_IP_ROUTER*/
+/* This one is only slowdown with checksumming in user process context. --ANK */
/*
* Copy from an ethernet device memory space to an sk_buff while checksumming if IP
@@ -298,7 +299,7 @@ void eth_copy_and_sum(struct sk_buff *dest, unsigned char *src, int length, int
if ((ip_length <= length) && (ip_length > 7))
length=ip_length;
- dest->csum=csum_partial_copy(src+sizeof(struct iphdr)+ETH_HLEN,dest->data+sizeof(struct iphdr)+ETH_HLEN,length,base);
+ dest->csum=csum_partial_copy_nocheck(src+sizeof(struct iphdr)+ETH_HLEN,dest->data+sizeof(struct iphdr)+ETH_HLEN,length,base);
dest->ip_summed=1;
}
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 94fb19f92..bc2c97779 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -5,7 +5,7 @@
*
* PF_INET protocol family socket handler.
*
- * Version: $Id: af_inet.c,v 1.101 2000/01/09 02:19:38 davem Exp $
+ * Version: $Id: af_inet.c,v 1.104 2000/01/18 08:24:14 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -117,7 +117,9 @@
struct linux_mib net_statistics[NR_CPUS*2];
+#ifdef INET_REFCNT_DEBUG
atomic_t inet_sock_nr;
+#endif
extern int raw_get_info(char *, char **, off_t, int);
extern int snmp_get_info(char *, char **, off_t, int);
@@ -159,8 +161,8 @@ void inet_sock_destruct(struct sock *sk)
if (sk->protinfo.af_inet.opt)
kfree(sk->protinfo.af_inet.opt);
dst_release(sk->dst_cache);
- atomic_dec(&inet_sock_nr);
#ifdef INET_REFCNT_DEBUG
+ atomic_dec(&inet_sock_nr);
printk(KERN_DEBUG "INET socket %p released, %d are still alive\n", sk, atomic_read(&inet_sock_nr));
#endif
}
@@ -171,32 +173,28 @@ void inet_sock_release(struct sock *sk)
sk->prot->destroy(sk);
/* Observation: when inet_sock_release is called, processes have
- no access to socket. But net still has.
- Step one, detach it from networking:
-
- A. Remove from hash tables.
+ * no access to socket. But net still has.
+ * Step one, detach it from networking:
+ *
+ * A. Remove from hash tables.
*/
sk->prot->unhash(sk);
/* In this point socket cannot receive new packets,
- but it is possible that some packets are in flight
- because some CPU runs receiver and did hash table lookup
- before we unhashed socket. They will achieve receive queue
- and will be purged by socket destructor.
-
- Also we still have packets pending on receive
- queue and probably, our own packets waiting in device queues.
- sock_destroy will drain receive queue, but transmitted
- packets will delay socket destruction until the last reference
- will be released.
+ * but it is possible that some packets are in flight
+ * because some CPU runs receiver and did hash table lookup
+ * before we unhashed socket. They will achieve receive queue
+ * and will be purged by socket destructor.
+ *
+ * Also we still have packets pending on receive
+ * queue and probably, our own packets waiting in device queues.
+ * sock_destroy will drain receive queue, but transmitted
+ * packets will delay socket destruction until the last reference
+ * will be released.
*/
- write_lock_irq(&sk->callback_lock);
- sk->dead=1;
- sk->socket = NULL;
- sk->sleep = NULL;
- write_unlock_irq(&sk->callback_lock);
+ sock_orphan(sk);
#ifdef INET_REFCNT_DEBUG
if (atomic_read(&sk->refcnt) != 1) {
@@ -222,8 +220,7 @@ int inet_setsockopt(struct socket *sock, int level, int optname,
char *optval, int optlen)
{
struct sock *sk=sock->sk;
- if (sk->prot->setsockopt==NULL)
- return -EOPNOTSUPP;
+
return sk->prot->setsockopt(sk,level,optname,optval,optlen);
}
@@ -239,8 +236,7 @@ int inet_getsockopt(struct socket *sock, int level, int optname,
char *optval, int *optlen)
{
struct sock *sk=sock->sk;
- if (sk->prot->getsockopt==NULL)
- return -EOPNOTSUPP;
+
return sk->prot->getsockopt(sk,level,optname,optval,optlen);
}
@@ -264,14 +260,6 @@ static int inet_autobind(struct sock *sk)
return 0;
}
-/* Listening INET sockets never sleep to wait for memory, so
- * it is completely silly to wake them up on queue space
- * available events. So we hook them up to this dummy callback.
- */
-static void inet_listen_write_space(struct sock *sk)
-{
-}
-
/*
* Move a socket into listening state.
*/
@@ -282,12 +270,13 @@ int inet_listen(struct socket *sock, int backlog)
unsigned char old_state;
int err;
+ lock_sock(sk);
+
+ err = -EINVAL;
if (sock->state != SS_UNCONNECTED || sock->type != SOCK_STREAM)
- return -EINVAL;
+ goto out;
- lock_sock(sk);
old_state = sk->state;
- err = -EINVAL;
if (!((1<<old_state)&(TCPF_CLOSE|TCPF_LISTEN)))
goto out;
@@ -295,25 +284,9 @@ int inet_listen(struct socket *sock, int backlog)
* we can only allow the backlog to be adjusted.
*/
if (old_state != TCP_LISTEN) {
- sk->state = TCP_LISTEN;
- sk->ack_backlog = 0;
- if (sk->num == 0) {
- if (sk->prot->get_port(sk, 0) != 0) {
- sk->state = old_state;
- err = -EAGAIN;
- goto out;
- }
- sk->sport = htons(sk->num);
- } else {
- /* Not nice, but the simplest solution however */
- if (sk->prev)
- ((struct tcp_bind_bucket*)sk->prev)->fastreuse = 0;
- }
-
- sk_dst_reset(sk);
- sk->prot->hash(sk);
- sk->socket->flags |= SO_ACCEPTCON;
- sk->write_space = inet_listen_write_space;
+ err = tcp_listen_start(sk);
+ if (err)
+ goto out;
}
sk->max_ack_backlog = backlog;
err = 0;
@@ -345,10 +318,6 @@ static int inet_create(struct socket *sock, int protocol)
if (protocol && protocol != IPPROTO_TCP)
goto free_and_noproto;
protocol = IPPROTO_TCP;
- if (ipv4_config.no_pmtu_disc)
- sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT;
- else
- sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;
prot = &tcp_prot;
sock->ops = &inet_stream_ops;
break;
@@ -359,7 +328,6 @@ static int inet_create(struct socket *sock, int protocol)
goto free_and_noproto;
protocol = IPPROTO_UDP;
sk->no_check = UDP_CSUM_DEFAULT;
- sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT;
prot=&udp_prot;
sock->ops = &inet_dgram_ops;
break;
@@ -370,7 +338,6 @@ static int inet_create(struct socket *sock, int protocol)
goto free_and_noproto;
prot = &raw_prot;
sk->reuse = 1;
- sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT;
sk->num = protocol;
sock->ops = &inet_dgram_ops;
if (protocol == IPPROTO_RAW)
@@ -380,23 +347,22 @@ static int inet_create(struct socket *sock, int protocol)
goto free_and_badtype;
}
+ if (ipv4_config.no_pmtu_disc)
+ sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT;
+ else
+ sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;
+
sock_init_data(sock,sk);
sk->destruct = inet_sock_destruct;
- sk->zapped=0;
-#ifdef CONFIG_TCP_NAGLE_OFF
- sk->nonagle = 1;
-#endif
+ sk->zapped = 0;
sk->family = PF_INET;
sk->protocol = protocol;
sk->prot = prot;
sk->backlog_rcv = prot->backlog_rcv;
- sk->timer.data = (unsigned long)sk;
- sk->timer.function = &tcp_keepalive_timer;
-
sk->protinfo.af_inet.ttl=sysctl_ip_default_ttl;
sk->protinfo.af_inet.mc_loop=1;
@@ -404,7 +370,9 @@ static int inet_create(struct socket *sock, int protocol)
sk->protinfo.af_inet.mc_index=0;
sk->protinfo.af_inet.mc_list=NULL;
+#ifdef INET_REFCNT_DEBUG
atomic_inc(&inet_sock_nr);
+#endif
if (sk->num) {
/* It assumes that any protocol which allows
@@ -469,11 +437,8 @@ int inet_release(struct socket *sock)
* linger..
*/
timeout = 0;
- if (sk->linger && !(current->flags & PF_EXITING)) {
- timeout = HZ * sk->lingertime;
- if (!timeout)
- timeout = MAX_SCHEDULE_TIMEOUT;
- }
+ if (sk->linger && !(current->flags & PF_EXITING))
+ timeout = sk->lingertime;
sock->sk = NULL;
sk->prot->close(sk, timeout);
}
@@ -496,10 +461,6 @@ static int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
return -EINVAL;
chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
- if (addr->sin_addr.s_addr != 0 && chk_addr_ret != RTN_LOCAL &&
- chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) {
- return -EADDRNOTAVAIL; /* Source address MUST be ours! */
- }
snum = ntohs(addr->sin_port);
if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
@@ -555,25 +516,29 @@ int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr,
return sk->prot->connect(sk, (struct sockaddr *)uaddr, addr_len);
}
-static void inet_wait_for_connect(struct sock *sk)
+static long inet_wait_for_connect(struct sock *sk, long timeo)
{
DECLARE_WAITQUEUE(wait, current);
__set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(sk->sleep, &wait);
+ /* Basic assumption: if someone sets sk->err, he _must_
+ * change state of the socket from TCP_SYN_*.
+ * Connect() does not allow to get error notifications
+ * without closing the socket.
+ */
while ((1<<sk->state)&(TCPF_SYN_SENT|TCPF_SYN_RECV)) {
- if (signal_pending(current))
- break;
- if (sk->err)
- break;
release_sock(sk);
- schedule();
+ timeo = schedule_timeout(timeo);
lock_sock(sk);
+ if (signal_pending(current) || !timeo)
+ break;
set_current_state(TASK_INTERRUPTIBLE);
}
__set_current_state(TASK_RUNNING);
remove_wait_queue(sk->sleep, &wait);
+ return timeo;
}
/*
@@ -586,16 +551,16 @@ int inet_stream_connect(struct socket *sock, struct sockaddr * uaddr,
{
struct sock *sk=sock->sk;
int err;
+ long timeo;
+
+ lock_sock(sk);
if (uaddr->sa_family == AF_UNSPEC) {
- lock_sock(sk);
err = sk->prot->disconnect(sk, flags);
sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
- release_sock(sk);
- return err;
+ goto out;
}
- lock_sock(sk);
switch (sock->state) {
default:
err = -EINVAL;
@@ -604,40 +569,58 @@ int inet_stream_connect(struct socket *sock, struct sockaddr * uaddr,
err = -EISCONN;
goto out;
case SS_CONNECTING:
- if (tcp_established(sk->state)) {
- sock->state = SS_CONNECTED;
- err = 0;
- goto out;
- }
- if (sk->err)
- goto sock_error;
err = -EALREADY;
- if (flags & O_NONBLOCK)
- goto out;
+ /* Fall out of switch with err, set for this state */
break;
case SS_UNCONNECTED:
+ err = -EISCONN;
+ if (sk->state != TCP_CLOSE)
+ goto out;
+
+ err = -EAGAIN;
+ if (sk->num == 0) {
+ if (sk->prot->get_port(sk, 0) != 0)
+ goto out;
+ sk->sport = htons(sk->num);
+ }
+
err = sk->prot->connect(sk, uaddr, addr_len);
if (err < 0)
goto out;
+
sock->state = SS_CONNECTING;
- }
- if (sk->state > TCP_FIN_WAIT2)
- goto sock_error;
+ /* Just entered SS_CONNECTING state; the only
+ * difference is that return value in non-blocking
+ * case is EINPROGRESS, rather than EALREADY.
+ */
+ err = -EINPROGRESS;
+ break;
+ }
- err = -EINPROGRESS;
- if (!tcp_established(sk->state) && (flags & O_NONBLOCK))
- goto out;
+ timeo = sock_sndtimeo(sk, flags&O_NONBLOCK);
if ((1<<sk->state)&(TCPF_SYN_SENT|TCPF_SYN_RECV)) {
- inet_wait_for_connect(sk);
+ /* Error code is set above */
+ if (!timeo || !inet_wait_for_connect(sk, timeo))
+ goto out;
+
err = -ERESTARTSYS;
if (signal_pending(current))
goto out;
}
- if (sk->err && !tcp_established(sk->state))
- goto sock_error;
+ /* Connection was closed by RST, timeout, ICMP error
+ * or another process disconnected us.
+ */
+ if (sk->state == TCP_CLOSE)
+ goto sock_error;
+
+ /* sk->err may be not zero now, if RECVERR was ordered by user
+ * and error was received after socket entered established state.
+ * Hence, it is handled normally after connect() return successfully.
+ */
+
sock->state = SS_CONNECTED;
err = 0;
out:
@@ -647,11 +630,9 @@ out:
sock_error:
err = sock_error(sk) ? : -ECONNABORTED;
sock->state = SS_UNCONNECTED;
- if (sk->prot->disconnect(sk, O_NONBLOCK))
+ if (sk->prot->disconnect(sk, flags))
sock->state = SS_DISCONNECTING;
- release_sock(sk);
-
- return err;
+ goto out;
}
/*
@@ -671,11 +652,7 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags)
BUG_TRAP((1<<sk2->state)&(TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_CLOSE));
- write_lock_irq(&sk2->callback_lock);
- sk2->sleep = &newsock->wait;
- newsock->sk = sk2;
- sk2->socket = newsock;
- write_unlock_irq(&sk2->callback_lock);
+ sock_graft(sk2, newsock);
newsock->state = SS_CONNECTED;
release_sock(sk2);
@@ -749,7 +726,7 @@ int inet_sendmsg(struct socket *sock, struct msghdr *msg, int size,
int inet_shutdown(struct socket *sock, int how)
{
struct sock *sk = sock->sk;
- int err;
+ int err = 0;
/* This should really check to make sure
* the socket is a TCP socket. (WHY AC...)
@@ -759,35 +736,45 @@ int inet_shutdown(struct socket *sock, int how)
2->3 */
if ((how & ~SHUTDOWN_MASK) || how==0) /* MAXINT->0 */
return -EINVAL;
- if (!sk)
- return -ENOTCONN;
lock_sock(sk);
- if (sock->state == SS_CONNECTING && tcp_established(sk->state))
- sock->state = SS_CONNECTED;
- err = -ENOTCONN;
- if (!tcp_connected(sk->state))
- goto out;
- sk->shutdown |= how;
- if (sk->prot->shutdown)
- sk->prot->shutdown(sk, how);
+ if (sock->state == SS_CONNECTING) {
+ if ((1<<sk->state)&(TCPF_SYN_SENT|TCPF_SYN_RECV|TCPF_CLOSE))
+ sock->state = SS_DISCONNECTING;
+ else
+ sock->state = SS_CONNECTED;
+ }
+
+ switch (sk->state) {
+ default:
+ sk->shutdown |= how;
+ if (sk->prot->shutdown)
+ sk->prot->shutdown(sk, how);
+ break;
+ case TCP_CLOSE:
+ err = -ENOTCONN;
+ break;
+
+ /* Remaining two branches are temporary solution for missing
+ * close() in multithreaded environment. It is _not_ a good idea,
+ * but we have no choice until close() is repaired at VFS level.
+ */
+ case TCP_LISTEN:
+ if (!(how & RCV_SHUTDOWN))
+ break;
+ /* Fall through */
+ case TCP_SYN_SENT:
+ err = sk->prot->disconnect(sk, O_NONBLOCK);
+ sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
+ break;
+ }
+
/* Wake up anyone sleeping in poll. */
sk->state_change(sk);
- err = 0;
-out:
release_sock(sk);
return err;
}
-unsigned int inet_poll(struct file * file, struct socket *sock, poll_table *wait)
-{
- struct sock *sk = sock->sk;
-
- if (sk->prot->poll == NULL)
- return(0);
- return sk->prot->poll(file, sock, wait);
-}
-
/*
* ioctl() calls you can issue on an INET socket. Most of these are
* device configuration and stuff and very rarely used. Some ioctls
@@ -909,7 +896,7 @@ struct proto_ops inet_stream_ops = {
sock_no_socketpair,
inet_accept,
inet_getname,
- inet_poll,
+ tcp_poll,
inet_ioctl,
inet_listen,
inet_shutdown,
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 591f3cceb..588cdf030 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1,6 +1,6 @@
/* linux/net/inet/arp.c
*
- * Version: $Id: arp.c,v 1.83 1999/12/15 22:39:03 davem Exp $
+ * Version: $Id: arp.c,v 1.84 2000/01/18 08:24:14 davem Exp $
*
* Copyright (C) 1994 by Florian La Roche
*
@@ -487,7 +487,9 @@ void arp_send(int type, int ptype, u32 dest_ip,
/*
* Fill the device header for the ARP frame
*/
- dev->hard_header(skb,dev,ptype,dest_hw,src_hw,skb->len);
+ if (dev->hard_header &&
+ dev->hard_header(skb,dev,ptype,dest_hw,src_hw,skb->len) < 0)
+ goto out;
/*
* Fill out the arp protocol part.
@@ -552,6 +554,10 @@ void arp_send(int type, int ptype, u32 dest_ip,
skb->dev = dev;
dev_queue_xmit(skb);
+ return;
+
+out:
+ kfree_skb(skb);
}
static void parp_redo(struct sk_buff *skb)
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 11a8c319b..23389d249 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -5,7 +5,7 @@
*
* The Internet Protocol (IP) module.
*
- * Version: $Id: ip_input.c,v 1.44 2000/01/09 02:19:30 davem Exp $
+ * Version: $Id: ip_input.c,v 1.45 2000/01/16 05:11:22 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -317,13 +317,12 @@ static inline int ip_rcv_finish(struct sk_buff *skb)
#ifdef CONFIG_NET_CLS_ROUTE
if (skb->dst->tclassid) {
+ struct ip_rt_acct *st = ip_rt_acct + 256*smp_processor_id();
u32 idx = skb->dst->tclassid;
- write_lock(&ip_rt_acct_lock);
- ip_rt_acct[idx&0xFF].o_packets++;
- ip_rt_acct[idx&0xFF].o_bytes+=skb->len;
- ip_rt_acct[(idx>>16)&0xFF].i_packets++;
- ip_rt_acct[(idx>>16)&0xFF].i_bytes+=skb->len;
- write_unlock(&ip_rt_acct_lock);
+ st[idx&0xFF].o_packets++;
+ st[idx&0xFF].o_bytes+=skb->len;
+ st[(idx>>16)&0xFF].i_packets++;
+ st[(idx>>16)&0xFF].i_bytes+=skb->len;
}
#endif
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 59e6ff865..2a4e3cf41 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -5,7 +5,7 @@
*
* The Internet Protocol (IP) output module.
*
- * Version: $Id: ip_output.c,v 1.77 2000/01/09 02:19:31 davem Exp $
+ * Version: $Id: ip_output.c,v 1.78 2000/01/16 05:11:22 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -149,8 +149,8 @@ output_maybe_reroute(struct sk_buff *skb)
/*
* Add an ip header to a skbuff and send it out.
*/
-void ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
- u32 saddr, u32 daddr, struct ip_options *opt)
+int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
+ u32 saddr, u32 daddr, struct ip_options *opt)
{
struct rtable *rt = (struct rtable *)skb->dst;
struct iphdr *iph;
@@ -182,8 +182,8 @@ void ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
ip_send_check(iph);
/* Send it out. */
- NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
- output_maybe_reroute);
+ return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+ output_maybe_reroute);
}
static inline int ip_finish_output2(struct sk_buff *skb)
@@ -257,7 +257,7 @@ int ip_mc_output(struct sk_buff *skb)
{
struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
if (newskb)
- NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, newskb, NULL,
+ NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL,
newskb->dev,
ip_dev_loopback_xmit);
}
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index c618689b2..90b74447f 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -5,7 +5,7 @@
*
* The IP to API glue.
*
- * Version: $Id: ip_sockglue.c,v 1.46 2000/01/09 02:19:32 davem Exp $
+ * Version: $Id: ip_sockglue.c,v 1.47 2000/01/16 05:11:23 davem Exp $
*
* Authors: see ip.c
*
@@ -415,7 +415,7 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
if (sk->family == PF_INET ||
- ((tcp_connected(sk->state) || sk->state == TCP_SYN_SENT)
+ (!((1<<sk->state)&(TCPF_LISTEN|TCPF_CLOSE))
&& sk->daddr != LOOPBACK4_IPV6)) {
#endif
if (opt)
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 4d2195312..d4d556cb5 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -534,7 +534,14 @@ static void __init ic_bootp_send_if(struct ic_device *d, u32 jiffies)
/* Construct BOOTP header */
b->op = BOOTP_REQUEST;
- b->htype = dev->type;
+ if (dev->type < 256) /* check for false types */
+ b->htype = dev->type;
+ else if (dev->type == ARPHRD_IEEE802_TR) /* fix for token ring */
+ b->htype = ARPHRD_IEEE802;
+ else {
+ printk("Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name);
+ b->htype = dev->type; /* can cause undefined behavior */
+ }
b->hlen = dev->addr_len;
memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);
b->secs = htons(jiffies / HZ);
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index b3e86f58c..d6a7c57f5 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -7,7 +7,7 @@
* PROC file system. It is mainly used for debugging and
* statistics.
*
- * Version: $Id: proc.c,v 1.38 2000/01/09 02:19:30 davem Exp $
+ * Version: $Id: proc.c,v 1.41 2000/01/21 23:45:57 davem Exp $
*
* Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de>
@@ -71,8 +71,9 @@ int afinet_get_info(char *buffer, char **start, off_t offset, int length)
int len = socket_get_info(buffer,start,offset,length);
- len += sprintf(buffer+len,"TCP: inuse %d\n",
- fold_prot_inuse(&tcp_prot));
+ len += sprintf(buffer+len,"TCP: inuse %d orphan %d tw %d\n",
+ fold_prot_inuse(&tcp_prot),
+ atomic_read(&tcp_orphan_count), tcp_tw_count);
len += sprintf(buffer+len,"UDP: inuse %d\n",
fold_prot_inuse(&udp_prot));
len += sprintf(buffer+len,"RAW: inuse %d\n",
@@ -163,7 +164,14 @@ int netstat_get_info(char *buffer, char **start, off_t offset, int length)
len = sprintf(buffer,
"TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed"
" EmbryonicRsts PruneCalled RcvPruned OfoPruned"
- " OutOfWindowIcmps LockDroppedIcmps\n"
+ " OutOfWindowIcmps LockDroppedIcmps"
+ " TW TWRecycled TWKilled"
+ " PAWSPassive PAWSActive PAWSEstab"
+ " DelayedACKs DelayedACKLocked DelayedACKLost"
+ " ListenOverflows ListenDrops"
+ " TCPPrequeued TCPDirectCopyFromBacklog"
+ " TCPDirectCopyFromPrequeue TCPPrequeueDropped"
+ " TCPHPHits TCPHPHitsToUser\n"
"TcpExt:");
for (i=0; i<offsetof(struct linux_mib, __pad)/sizeof(unsigned long); i++)
len += sprintf(buffer+len, " %lu", fold_field((unsigned long*)net_statistics, sizeof(struct linux_mib), i));
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 6fc5e59c5..e9aa1952a 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -5,7 +5,7 @@
*
* RAW - implementation of IP "raw" sockets.
*
- * Version: $Id: raw.c,v 1.46 2000/01/09 02:19:30 davem Exp $
+ * Version: $Id: raw.c,v 1.48 2000/01/18 08:24:15 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -648,10 +648,6 @@ struct proto raw_prot = {
udp_connect, /* connect */
udp_disconnect, /* disconnect */
NULL, /* accept */
- NULL, /* retransmit */
- NULL, /* write_wakeup */
- NULL, /* read_wakeup */
- datagram_poll, /* poll */
#ifdef CONFIG_IP_MROUTE
ipmr_ioctl, /* ioctl */
#else
@@ -669,7 +665,5 @@ struct proto raw_prot = {
raw_v4_hash, /* hash */
raw_v4_unhash, /* unhash */
NULL, /* get_port */
- 128, /* max_header */
- 0, /* retransmits */
"RAW", /* name */
};
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index add42730d..bbc6ec111 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -5,7 +5,7 @@
*
* ROUTE - implementation of the IP router.
*
- * Version: $Id: route.c,v 1.78 2000/01/13 00:06:58 davem Exp $
+ * Version: $Id: route.c,v 1.80 2000/01/21 06:37:27 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -1178,6 +1178,7 @@ ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr,
rth->u.dst.output= ip_rt_bug;
atomic_set(&rth->u.dst.__refcnt, 1);
+ rth->u.dst.flags= DST_HOST;
rth->key.dst = daddr;
rth->rt_dst = daddr;
rth->key.tos = tos;
@@ -1385,6 +1386,7 @@ int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
goto e_nobufs;
atomic_set(&rth->u.dst.__refcnt, 1);
+ rth->u.dst.flags= DST_HOST;
rth->key.dst = daddr;
rth->rt_dst = daddr;
rth->key.tos = tos;
@@ -1462,6 +1464,7 @@ local_input:
rth->u.dst.output= ip_rt_bug;
atomic_set(&rth->u.dst.__refcnt, 1);
+ rth->u.dst.flags= DST_HOST;
rth->key.dst = daddr;
rth->rt_dst = daddr;
rth->key.tos = tos;
@@ -1815,6 +1818,7 @@ make_route:
goto e_nobufs;
atomic_set(&rth->u.dst.__refcnt, 1);
+ rth->u.dst.flags= DST_HOST;
rth->key.dst = daddr;
rth->key.tos = tos;
rth->key.src = saddr;
@@ -2208,8 +2212,7 @@ ctl_table ipv4_route_table[] = {
#endif
#ifdef CONFIG_NET_CLS_ROUTE
-struct ip_rt_acct ip_rt_acct[256];
-rwlock_t ip_rt_acct_lock = RW_LOCK_UNLOCKED;
+struct ip_rt_acct *ip_rt_acct;
#ifdef CONFIG_PROC_FS
static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
@@ -2217,14 +2220,34 @@ static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
{
*start=buffer;
- if (offset + length > sizeof(ip_rt_acct)) {
- length = sizeof(ip_rt_acct) - offset;
+ if ((offset&3) || (length&3))
+ return -EIO;
+
+ if (offset + length >= sizeof(struct ip_rt_acct)*256) {
+ length = sizeof(struct ip_rt_acct)*256 - offset;
*eof = 1;
}
if (length > 0) {
- read_lock_bh(&ip_rt_acct_lock);
- memcpy(buffer, ((u8*)&ip_rt_acct)+offset, length);
- read_unlock_bh(&ip_rt_acct_lock);
+ u32 *dst = (u32*)buffer;
+ u32 *src = (u32*)(((u8*)ip_rt_acct) + offset);
+
+ memcpy(dst, src, length);
+
+#ifdef __SMP__
+ if (smp_num_cpus > 1) {
+ int i;
+ int cnt = length/4;
+
+ for (i=1; i<smp_num_cpus; i++) {
+ int k;
+
+ src += (256/4)*sizeof(struct ip_rt_acct);
+
+ for (k=0; k<cnt; k++)
+ dst[k] += src[k];
+ }
+ }
+#endif
return length;
}
return 0;
@@ -2236,6 +2259,16 @@ void __init ip_rt_init(void)
{
int i, order, goal;
+#ifdef CONFIG_NET_CLS_ROUTE
+ for (order=0;
+ (PAGE_SIZE<<order) < 256*sizeof(ip_rt_acct)*smp_num_cpus; order++)
+ /* NOTHING */;
+ ip_rt_acct = (struct ip_rt_acct *)__get_free_pages(GFP_KERNEL, order);
+ if (!ip_rt_acct)
+ panic("IP: failed to allocate ip_rt_acct\n");
+ memset(ip_rt_acct, 0, PAGE_SIZE<<order);
+#endif
+
ipv4_dst_ops.kmem_cachep = kmem_cache_create("ip_dst_cache",
sizeof(struct rtable),
0, SLAB_HWCACHE_ALIGN,
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index e82233cfd..d218c3bdb 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -9,7 +9,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * $Id: syncookies.c,v 1.10 2000/01/09 02:19:35 davem Exp $
+ * $Id: syncookies.c,v 1.11 2000/01/16 05:11:27 davem Exp $
*
* Missing: IPv6 support.
*/
@@ -102,23 +102,16 @@ static inline struct sock *
get_cookie_sock(struct sock *sk, struct sk_buff *skb, struct open_request *req,
struct dst_entry *dst)
{
- struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ struct sock *child;
- /* Oops! It was missing, syn_recv_sock decreases it. */
- tp->syn_backlog++;
+ child = tp->af_specific->syn_recv_sock(sk, skb, req, dst);
+ if (child)
+ tcp_acceptq_queue(sk, req, child);
+ else
+ tcp_openreq_free(req);
- sk = tp->af_specific->syn_recv_sock(sk, skb, req, dst);
- if (sk) {
- req->sk = sk;
-
- /* Queue up for accept() */
- tcp_synq_queue(tp, req);
- } else {
- tp->syn_backlog--;
- req->class->destructor(req);
- tcp_openreq_free(req);
- }
- return sk;
+ return child;
}
struct sock *
@@ -171,9 +164,9 @@ cookie_v4_check(struct sock *sk, struct sk_buff *skb, struct ip_options *opt)
}
}
}
-
+
req->snd_wscale = req->rcv_wscale = req->tstamp_ok = 0;
- req->wscale_ok = 0;
+ req->wscale_ok = req->sack_ok = 0;
req->expires = 0UL;
req->retrans = 0;
@@ -189,8 +182,8 @@ cookie_v4_check(struct sock *sk, struct sk_buff *skb, struct ip_options *opt)
req->af.v4_req.loc_addr,
sk->protinfo.af_inet.tos | RTO_CONN,
0)) {
- tcp_openreq_free(req);
- return NULL;
+ tcp_openreq_free(req);
+ return NULL;
}
/* Try to redo what tcp_v4_send_synack did. */
@@ -198,6 +191,7 @@ cookie_v4_check(struct sock *sk, struct sk_buff *skb, struct ip_options *opt)
tcp_select_initial_window(tcp_full_space(sk),req->mss,
&req->rcv_wnd, &req->window_clamp,
0, &rcv_wscale);
+ /* BTW win scale with syncookies is 0 by definition */
req->rcv_wscale = rcv_wscale;
return get_cookie_sock(sk, skb, req, &rt->u.dst);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 9465e4021..d9416525b 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -1,7 +1,7 @@
/*
* sysctl_net_ipv4.c: sysctl interface to net IPV4 subsystem.
*
- * $Id: sysctl_net_ipv4.c,v 1.42 2000/01/09 02:19:37 davem Exp $
+ * $Id: sysctl_net_ipv4.c,v 1.43 2000/01/16 05:11:27 davem Exp $
*
* Begun April 1, 1996, Mike Shaver.
* Added /proc/sys/net/ipv4 directory entry (empty =) ). [MS]
@@ -41,26 +41,6 @@ extern int sysctl_ipfrag_time;
/* From ip_output.c */
extern int sysctl_ip_dynaddr;
-/* From ip_masq.c */
-extern int sysctl_ip_masq_debug;
-
-extern int sysctl_tcp_timestamps;
-extern int sysctl_tcp_window_scaling;
-extern int sysctl_tcp_sack;
-extern int sysctl_tcp_retrans_collapse;
-extern int sysctl_tcp_keepalive_time;
-extern int sysctl_tcp_keepalive_probes;
-extern int sysctl_tcp_retries1;
-extern int sysctl_tcp_retries2;
-extern int sysctl_tcp_fin_timeout;
-extern int sysctl_tcp_syncookies;
-extern int sysctl_tcp_syn_retries;
-extern int sysctl_tcp_stdurg;
-extern int sysctl_tcp_rfc1337;
-extern int sysctl_tcp_syn_taildrop;
-extern int sysctl_max_syn_backlog;
-extern int sysctl_tcp_tw_recycle;
-
/* From icmp.c */
extern int sysctl_icmp_destunreach_time;
extern int sysctl_icmp_timeexceed_time;
@@ -142,6 +122,12 @@ ctl_table ipv4_table[] = {
&proc_dointvec},
{NET_IPV4_TCP_SYN_RETRIES, "tcp_syn_retries",
&sysctl_tcp_syn_retries, sizeof(int), 0644, NULL, &proc_dointvec},
+ {NET_TCP_SYNACK_RETRIES, "tcp_synack_retries",
+ &sysctl_tcp_synack_retries, sizeof(int), 0644, NULL, &proc_dointvec},
+ {NET_TCP_MAX_ORPHANS, "tcp_max_orphans",
+ &sysctl_tcp_max_orphans, sizeof(int), 0644, NULL, &proc_dointvec},
+ {NET_TCP_MAX_TW_BUCKETS, "tcp_max_tw_buckets",
+ &sysctl_tcp_max_tw_buckets, sizeof(int), 0644, NULL, &proc_dointvec},
{NET_IPV4_IPFRAG_HIGH_THRESH, "ipfrag_high_thresh",
&sysctl_ipfrag_high_thresh, sizeof(int), 0644, NULL, &proc_dointvec},
{NET_IPV4_IPFRAG_LOW_THRESH, "ipfrag_low_thresh",
@@ -172,10 +158,10 @@ ctl_table ipv4_table[] = {
{NET_TCP_SYNCOOKIES, "tcp_syncookies",
&sysctl_tcp_syncookies, sizeof(int), 0644, NULL, &proc_dointvec},
#endif
-#ifdef CONFIG_TCP_TW_RECYCLE
{NET_TCP_TW_RECYCLE, "tcp_tw_recycle",
&sysctl_tcp_tw_recycle, sizeof(int), 0644, NULL, &proc_dointvec},
-#endif
+ {NET_TCP_ABORT_ON_OVERFLOW, "tcp_abort_on_overflow",
+ &sysctl_tcp_abort_on_overflow, sizeof(int), 0644, NULL, &proc_dointvec},
{NET_TCP_STDURG, "tcp_stdurg", &sysctl_tcp_stdurg,
sizeof(int), 0644, NULL, &proc_dointvec},
{NET_TCP_RFC1337, "tcp_rfc1337", &sysctl_tcp_rfc1337,
@@ -221,6 +207,8 @@ ctl_table ipv4_table[] = {
{NET_IPV4_INET_PEER_GC_MAXTIME, "inet_peer_gc_maxtime",
&inet_peer_gc_maxtime, sizeof(int), 0644, NULL,
&proc_dointvec_jiffies, &sysctl_jiffies},
+ {NET_TCP_ORPHAN_RETRIES, "tcp_orphan_retries",
+ &sysctl_tcp_orphan_retries, sizeof(int), 0644, NULL, &proc_dointvec},
{0}
};
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 8e24e19a4..e01892326 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp.c,v 1.153 2000/01/09 02:19:33 davem Exp $
+ * Version: $Id: tcp.c,v 1.160 2000/01/24 18:40:32 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -202,6 +202,8 @@
* Eric Schenk : Fix fast close down bug with
* shutdown() followed by close().
* Andi Kleen : Make poll agree with SIGIO
+ * Salvatore Sanfilippo : Support SO_LINGER with linger == 1 and
+ * lingertime == 0 (RFC 793 ABORT Call)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -432,113 +434,14 @@ kmem_cache_t *tcp_openreq_cachep;
kmem_cache_t *tcp_bucket_cachep;
kmem_cache_t *tcp_timewait_cachep;
-/*
- * Find someone to 'accept'. Must be called with
- * the listening socket locked.
- */
-
-static struct open_request *tcp_find_established(struct tcp_opt *tp,
- struct open_request **prevp)
-{
- struct open_request *req = tp->syn_wait_queue;
- struct open_request *prev = (struct open_request *)&tp->syn_wait_queue;
- while(req) {
- if (req->sk) {
- if((1 << req->sk->state) &
- ~(TCPF_SYN_SENT|TCPF_SYN_RECV))
- break;
- }
- prev = req;
- req = req->dl_next;
- }
- *prevp = prev;
- return req;
-}
-
-/*
- * Walk down the receive queue counting readable data.
- *
- * Must be called with the socket lock held.
- */
-
-static int tcp_readable(struct sock *sk)
-{
- unsigned long counted;
- unsigned long amount;
- struct sk_buff *skb;
- int sum;
-
- SOCK_DEBUG(sk, "tcp_readable: %p - ",sk);
-
- skb = skb_peek(&sk->receive_queue);
- if (skb == NULL) {
- SOCK_DEBUG(sk, "empty\n");
- return(0);
- }
-
- counted = sk->tp_pinfo.af_tcp.copied_seq; /* Where we are at the moment */
- amount = 0;
-
- /* Do until a push or until we are out of data. */
- do {
- /* Found a hole so stops here. */
- if (before(counted, TCP_SKB_CB(skb)->seq)) /* should not happen */
- break;
-
- /* Length - header but start from where we are up to
- * avoid overlaps.
- */
- sum = skb->len - (counted - TCP_SKB_CB(skb)->seq);
- if (sum >= 0) {
- /* Add it up, move on. */
- amount += sum;
- counted += sum;
- if (skb->h.th->syn)
- counted++;
- }
-
- /* Don't count urg data ... but do it in the right place!
- * Consider: "old_data (ptr is here) URG PUSH data"
- * The old code would stop at the first push because
- * it counted the urg (amount==1) and then does amount--
- * *after* the loop. This means tcp_readable() always
- * returned zero if any URG PUSH was in the queue, even
- * though there was normal data available. If we subtract
- * the urg data right here, we even get it to work for more
- * than one URG PUSH skb without normal data.
- * This means that poll() finally works now with urg data
- * in the queue. Note that rlogin was never affected
- * because it doesn't use poll(); it uses two processes
- * and a blocking read(). And the queue scan in tcp_read()
- * was correct. Mike <pall@rz.uni-karlsruhe.de>
- */
-
- /* Don't count urg data. */
- if (skb->h.th->urg)
- amount--;
-#if 0
- if (amount && skb->h.th->psh) break;
-#endif
- skb = skb->next;
- } while(skb != (struct sk_buff *)&sk->receive_queue);
-
- SOCK_DEBUG(sk, "got %lu bytes.\n",amount);
- return(amount);
-}
+atomic_t tcp_orphan_count = ATOMIC_INIT(0);
/*
* LISTEN is a special case for poll..
*/
-static unsigned int tcp_listen_poll(struct sock *sk, poll_table *wait)
+static __inline__ unsigned int tcp_listen_poll(struct sock *sk, poll_table *wait)
{
- struct open_request *req, *dummy;
-
- lock_sock(sk);
- req = tcp_find_established(&sk->tp_pinfo.af_tcp, &dummy);
- release_sock(sk);
- if (req)
- return POLLIN | POLLRDNORM;
- return 0;
+ return sk->tp_pinfo.af_tcp.accept_queue ? (POLLIN | POLLRDNORM) : 0;
}
/*
@@ -585,9 +488,25 @@ unsigned int tcp_poll(struct file * file, struct socket *sock, poll_table *wait)
* if you don't tell them that something has hung up!
*
* Check-me.
+ *
+ * Check number 1. POLLHUP is _UNMASKABLE_ event (see UNIX98 and
+ * our fs/select.c). It means that after we received EOF,
+ * poll always returns immediately, making impossible poll() on write()
+ * in state CLOSE_WAIT. One solution is evident --- to set POLLHUP
+ * if and only if shutdown has been made in both directions.
+ * Actually, it is interesting to look how Solaris and DUX
+ * solve this dilemma. I would prefer, if PULLHUP were maskable,
+ * then we could set it on SND_SHUTDOWN. BTW examples given
+ * in Stevens' books assume exactly this behaviour, it explains
+ * why PULLHUP is incompatible with POLLOUT. --ANK
+ *
+ * NOTE. Check for TCP_CLOSE is added. The goal is to prevent
+ * blocking on fresh not-connected or disconnected socket. --ANK
*/
- if (sk->shutdown & RCV_SHUTDOWN)
+ if (sk->shutdown == SHUTDOWN_MASK || sk->state == TCP_CLOSE)
mask |= POLLHUP;
+ if (sk->shutdown & RCV_SHUTDOWN)
+ mask |= POLLIN | POLLRDNORM;
/* Connected? */
if ((1 << sk->state) & ~(TCPF_SYN_SENT|TCPF_SYN_RECV)) {
@@ -605,7 +524,7 @@ unsigned int tcp_poll(struct file * file, struct socket *sock, poll_table *wait)
}
}
- if (tp->urg_data & URG_VALID)
+ if (tp->urg_data & TCP_URG_VALID)
mask |= POLLPRI;
}
return mask;
@@ -631,32 +550,48 @@ void tcp_write_space(struct sock *sk)
read_unlock(&sk->callback_lock);
}
+/* Listening TCP sockets never sleep to wait for memory, so
+ * it is completely silly to wake them up on queue space
+ * available events. So we hook them up to this dummy callback.
+ */
+static void tcp_listen_write_space(struct sock *sk)
+{
+}
int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
{
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
int answ;
switch(cmd) {
- case TIOCINQ:
-#ifdef FIXME /* FIXME: */
- case FIONREAD:
-#endif
+ case SIOCINQ:
if (sk->state == TCP_LISTEN)
return(-EINVAL);
+
lock_sock(sk);
- answ = tcp_readable(sk);
+ if ((1<<sk->state) & (TCPF_SYN_SENT|TCPF_SYN_RECV))
+ answ = 0;
+ else if (sk->urginline || !tp->urg_data ||
+ before(tp->urg_seq,tp->copied_seq) ||
+ !before(tp->urg_seq,tp->rcv_nxt))
+ answ = tp->rcv_nxt - tp->copied_seq;
+ else
+ answ = tp->urg_seq - tp->copied_seq;
release_sock(sk);
break;
case SIOCATMARK:
{
- struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
answ = tp->urg_data && tp->urg_seq == tp->copied_seq;
break;
}
- case TIOCOUTQ:
+ case SIOCOUTQ:
if (sk->state == TCP_LISTEN)
return(-EINVAL);
- answ = sock_wspace(sk);
+
+ if ((1<<sk->state) & (TCPF_SYN_SENT|TCPF_SYN_RECV))
+ answ = 0;
+ else
+ answ = tp->write_seq - tp->snd_una;
break;
default:
return(-ENOIOCTLCMD);
@@ -665,12 +600,131 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
return put_user(answ, (int *)arg);
}
+
+int tcp_listen_start(struct sock *sk)
+{
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ struct tcp_listen_opt *lopt;
+
+ sk->max_ack_backlog = 0;
+ sk->ack_backlog = 0;
+ tp->accept_queue = NULL;
+ tp->syn_wait_lock = RW_LOCK_UNLOCKED;
+
+ lopt = kmalloc(sizeof(struct tcp_listen_opt), GFP_KERNEL);
+ if (!lopt)
+ return -ENOMEM;
+
+ memset(lopt, 0, sizeof(struct tcp_listen_opt));
+ for (lopt->max_qlen_log = 6; ; lopt->max_qlen_log++)
+ if ((1<<lopt->max_qlen_log) >= sysctl_max_syn_backlog)
+ break;
+
+ write_lock_bh(&tp->syn_wait_lock);
+ tp->listen_opt = lopt;
+ write_unlock_bh(&tp->syn_wait_lock);
+
+ sk->state = TCP_LISTEN;
+ if (sk->num == 0) {
+ if (sk->prot->get_port(sk, 0) != 0) {
+ sk->state = TCP_CLOSE;
+ write_lock_bh(&tp->syn_wait_lock);
+ tp->listen_opt = NULL;
+ write_unlock_bh(&tp->syn_wait_lock);
+ kfree(lopt);
+ return -EAGAIN;
+ }
+ sk->sport = htons(sk->num);
+ } else {
+ if (sk->prev)
+ ((struct tcp_bind_bucket*)sk->prev)->fastreuse = 0;
+ }
+
+ sk_dst_reset(sk);
+ sk->prot->hash(sk);
+ sk->socket->flags |= SO_ACCEPTCON;
+ sk->write_space = tcp_listen_write_space;
+
+ return 0;
+}
+
+/*
+ * This routine closes sockets which have been at least partially
+ * opened, but not yet accepted.
+ */
+
+static void tcp_listen_stop (struct sock *sk)
+{
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ struct tcp_listen_opt *lopt = tp->listen_opt;
+ struct open_request *acc_req = tp->accept_queue;
+ struct open_request *req;
+ int i;
+
+ tcp_delete_keepalive_timer(sk);
+
+ /* make all the listen_opt local to us */
+ write_lock_bh(&tp->syn_wait_lock);
+ tp->listen_opt =NULL;
+ write_unlock_bh(&tp->syn_wait_lock);
+ tp->accept_queue = NULL;
+
+ if (lopt->qlen) {
+ for (i=0; i<TCP_SYNQ_HSIZE; i++) {
+ while ((req = lopt->syn_table[i]) != NULL) {
+ lopt->syn_table[i] = req->dl_next;
+ lopt->qlen--;
+ tcp_openreq_free(req);
+
+ /* Following specs, it would be better either to send FIN
+ * (and enter FIN-WAIT-1, it is normal close)
+ * or to send active reset (abort).
+ * Certainly, it is pretty dangerous while synflood, but it is
+ * bad justification for our negligence 8)
+ * To be honest, we are not able to make either
+ * of the variants now. --ANK
+ */
+ }
+ }
+ }
+ BUG_TRAP(lopt->qlen == 0);
+
+ kfree(lopt);
+
+ while ((req=acc_req) != NULL) {
+ struct sock *child = req->sk;
+
+ acc_req = req->dl_next;
+
+ local_bh_disable();
+ bh_lock_sock(child);
+ BUG_TRAP(child->lock.users==0);
+ sock_hold(child);
+
+ tcp_disconnect(child, O_NONBLOCK);
+
+ sock_orphan(child);
+
+ atomic_inc(&tcp_orphan_count);
+
+ tcp_destroy_sock(child);
+
+ bh_unlock_sock(child);
+ local_bh_enable();
+ sock_put(child);
+
+ tcp_acceptq_removed(sk);
+ tcp_openreq_fastfree(req);
+ }
+ BUG_TRAP(sk->ack_backlog == 0);
+}
+
/*
* Wait for a socket to get into the connected state
*
* Note: Must be called with the socket locked.
*/
-static int wait_for_tcp_connect(struct sock * sk, int flags)
+static int wait_for_tcp_connect(struct sock * sk, int flags, long *timeo_p)
{
struct task_struct *tsk = current;
DECLARE_WAITQUEUE(wait, tsk);
@@ -684,7 +738,7 @@ static int wait_for_tcp_connect(struct sock * sk, int flags)
send_sig(SIGPIPE, tsk, 0);
return -EPIPE;
}
- if(flags & MSG_DONTWAIT)
+ if(!*timeo_p)
return -EAGAIN;
if(signal_pending(tsk))
return -ERESTARTSYS;
@@ -694,7 +748,7 @@ static int wait_for_tcp_connect(struct sock * sk, int flags)
sk->tp_pinfo.af_tcp.write_pending++;
release_sock(sk);
- schedule();
+ *timeo_p = schedule_timeout(*timeo_p);
lock_sock(sk);
__set_task_state(tsk, TASK_RUNNING);
@@ -712,7 +766,7 @@ static inline int tcp_memory_free(struct sock *sk)
/*
* Wait for more memory for a socket
*/
-static void wait_for_tcp_memory(struct sock * sk)
+static long wait_for_tcp_memory(struct sock * sk, long timeo)
{
if (!tcp_memory_free(sk)) {
DECLARE_WAITQUEUE(wait, current);
@@ -732,12 +786,13 @@ static void wait_for_tcp_memory(struct sock * sk)
break;
release_sock(sk);
if (!tcp_memory_free(sk))
- schedule();
+ timeo = schedule_timeout(timeo);
lock_sock(sk);
}
current->state = TASK_RUNNING;
remove_wait_queue(sk->sleep, &wait);
}
+ return timeo;
}
/* When all user supplied data has been queued set the PSH bit */
@@ -746,11 +801,9 @@ static void wait_for_tcp_memory(struct sock * sk)
/*
* This routine copies from a user buffer into a socket,
* and starts the transmit system.
- *
- * Note: must be called with the socket locked.
*/
-int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg)
+int tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
{
struct iovec *iov;
struct tcp_opt *tp;
@@ -758,15 +811,22 @@ int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg)
int iovlen, flags;
int mss_now;
int err, copied;
+ long timeo;
err = 0;
tp = &(sk->tp_pinfo.af_tcp);
- /* Wait for a connection to finish. */
+ lock_sock(sk);
+ TCP_CHECK_TIMER(sk);
+
flags = msg->msg_flags;
+
+ timeo = sock_sndtimeo(sk, flags&MSG_DONTWAIT);
+
+ /* Wait for a connection to finish. */
if ((1 << sk->state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))
- if((err = wait_for_tcp_connect(sk, flags)) != 0)
- goto out;
+ if((err = wait_for_tcp_connect(sk, flags, &timeo)) != 0)
+ goto out_unlock;
/* This should be in poll */
sk->socket->flags &= ~SO_NOSPACE; /* clear SIGIO XXX */
@@ -777,7 +837,7 @@ int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg)
iovlen = msg->msg_iovlen;
iov = msg->msg_iov;
copied = 0;
-
+
while(--iovlen >= 0) {
int seglen=iov->iov_len;
unsigned char * from=iov->iov_base;
@@ -785,7 +845,7 @@ int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg)
iov++;
while(seglen > 0) {
- int copy, tmp, queue_it, psh;
+ int copy, tmp, queue_it;
if (err)
goto do_fault2;
@@ -811,8 +871,7 @@ int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg)
* welcome.
*/
if (skb_tailroom(skb) > 0 &&
- (mss_now - copy) > 0 &&
- tp->snd_nxt < TCP_SKB_CB(skb)->end_seq) {
+ (mss_now - copy) > 0) {
int last_byte_was_odd = (copy % 4);
copy = mss_now - copy;
@@ -855,34 +914,17 @@ int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg)
}
}
- /* We also need to worry about the window. If
- * window < 1/2 the maximum window we've seen
- * from this host, don't use it. This is
- * sender side silly window prevention, as
- * specified in RFC1122. (Note that this is
- * different than earlier versions of SWS
- * prevention, e.g. RFC813.). What we
- * actually do is use the whole MSS. Since
- * the results in the right edge of the packet
- * being outside the window, it will be queued
- * for later rather than sent.
+ /* A chunk was here doing something strange
+ * with psh etc. It is deleted, because it was
+ * evident non-sense. --ANK
*/
- psh = 0;
- copy = tp->snd_wnd - (tp->snd_nxt - tp->snd_una);
- if(copy > (tp->max_window >> 1)) {
- copy = min(copy, mss_now);
- psh = 1;
- } else {
- copy = mss_now;
- }
- if(copy > seglen)
- copy = seglen;
+
+ copy = min(seglen, mss_now);
/* Determine how large of a buffer to allocate. */
- tmp = MAX_HEADER + sk->prot->max_header;
- if (copy < min(mss_now, tp->max_window >> 1) &&
- !(flags & MSG_OOB)) {
- tmp += min(mss_now, tp->max_window);
+ tmp = MAX_TCP_HEADER + 15;
+ if (copy < mss_now && !(flags & MSG_OOB)) {
+ tmp += mss_now;
/* What is happening here is that we want to
* tack on later members of the users iovec
@@ -901,7 +943,7 @@ int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg)
/* If we didn't get any memory, we need to sleep. */
if (skb == NULL) {
sk->socket->flags |= SO_NOSPACE;
- if (flags&MSG_DONTWAIT) {
+ if (!timeo) {
err = -EAGAIN;
goto do_interrupted;
}
@@ -909,8 +951,8 @@ int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg)
err = -ERESTARTSYS;
goto do_interrupted;
}
- tcp_push_pending_frames(sk, tp);
- wait_for_tcp_memory(sk);
+ __tcp_push_pending_frames(sk, tp, mss_now);
+ timeo = wait_for_tcp_memory(sk, timeo);
/* If SACK's were formed or PMTU events happened,
* we must find out about it.
@@ -923,7 +965,7 @@ int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg)
/* Prepare control bits for TCP header creation engine. */
TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK |
- ((PSH_NEEDED || psh) ?
+ ((PSH_NEEDED) ?
TCPCB_FLAG_PSH : 0));
TCP_SKB_CB(skb)->sacked = 0;
if (flags & MSG_OOB) {
@@ -936,7 +978,7 @@ int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg)
* TCP+IP+DEV headers are SKB_PUSH()'d beneath.
* Reserve header space and checksum the data.
*/
- skb_reserve(skb, MAX_HEADER + sk->prot->max_header);
+ skb_reserve(skb, MAX_TCP_HEADER);
skb->csum = csum_and_copy_from_user(from,
skb_put(skb, copy), copy, 0, &err);
@@ -950,7 +992,7 @@ int tcp_do_sendmsg(struct sock *sk, struct msghdr *msg)
TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + copy;
/* This advances tp->write_seq for us. */
- tcp_send_skb(sk, skb, queue_it);
+ tcp_send_skb(sk, skb, queue_it, mss_now);
}
}
sk->err = 0;
@@ -981,63 +1023,39 @@ do_fault:
do_fault2:
err = -EFAULT;
out:
- tcp_push_pending_frames(sk, tp);
+ __tcp_push_pending_frames(sk, tp, mss_now);
+ TCP_CHECK_TIMER(sk);
+out_unlock:
+ release_sock(sk);
return err;
}
#undef PSH_NEEDED
/*
- * Send an ack if one is backlogged at this point. Ought to merge
- * this with tcp_send_ack().
- * This is called for delayed acks also.
- */
-
-void tcp_read_wakeup(struct sock *sk)
-{
- /* If we're closed, don't send an ack, or we'll get a RST
- * from the closed destination.
- */
- if (sk->state != TCP_CLOSE)
- tcp_send_ack(sk);
-}
-
-/*
* Handle reading urgent data. BSD has very simple semantics for
* this, no blocking and very strange errors 8)
*/
-static int tcp_recv_urg(struct sock * sk, int nonblock,
+static int tcp_recv_urg(struct sock * sk, long timeo,
struct msghdr *msg, int len, int flags,
int *addr_len)
{
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
/* No URG data to read. */
- if (sk->urginline || !tp->urg_data || tp->urg_data == URG_READ)
+ if (sk->urginline || !tp->urg_data || tp->urg_data == TCP_URG_READ)
return -EINVAL; /* Yes this is right ! */
if (sk->done)
return -ENOTCONN;
- if (sk->state == TCP_CLOSE || (sk->shutdown & RCV_SHUTDOWN)) {
- sk->done = 1;
- return 0;
- }
-
- if (tp->urg_data & URG_VALID) {
+ if (tp->urg_data & TCP_URG_VALID) {
int err = 0;
char c = tp->urg_data;
if (!(flags & MSG_PEEK))
- tp->urg_data = URG_READ;
-
- if(msg->msg_name)
- tp->af_specific->addr2sockaddr(sk, (struct sockaddr *)
- msg->msg_name);
-
- if(addr_len)
- *addr_len = tp->af_specific->sockaddr_len;
+ tp->urg_data = TCP_URG_READ;
/* Read urgent data. */
msg->msg_flags|=MSG_OOB;
@@ -1051,6 +1069,10 @@ static int tcp_recv_urg(struct sock * sk, int nonblock,
return err ? -EFAULT : len;
}
+ /* Do not set sk->done, it is set only by normal data receive */
+ if (sk->state == TCP_CLOSE || (sk->shutdown & RCV_SHUTDOWN))
+ return 0;
+
/* Fixed the recv(..., MSG_OOB) behaviour. BSD docs and
* the available implementations agree in this case:
* this call should never block, independent of the
@@ -1069,6 +1091,8 @@ static int tcp_recv_urg(struct sock * sk, int nonblock,
static inline void tcp_eat_skb(struct sock *sk, struct sk_buff * skb)
{
__skb_unlink(skb, &sk->receive_queue);
+ BUG_TRAP(atomic_read(&skb->users) == 1);
+ /* Well, if I missed something then punishment will be terrible oops. */
__kfree_skb(skb);
}
@@ -1080,22 +1104,34 @@ static inline void tcp_eat_skb(struct sock *sk, struct sk_buff * skb)
*/
static void cleanup_rbuf(struct sock *sk, int copied)
{
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
struct sk_buff *skb;
+ int time_to_ack;
/* NOTE! The socket must be locked, so that we don't get
* a messed-up receive queue.
*/
while ((skb=skb_peek(&sk->receive_queue)) != NULL) {
- if (!skb->used || atomic_read(&skb->users) > 1)
+ if (!skb->used)
break;
tcp_eat_skb(sk, skb);
}
+ /* Delayed ACKs frequently hit locked sockets during bulk receive. */
+ time_to_ack = tp->ack.blocked && tp->ack.pending;
+#if 1/*def CONFIG_TCP_MORE_COARSE_ACKS*/
+ if (tp->ack.pending &&
+ (tp->rcv_nxt - tp->rcv_wup) > tp->ack.rcv_mss)
+ time_to_ack = 1;
+#endif
+
/* We send an ACK if we can now advertise a non-zero window
* which has been raised "significantly".
+ *
+ * Even if window raised up to infinity, do not send window open ACK
+ * in states, where we will not receive more. It is useless.
*/
- if(copied > 0) {
- struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ if(copied > 0 && !time_to_ack && !(sk->shutdown&RCV_SHUTDOWN)) {
__u32 rcv_window_now = tcp_receive_window(tp);
__u32 new_window = __tcp_select_window(sk);
@@ -1106,16 +1142,20 @@ static void cleanup_rbuf(struct sock *sk, int copied)
* which don't advertize a larger window.
*/
if((new_window && (new_window >= rcv_window_now * 2)) &&
- ((rcv_window_now + tp->mss_cache) <= tp->window_clamp))
- tcp_read_wakeup(sk);
+ ((rcv_window_now + tp->ack.rcv_mss) <= tp->window_clamp))
+ time_to_ack = 1;
}
+ if (time_to_ack)
+ tcp_send_ack(sk);
}
/* Now socket state including sk->err is changed only under lock,
- hence we should check only pending signals.
+ * hence we may omit checks after joining wait queue.
+ * We check receive queue before schedule() only as optimization;
+ * it is very likely that release_sock() added new data.
*/
-static void tcp_data_wait(struct sock *sk)
+static long tcp_data_wait(struct sock *sk, long timeo)
{
DECLARE_WAITQUEUE(wait, current);
@@ -1127,17 +1167,39 @@ static void tcp_data_wait(struct sock *sk)
release_sock(sk);
if (skb_queue_empty(&sk->receive_queue))
- schedule();
+ timeo = schedule_timeout(timeo);
lock_sock(sk);
sk->socket->flags &= ~SO_WAITDATA;
remove_wait_queue(sk->sleep, &wait);
__set_current_state(TASK_RUNNING);
+ return timeo;
+}
+
+static void tcp_prequeue_process(struct sock *sk)
+{
+ struct sk_buff *skb;
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+
+ net_statistics[smp_processor_id()*2+1].TCPPrequeued += skb_queue_len(&tp->ucopy.prequeue);
+
+ /* RX process wants to run with disabled BHs, though it is not necessary */
+ local_bh_disable();
+ while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL)
+ sk->backlog_rcv(sk, skb);
+ local_bh_enable();
+
+ /* Clear memory counter. */
+ tp->ucopy.memory = 0;
}
/*
* This routine copies from a sock struct into the user buffer.
+ *
+ * Technical note: in 2.3 we work on _locked_ socket, so that
+ * tricks with *seq access order and skb->users are not required.
+ * Probably, code can be easily improved even more.
*/
int tcp_recvmsg(struct sock *sk, struct msghdr *msg,
@@ -1146,13 +1208,18 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg,
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
int copied = 0;
u32 peek_seq;
- volatile u32 *seq; /* So gcc doesn't overoptimise */
+ u32 *seq;
unsigned long used;
int err;
- int target = 1; /* Read at least this many bytes */
+ int target; /* Read at least this many bytes */
+ long timeo;
+ struct task_struct *user_recv = NULL;
lock_sock(sk);
+ TCP_CHECK_TIMER(sk);
+
+
if (sk->err)
goto out_err;
@@ -1160,24 +1227,20 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg,
if (sk->state == TCP_LISTEN)
goto out;
+ timeo = sock_rcvtimeo(sk, nonblock);
+
/* Urgent data needs to be handled specially. */
if (flags & MSG_OOB)
goto recv_urg;
- /* Copying sequence to update. This is volatile to handle
- * the multi-reader case neatly (memcpy_to/fromfs might be
- * inline and thus not flush cached variables otherwise).
- */
- peek_seq = tp->copied_seq;
seq = &tp->copied_seq;
- if (flags & MSG_PEEK)
+ if (flags & MSG_PEEK) {
+ peek_seq = tp->copied_seq;
seq = &peek_seq;
+ }
- /* Handle the POSIX bogosity MSG_WAITALL. */
- if (flags & MSG_WAITALL)
- target=len;
+ target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
-
/*
* BUG BUG BUG
* This violates 1003.1g compliance. We must wait for
@@ -1200,7 +1263,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg,
if (copied)
break;
copied = -ERESTARTSYS;
- if (nonblock)
+ if (!timeo)
copied = -EAGAIN;
break;
}
@@ -1232,47 +1295,128 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg,
skb = skb->next;
} while (skb != (struct sk_buff *)&sk->receive_queue);
- if (copied >= target)
+ /* Well, if we have backlog, try to process it now yet. */
+
+ if (copied >= target && sk->backlog.tail == NULL)
break;
- if (sk->err && !(flags&MSG_PEEK)) {
- if (!copied)
+ if (copied) {
+ if (sk->err ||
+ sk->state == TCP_CLOSE ||
+ (sk->shutdown & RCV_SHUTDOWN) ||
+ !timeo)
+ break;
+ } else {
+ if (sk->err) {
copied = sock_error(sk);
- break;
- }
+ break;
+ }
- if (sk->shutdown & RCV_SHUTDOWN) {
- sk->done = 1;
- break;
- }
+ if (sk->done) {
+ copied = -ENOTCONN;
+ break;
+ }
- if (sk->state == TCP_CLOSE) {
- if (!sk->done) {
- sk->done = 1;
+ if (sk->state == TCP_CLOSE) {
+ if (!(flags&MSG_PEEK))
+ sk->done = 1;
break;
}
- if (!copied)
- copied = -ENOTCONN;
- break;
- }
- if (nonblock) {
- copied = -EAGAIN;
- break;
+ if (sk->shutdown & RCV_SHUTDOWN)
+ break;
+
+ if (!timeo) {
+ copied = -EAGAIN;
+ break;
+ }
}
cleanup_rbuf(sk, copied);
- tcp_data_wait(sk);
+
+ if (tp->ucopy.task == user_recv) {
+ /* Install new reader */
+ if (user_recv == NULL && !(flags&MSG_PEEK)) {
+ user_recv = current;
+ tp->ucopy.task = user_recv;
+ tp->ucopy.iov = msg->msg_iov;
+ }
+
+ tp->ucopy.len = len;
+
+ BUG_TRAP(tp->copied_seq == tp->rcv_nxt);
+
+ /* Ugly... If prequeue is not empty, we have to
+ * process it before releasing socket, otherwise
+ * order will be broken at second iteration.
+ * More elegant solution is required!!!
+ *
+ * Look: we have the following (pseudo)queues:
+ *
+ * 1. packets in flight
+ * 2. backlog
+ * 3. prequeue
+ * 4. receive_queue
+ *
+ * Each queue can be processed only if the next ones
+ * are empty. At this point we have empty receive_queue.
+ * But prequeue _can_ be not empty after second iteration,
+ * when we jumped to start of loop because backlog
+ * processing added something to receive_queue.
+ * We cannot release_sock(), because backlog contains
+ * packets arrived _after_ prequeued ones.
+ *
+ * Shortly, algorithm is clear --- to process all
+ * the queues in order. We could make it more directly,
+ * requeueing packets from backlog to prequeue, if
+ * is not empty. It is more elegant, but eats cycles,
+ * unfortunately.
+ */
+ if (skb_queue_len(&tp->ucopy.prequeue))
+ goto do_prequeue;
+
+ /* __ Set realtime policy in scheduler __ */
+ }
+
+ if (copied >= target) {
+ /* Do not sleep, just process backlog. */
+ release_sock(sk);
+ lock_sock(sk);
+ } else {
+ timeo = tcp_data_wait(sk, timeo);
+ }
+
+ if (user_recv) {
+ int chunk;
+
+ /* __ Restore normal policy in scheduler __ */
+
+ if ((chunk = len - tp->ucopy.len) != 0) {
+ net_statistics[smp_processor_id()*2+1].TCPDirectCopyFromBacklog += chunk;
+ len -= chunk;
+ copied += chunk;
+ }
+
+ if (tp->rcv_nxt == tp->copied_seq &&
+ skb_queue_len(&tp->ucopy.prequeue)) {
+do_prequeue:
+ tcp_prequeue_process(sk);
+
+ if ((chunk = len - tp->ucopy.len) != 0) {
+ net_statistics[smp_processor_id()*2+1].TCPDirectCopyFromPrequeue += chunk;
+ len -= chunk;
+ copied += chunk;
+ }
+ }
+#if 1/*def CONFIG_TCP_MORE_COARSE_ACKS*/
+ if (tp->ack.pending &&
+ (tp->rcv_nxt - tp->rcv_wup) > tp->ack.rcv_mss)
+ tcp_send_ack(sk);
+#endif
+ }
continue;
found_ok_skb:
- /* Lock the buffer. We can be fairly relaxed as
- * an interrupt will never steal a buffer we are
- * using unless I've missed something serious in
- * tcp_data.
- */
- atomic_inc(&skb->users);
-
/* Ok so how much can we use? */
used = skb->len - offset;
if (len < used)
@@ -1293,36 +1437,28 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg,
}
}
- /* Copy it - We _MUST_ update *seq first so that we
- * don't ever double read when we have dual readers
- */
- *seq += used;
-
- /* This memcpy_toiovec can sleep. If it sleeps and we
- * do a second read it relies on the skb->users to avoid
- * a crash when cleanup_rbuf() gets called.
- */
err = memcpy_toiovec(msg->msg_iov, ((unsigned char *)skb->h.th) + skb->h.th->doff*4 + offset, used);
if (err) {
/* Exception. Bailout! */
- atomic_dec(&skb->users);
- copied = -EFAULT;
+ if (!copied)
+ copied = -EFAULT;
break;
}
+ *seq += used;
copied += used;
len -= used;
- /* We now will not sleep again until we are finished
- * with skb. Sorry if you are doing the SMP port
- * but you'll just have to fix it neatly ;)
- *
- * Very funny Alan... -DaveM
- */
- atomic_dec(&skb->users);
-
- if (after(tp->copied_seq,tp->urg_seq))
+ if (after(tp->copied_seq,tp->urg_seq)) {
tp->urg_data = 0;
+ if (skb_queue_len(&tp->out_of_order_queue) == 0
+#ifdef TCP_FORMAL_WINDOW
+ && tcp_receive_window(tp)
+#endif
+ ) {
+ tcp_fast_path_on(tp);
+ }
+ }
if (used + offset < skb->len)
continue;
@@ -1334,8 +1470,30 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg,
if (flags & MSG_PEEK)
continue;
skb->used = 1;
- if (atomic_read(&skb->users) == 1)
- tcp_eat_skb(sk, skb);
+ tcp_eat_skb(sk, skb);
+
+#ifdef CONFIG_TCP_LESS_COARSE_ACKS
+ /* Possible improvement. When sender is faster than receiver,
+ * traffic looks like: fill window ... wait for window open ...
+ * fill window. We lose at least one rtt, because call
+ * cleanup_rbuf only once. Probably, if "len" was large
+ * we should insert several intermediate cleanup_rbuf(s).
+ *
+ * F.e.:
+ */
+ do {
+ u32 full_space = min(tp->window_clamp, tcp_full_space(sk));
+
+ /* Try to ACK, if total buffer length is larger
+ than maximal window and if rcv_window has
+ chances to increase twice. It will result
+ to exponentially decreased ACKing during
+ read to huge (usually, mmapped) buffer.
+ */
+ if (len >= full_space && tp->rcv_wnd <= full_space/2)
+ cleanup_rbuf(sk, copied);
+ } while (0);
+#endif
continue;
found_fin_ok:
@@ -1345,19 +1503,36 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg,
/* All is done. */
skb->used = 1;
- sk->shutdown |= RCV_SHUTDOWN;
break;
}
- if (copied >= 0 && msg->msg_name)
- tp->af_specific->addr2sockaddr(sk, (struct sockaddr *)
- msg->msg_name);
+ if (user_recv) {
+ if (skb_queue_len(&tp->ucopy.prequeue)) {
+ int chunk;
+
+ tp->ucopy.len = copied > 0 ? len : 0;
+
+ tcp_prequeue_process(sk);
+
+ if (copied > 0 && (chunk = len - tp->ucopy.len) != 0) {
+ net_statistics[smp_processor_id()*2+1].TCPDirectCopyFromPrequeue += chunk;
+ len -= chunk;
+ copied += chunk;
+ }
+ }
- if(addr_len)
- *addr_len = tp->af_specific->sockaddr_len;
+ tp->ucopy.task = NULL;
+ tp->ucopy.len = 0;
+ }
+
+ /* According to UNIX98, msg_name/msg_namelen are ignored
+ * on connected socket. I was just happy when found this 8) --ANK
+ */
/* Clean up data we have read: This will do ACK frames. */
cleanup_rbuf(sk, copied);
+
+ TCP_CHECK_TIMER(sk);
release_sock(sk);
return copied;
@@ -1365,24 +1540,16 @@ out_err:
err = sock_error(sk);
out:
+ TCP_CHECK_TIMER(sk);
release_sock(sk);
return err;
recv_urg:
- err = tcp_recv_urg(sk, nonblock, msg, len, flags, addr_len);
+ err = tcp_recv_urg(sk, timeo, msg, len, flags, addr_len);
goto out;
}
/*
- * Check whether to renew the timer.
- */
-static inline void tcp_check_fin_timer(struct sock *sk)
-{
- if (sk->state == TCP_FIN_WAIT2)
- tcp_reset_keepalive_timer(sk, sysctl_tcp_fin_timeout);
-}
-
-/*
* State processing on a close. This implements the state shift for
* sending our FIN frame. Note that we only send a FIN for some
* states. A shutdown() may have already sent the FIN, or we may be
@@ -1405,24 +1572,13 @@ static unsigned char new_state[16] = {
/* TCP_CLOSING */ TCP_CLOSING,
};
-static int tcp_close_state(struct sock *sk, int dead)
+static int tcp_close_state(struct sock *sk)
{
int next = (int) new_state[sk->state];
int ns = (next & TCP_STATE_MASK);
tcp_set_state(sk, ns);
- /* This is a (useful) BSD violating of the RFC. There is a
- * problem with TCP as specified in that the other end could
- * keep a socket open forever with no application left this end.
- * We use a 3 minute timeout (about the same as BSD) then kill
- * our end. If they send after that then tough - BUT: long enough
- * that we won't make the old 4*rto = almost no time - whoops
- * reset mistake.
- */
- if (dead)
- tcp_check_fin_timer(sk);
-
return (next & TCP_ACTION_FIN);
}
@@ -1443,9 +1599,8 @@ void tcp_shutdown(struct sock *sk, int how)
/* If we've already sent a FIN, or it's a closed state, skip this. */
if ((1 << sk->state) &
(TCPF_ESTABLISHED|TCPF_SYN_SENT|TCPF_SYN_RECV|TCPF_CLOSE_WAIT)) {
-
/* Clear out any half completed packets. FIN if needed. */
- if (tcp_close_state(sk,0))
+ if (tcp_close_state(sk))
tcp_send_fin(sk);
}
}
@@ -1460,40 +1615,6 @@ static inline int closing(struct sock * sk)
return ((1 << sk->state) & (TCPF_FIN_WAIT1|TCPF_CLOSING|TCPF_LAST_ACK));
}
-/*
- * This routine closes sockets which have been at least partially
- * opened, but not yet accepted. Currently it is only called by
- * tcp_close.
- */
-
-static void tcp_close_pending (struct sock *sk)
-{
- struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
- struct open_request *req = tp->syn_wait_queue;
-
- while(req) {
- struct open_request *iter;
-
- if (req->sk)
- tcp_close(req->sk, 0);
-
- iter = req;
- req = req->dl_next;
-
- if (iter->sk) {
- sk->ack_backlog--;
- } else {
- tcp_dec_slow_timer(TCP_SLT_SYNACK);
- tp->syn_backlog--;
- }
- (*iter->class->destructor)(iter);
- tcp_openreq_free(iter);
- }
- BUG_TRAP(tp->syn_backlog == 0);
- BUG_TRAP(sk->ack_backlog == 0);
- tcp_synq_init(tp);
-}
-
static __inline__ void tcp_kill_sk_queues(struct sock *sk)
{
/* First the read buffer. */
@@ -1528,6 +1649,14 @@ void tcp_destroy_sock(struct sock *sk)
/* It it has not 0 sk->num, it must be bound */
BUG_TRAP(!sk->num || sk->prev!=NULL);
+#ifdef TCP_DEBUG
+ if (sk->zapped) {
+ printk("TCP: double destroy sk=%p\n", sk);
+ sock_hold(sk);
+ }
+ sk->zapped = 1;
+#endif
+
sk->prot->destroy(sk);
tcp_kill_sk_queues(sk);
@@ -1538,6 +1667,7 @@ void tcp_destroy_sock(struct sock *sk)
}
#endif
+ atomic_dec(&tcp_orphan_count);
sock_put(sk);
}
@@ -1547,17 +1677,17 @@ void tcp_close(struct sock *sk, long timeout)
int data_was_unread = 0;
lock_sock(sk);
+ sk->shutdown = SHUTDOWN_MASK;
+
if(sk->state == TCP_LISTEN) {
tcp_set_state(sk, TCP_CLOSE);
/* Special case. */
- tcp_close_pending(sk);
+ tcp_listen_stop(sk);
goto adjudge_to_death;
}
- sk->shutdown = SHUTDOWN_MASK;
-
/* We need to flush the recv. buffs. We do this only on the
* descriptor close, not protocol-sourced closes, because the
* reader process may not have drained the data yet!
@@ -1581,10 +1711,35 @@ void tcp_close(struct sock *sk, long timeout)
/* Unread data was tossed, zap the connection. */
tcp_set_state(sk, TCP_CLOSE);
tcp_send_active_reset(sk, GFP_KERNEL);
- } else if (tcp_close_state(sk,1)) {
+ } else if (sk->linger && sk->lingertime==0) {
+ /* Check zero linger _after_ checking for unread data. */
+ sk->prot->disconnect(sk, 0);
+ } else if (tcp_close_state(sk)) {
/* We FIN if the application ate all the data before
* zapping the connection.
*/
+
+ /* RED-PEN. Formally speaking, we have broken TCP state
+ * machine. State transitions:
+ *
+ * TCP_ESTABLISHED -> TCP_FIN_WAIT1
+ * TCP_SYN_RECV -> TCP_FIN_WAIT1 (forget it, it's impossible)
+ * TCP_CLOSE_WAIT -> TCP_LAST_ACK
+ *
+ * are legal only when FIN has been sent (i.e. in window),
+ * rather than queued out of window. Purists blame.
+ *
+ * F.e. "RFC state" is ESTABLISHED,
+ * if Linux state is FIN-WAIT-1, but FIN is still not sent.
+ *
+ * The visible declinations are that sometimes
+ * we enter time-wait state, when it is not required really
+ * (harmless), do not send active resets, when they are
+ * required by specs (TCP_ESTABLISHED, TCP_CLOSE_WAIT, when
+ * they look as CLOSING or LAST_ACK for Linux)
+ * Probably, I missed some more holelets.
+ * --ANK
+ */
tcp_send_fin(sk);
}
@@ -1594,26 +1749,19 @@ void tcp_close(struct sock *sk, long timeout)
add_wait_queue(sk->sleep, &wait);
- while (1) {
+ do {
set_current_state(TASK_INTERRUPTIBLE);
if (!closing(sk))
break;
release_sock(sk);
timeout = schedule_timeout(timeout);
lock_sock(sk);
- if (!signal_pending(tsk) || timeout)
- break;
- }
+ } while (!signal_pending(tsk) && timeout);
tsk->state = TASK_RUNNING;
remove_wait_queue(sk->sleep, &wait);
}
- /* Now that the socket is dead, if we are in the FIN_WAIT2 state
- * we may need to set up a timer.
- */
- tcp_check_fin_timer(sk);
-
adjudge_to_death:
/* It is the last release_sock in its life. It will remove backlog. */
release_sock(sk);
@@ -1627,23 +1775,67 @@ adjudge_to_death:
BUG_TRAP(sk->lock.users==0);
sock_hold(sk);
+ sock_orphan(sk);
+
+ /* This is a (useful) BSD violating of the RFC. There is a
+ * problem with TCP as specified in that the other end could
+ * keep a socket open forever with no application left this end.
+ * We use a 3 minute timeout (about the same as BSD) then kill
+ * our end. If they send after that then tough - BUT: long enough
+ * that we won't make the old 4*rto = almost no time - whoops
+ * reset mistake.
+ *
+ * Nope, it was not mistake. It is really desired behaviour
+ * f.e. on http servers, when such sockets are useless, but
+ * consume significant resources. Let's do it with special
+ * linger2 option. --ANK
+ */
+
+ if (sk->state == TCP_FIN_WAIT2) {
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ if (tp->linger2 < 0) {
+ tcp_set_state(sk, TCP_CLOSE);
+ tcp_send_active_reset(sk, GFP_ATOMIC);
+ } else {
+ int tmo = tcp_fin_time(tp);
- /* Announce socket dead, detach it from wait queue and inode. */
- write_lock_irq(&sk->callback_lock);
- sk->dead = 1;
- sk->socket = NULL;
- sk->sleep = NULL;
- write_unlock_irq(&sk->callback_lock);
+ if (tmo > TCP_TIMEWAIT_LEN) {
+ tcp_reset_keepalive_timer(sk, tcp_fin_time(tp));
+ } else {
+ atomic_inc(&tcp_orphan_count);
+ tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
+ goto out;
+ }
+ }
+ }
+ if (sk->state != TCP_CLOSE &&
+ atomic_read(&tcp_orphan_count) > sysctl_tcp_max_orphans) {
+ if (net_ratelimit())
+ printk(KERN_INFO "TCP: too many of orphaned sockets\n");
+ tcp_set_state(sk, TCP_CLOSE);
+ tcp_send_active_reset(sk, GFP_ATOMIC);
+ }
+ atomic_inc(&tcp_orphan_count);
if (sk->state == TCP_CLOSE)
tcp_destroy_sock(sk);
/* Otherwise, socket is reprieved until protocol close. */
+out:
bh_unlock_sock(sk);
local_bh_enable();
sock_put(sk);
}
+/* These states need RST on ABORT according to RFC793 */
+
+extern __inline__ int tcp_need_reset(int state)
+{
+ return ((1 << state) &
+ (TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_FIN_WAIT1|
+ TCPF_FIN_WAIT2|TCPF_SYN_RECV));
+}
+
int tcp_disconnect(struct sock *sk, int flags)
{
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
@@ -1656,9 +1848,14 @@ int tcp_disconnect(struct sock *sk, int flags)
/* ABORT function of RFC793 */
if (old_state == TCP_LISTEN) {
- tcp_close_pending(sk);
- } else if (tcp_connected(old_state)) {
- tcp_send_active_reset(sk, GFP_KERNEL);
+ tcp_listen_stop(sk);
+ } else if (tcp_need_reset(old_state) ||
+ (tp->snd_nxt != tp->write_seq &&
+ (1<<old_state)&(TCPF_CLOSING|TCPF_LAST_ACK))) {
+ /* The last check adjusts for discrepance of Linux wrt. RFC
+ * states
+ */
+ tcp_send_active_reset(sk, gfp_any());
sk->err = ECONNRESET;
} else if (old_state == TCP_SYN_SENT)
sk->err = ECONNRESET;
@@ -1677,26 +1874,25 @@ int tcp_disconnect(struct sock *sk, int flags)
memset(&sk->net_pinfo.af_inet6.rcv_saddr, 0, 16);
#endif
- sk->zapped = 0;
sk->shutdown = 0;
sk->done = 0;
sk->write_space = tcp_write_space;
tp->srtt = 0;
-#ifdef CONFIG_TCP_TW_RECYCLE
- if ((tp->write_seq += 2) == 0)
- tp->write_seq = 1;
-#else
- tp->write_seq = 0;
-#endif
- tp->ato = 0;
+ if (sysctl_tcp_tw_recycle) {
+ if ((tp->write_seq += 2) == 0)
+ tp->write_seq = 1;
+ } else {
+ tp->write_seq = 0;
+ }
tp->backoff = 0;
tp->snd_cwnd = 2;
tp->probes_out = 0;
+ tp->packets_out = 0;
tp->high_seq = 0;
tp->snd_ssthresh = 0x7fffffff;
tp->snd_cwnd_cnt = 0;
tp->dup_acks = 0;
- tp->delayed_acks = 0;
+ tcp_delack_init(tp);
tp->send_head = tp->retrans_head = NULL;
tp->saw_tstamp = 0;
__sk_dst_reset(sk);
@@ -1712,11 +1908,10 @@ int tcp_disconnect(struct sock *sk, int flags)
* conditions. This must be called with the socket locked,
* and without the kernel lock held.
*/
-static struct open_request * wait_for_connect(struct sock * sk,
- struct open_request **pprev)
+static int wait_for_connect(struct sock * sk, long timeo)
{
DECLARE_WAITQUEUE(wait, current);
- struct open_request *req;
+ int err;
/*
* True wake-one mechanism for incoming connections: only
@@ -1736,17 +1931,25 @@ static struct open_request * wait_for_connect(struct sock * sk,
for (;;) {
current->state = TASK_EXCLUSIVE | TASK_INTERRUPTIBLE;
release_sock(sk);
- schedule();
+ if (sk->tp_pinfo.af_tcp.accept_queue == NULL)
+ timeo = schedule_timeout(timeo);
lock_sock(sk);
- req = tcp_find_established(&(sk->tp_pinfo.af_tcp), pprev);
- if (req)
+ err = 0;
+ if (sk->tp_pinfo.af_tcp.accept_queue)
+ break;
+ err = -EINVAL;
+ if (sk->state != TCP_LISTEN)
break;
+ err = -ERESTARTSYS;
if (signal_pending(current))
break;
+ err = -EAGAIN;
+ if (!timeo)
+ break;
}
current->state = TASK_RUNNING;
remove_wait_queue(sk->sleep, &wait);
- return req;
+ return err;
}
/*
@@ -1758,9 +1961,10 @@ static struct open_request * wait_for_connect(struct sock * sk,
struct sock *tcp_accept(struct sock *sk, int flags, int *err)
{
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
- struct open_request *req, *prev;
+ struct open_request *req;
struct sock *newsk;
int error;
+ long timeo;
lock_sock(sk);
@@ -1771,25 +1975,27 @@ struct sock *tcp_accept(struct sock *sk, int flags, int *err)
if (sk->state != TCP_LISTEN)
goto out;
+ timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
+
/* Find already established connection */
- req = tcp_find_established(tp, &prev);
- if (!req) {
+ if (!tp->accept_queue) {
/* If this is a non blocking socket don't sleep */
error = -EAGAIN;
- if (flags & O_NONBLOCK)
+ if (!timeo)
goto out;
- error = -ERESTARTSYS;
- req = wait_for_connect(sk, &prev);
- if (!req)
+ error = wait_for_connect(sk, timeo);
+ if (error)
goto out;
}
- tcp_synq_unlink(tp, req, prev);
- newsk = req->sk;
- req->class->destructor(req);
- tcp_openreq_free(req);
- sk->ack_backlog--;
+ req = tp->accept_queue;
+ tp->accept_queue = req->dl_next;
+
+ newsk = req->sk;
+ tcp_acceptq_removed(sk);
+ tcp_openreq_fastfree(req);
+ BUG_TRAP(newsk->state != TCP_SYN_RECV);
release_sock(sk);
return newsk;
@@ -1828,7 +2034,7 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char *optval,
* the point when this call is done we typically don't yet know
* which interface is going to be used
*/
- if(val < 1 || val > MAX_WINDOW) {
+ if(val < 8 || val > MAX_TCP_WINDOW) {
err = -EINVAL;
break;
}
@@ -1839,11 +2045,11 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char *optval,
/* You cannot try to use this and TCP_CORK in
* tandem, so let the user know.
*/
- if (sk->nonagle == 2) {
+ if (tp->nonagle == 2) {
err = -EINVAL;
break;
}
- sk->nonagle = (val == 0) ? 0 : 1;
+ tp->nonagle = (val == 0) ? 0 : 1;
break;
case TCP_CORK:
@@ -1858,14 +2064,14 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char *optval,
* You cannot try to use TCP_NODELAY and this mechanism
* at the same time, so let the user know.
*/
- if (sk->nonagle == 1) {
+ if (tp->nonagle == 1) {
err = -EINVAL;
break;
}
if (val != 0) {
- sk->nonagle = 2;
+ tp->nonagle = 2;
} else {
- sk->nonagle = 0;
+ tp->nonagle = 0;
tcp_push_pending_frames(sk, tp);
}
@@ -1905,6 +2111,38 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char *optval,
tp->syn_retries = val;
break;
+ case TCP_LINGER2:
+ if (val < 0)
+ tp->linger2 = -1;
+ else if (val > sysctl_tcp_fin_timeout/HZ)
+ tp->linger2 = 0;
+ else
+ tp->linger2 = val*HZ;
+ break;
+
+ case TCP_DEFER_ACCEPT:
+ tp->defer_accept = 0;
+ if (val > 0) {
+ /* Translate value in seconds to number of retransmits */
+ while (val > ((TCP_TIMEOUT_INIT/HZ)<<tp->defer_accept))
+ tp->defer_accept++;
+ tp->defer_accept++;
+ }
+ break;
+
+ case TCP_WINDOW_CLAMP:
+ if (val==0) {
+ if (sk->state != TCP_CLOSE) {
+ err = -EINVAL;
+ break;
+ }
+ tp->window_clamp = 0;
+ } else {
+ tp->window_clamp = val<SOCK_MIN_RCVBUF/2 ?
+ SOCK_MIN_SNDBUF : val;
+ }
+ break;
+
default:
err = -ENOPROTOOPT;
break;
@@ -1930,37 +2168,38 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char *optval,
switch(optname) {
case TCP_MAXSEG:
- val = tp->user_mss;
+ val = tp->mss_cache;
+ if (val == 0 && ((1<<sk->state)&(TCPF_CLOSE|TCPF_LISTEN)))
+ val = tp->user_mss;
break;
case TCP_NODELAY:
- val = (sk->nonagle == 1);
+ val = (tp->nonagle == 1);
break;
case TCP_CORK:
- val = (sk->nonagle == 2);
+ val = (tp->nonagle == 2);
break;
case TCP_KEEPIDLE:
- if (tp->keepalive_time)
- val = tp->keepalive_time / HZ;
- else
- val = sysctl_tcp_keepalive_time / HZ;
+ val = (tp->keepalive_time ? : sysctl_tcp_keepalive_time)/HZ;
break;
case TCP_KEEPINTVL:
- if (tp->keepalive_intvl)
- val = tp->keepalive_intvl / HZ;
- else
- val = sysctl_tcp_keepalive_intvl / HZ;
+ val = (tp->keepalive_intvl ? : sysctl_tcp_keepalive_intvl)/HZ;
break;
case TCP_KEEPCNT:
- if (tp->keepalive_probes)
- val = tp->keepalive_probes;
- else
- val = sysctl_tcp_keepalive_probes;
+ val = tp->keepalive_probes ? : sysctl_tcp_keepalive_probes;
break;
case TCP_SYNCNT:
- if (tp->syn_retries)
- val = tp->syn_retries;
- else
- val = sysctl_tcp_syn_retries;
+ val = tp->syn_retries ? : sysctl_tcp_syn_retries;
+ break;
+ case TCP_LINGER2:
+ val = tp->linger2;
+ if (val > 0)
+ val = (val ? : sysctl_tcp_fin_timeout)/HZ;
+ break;
+ case TCP_DEFER_ACCEPT:
+ val = tp->defer_accept == 0 ? 0 : (TCP_TIMEOUT_INIT<<(tp->defer_accept-1));
+ break;
+ case TCP_WINDOW_CLAMP:
+ val = tp->window_clamp;
break;
default:
return -ENOPROTOOPT;
@@ -2049,11 +2288,20 @@ void __init tcp_init(void)
tcp_bhash[i].chain = NULL;
}
+ /* Try to be a bit smarter and adjust defaults depending
+ * on available memory.
+ */
if (order > 4) {
sysctl_local_port_range[0] = 32768;
sysctl_local_port_range[1] = 61000;
+ sysctl_tcp_max_tw_buckets = 180000;
+ sysctl_tcp_max_orphans = 4096<<(order-4);
+ sysctl_max_syn_backlog = 1024;
} else if (order < 3) {
sysctl_local_port_range[0] = 1024*(3-order);
+ sysctl_tcp_max_tw_buckets >>= (3-order);
+ sysctl_tcp_max_orphans >>= (3-order);
+ sysctl_max_syn_backlog = 128;
}
tcp_port_rover = sysctl_local_port_range[0] - 1;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 3b4ae64a2..d61a5df02 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_input.c,v 1.177 2000/01/09 02:19:39 davem Exp $
+ * Version: $Id: tcp_input.c,v 1.183 2000/01/24 18:40:33 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -70,9 +70,6 @@
#define SYNC_INIT 1
#endif
-extern int sysctl_tcp_fin_timeout;
-extern int sysctl_tcp_keepalive_time;
-
/* These are on by default so the code paths get tested.
* For the final 2.2 this may be undone at our discretion. -DaveM
*/
@@ -83,10 +80,108 @@ int sysctl_tcp_sack = 1;
int sysctl_tcp_syncookies = SYNC_INIT;
int sysctl_tcp_stdurg;
int sysctl_tcp_rfc1337;
-int sysctl_tcp_tw_recycle;
+int sysctl_tcp_tw_recycle = 1;
+int sysctl_tcp_abort_on_overflow = 0;
+int sysctl_tcp_max_orphans = NR_FILE;
+int sysctl_tcp_max_tw_buckets = NR_FILE*2;
static int prune_queue(struct sock *sk);
+/*
+ * Adapt the MSS value used to make delayed ack decision to the
+ * real world.
+ *
+ * The constant 536 hasn't any good meaning. In IPv4 world
+ * MTU may be smaller, though it contradicts to RFC1122, which
+ * states that MSS must be at least 536.
+ * We use the constant to do not ACK each second
+ * packet in a stream of tiny size packets.
+ * It means that super-low mtu links will be aggressively delacked.
+ * Seems, it is even good. If they have so low mtu, they are weirdly
+ * slow.
+ *
+ * AK: BTW it may be useful to add an option to lock the rcv_mss.
+ * this way the beowulf people wouldn't need ugly patches to get the
+ * ack frequencies they want and it would be an elegant way to tune delack.
+ */
+static __inline__ void tcp_measure_rcv_mss(struct tcp_opt *tp, struct sk_buff *skb)
+{
+ unsigned int len, lss;
+
+ lss = tp->ack.last_seg_size;
+ tp->ack.last_seg_size = 0;
+
+ /* skb->len may jitter because of SACKs, even if peer
+ * sends good full-sized frames.
+ */
+ len = skb->len;
+ if (len >= tp->ack.rcv_mss) {
+ tp->ack.rcv_mss = len;
+ } else {
+ /* Otherwise, we make more careful check taking into account,
+ * that SACKs block is variable.
+ *
+ * "len" is invariant segment length, including TCP header.
+ */
+ len = skb->tail - skb->h.raw;
+ if (len >= TCP_MIN_RCVMSS + sizeof(struct tcphdr)) {
+ /* Subtract also invariant (if peer is RFC compliant),
+ * tcp header plus fixed timestamp option length.
+ * Resulting "len" is MSS free of SACK jitter.
+ */
+ len -= tp->tcp_header_len;
+ if (len == lss)
+ tp->ack.rcv_mss = len;
+ tp->ack.last_seg_size = len;
+ }
+
+#if 0
+ /* Tiny-grams with PSH set artifically deflate our
+ * ato measurement.
+ *
+ * Mmm... I copied this test from tcp_remember_ack(), but
+ * I did not understand this. Is it to speedup nagling sender?
+ * It does not because classic (non-Minshall) sender nagles
+ * guided by not-acked frames not depending on size.
+ * And it does not help NODELAY sender, because latency
+ * is too high in any case. The only result is timer trashing
+ * and redundant ACKs. Grr... Seems, I missed something. --ANK
+ *
+ * Let me to comment out this yet... TCP should work
+ * perfectly without this. --ANK
+ */
+ if (len < (tp->ack.rcv_mss >> 1) && skb->h.th->psh)
+ tp->ack.ato = TCP_ATO_MIN;
+#endif
+ }
+}
+
+
+static __inline__ void tcp_enter_quickack_mode(struct tcp_opt *tp)
+{
+ unsigned quickacks = tcp_receive_window(tp)/(2*tp->ack.rcv_mss);
+
+ tp->ack.quick = max(min(quickacks, 127), 1);
+
+ if (!tp->tstamp_ok && tp->ack.quick>2) {
+ /* Quick ACKs are _dangerous_, if RTTM is not used.
+ * See comment in tcp_init_metrics(). We still help
+ * them to overcome the most difficult, initial
+ * phase of slow start.
+ */
+ tp->ack.quick = 2;
+ }
+}
+
+/* Send ACKs quickly, if "quick" count is not ehausted
+ * and the session is not interactive.
+ */
+
+static __inline__ int tcp_in_quickack_mode(struct tcp_opt *tp)
+{
+ return (tp->ack.quick && !tp->ack.pingpong);
+}
+
/* There is something which you must keep in mind when you analyze the
* behavior of the tp->ato delayed ack timeout interval. When a
* connection starts up, we want to ack as quickly as possible. The
@@ -97,53 +192,52 @@ static int prune_queue(struct sock *sk);
* each ACK we send, he increments snd_cwnd and transmits more of his
* queue. -DaveM
*/
-static void tcp_delack_estimator(struct tcp_opt *tp)
+static void tcp_event_data_recv(struct tcp_opt *tp, struct sk_buff *skb)
{
- if(tp->ato == 0) {
- tp->lrcvtime = tcp_time_stamp;
+ u32 now;
- /* Help sender leave slow start quickly,
- * and also makes sure we do not take this
- * branch ever again for this connection.
+ tcp_measure_rcv_mss(tp, skb);
+
+ tp->ack.pending = 1;
+
+ now = tcp_time_stamp;
+
+ if (!tp->ack.ato) {
+ /* The _first_ data packet received, initialize
+ * delayed ACK engine.
*/
- tp->ato = 1;
+
+ /* Help sender leave slow start quickly. */
tcp_enter_quickack_mode(tp);
+
+ /* Pingpong is off, session is not interactive by default */
+ tp->ack.pingpong = 0;
+
+ /* ATO is minimal */
+ tp->ack.ato = TCP_ATO_MIN;
} else {
- int m = tcp_time_stamp - tp->lrcvtime;
-
- tp->lrcvtime = tcp_time_stamp;
- if(m <= 0)
- m = 1;
- if(m > tp->rto)
- tp->ato = tp->rto;
- else {
- /* This funny shift makes sure we
- * clear the "quick ack mode" bit.
+ int m = now - tp->ack.lrcvtime;
+
+ if (m > TCP_ATO_MAX/2) {
+ /* Do not touch ATO, if interval is out of bounds.
+ * It will be deflated by delack timer, if our peer
+ * really sends too rarely.
*/
- tp->ato = ((tp->ato << 1) >> 2) + m;
+ if (m > tp->rto) {
+ /* Too long gap. Apparently sender falled to
+ * restart window, so that we send ACKs quickly.
+ */
+ tcp_enter_quickack_mode(tp);
+ }
+ } else {
+ if (m <= 0)
+ m = TCP_ATO_MIN/2;
+ tp->ack.ato = (tp->ack.ato >> 1) + m;
}
}
+ tp->ack.lrcvtime = now;
}
-/*
- * Remember to send an ACK later.
- */
-static __inline__ void tcp_remember_ack(struct tcp_opt *tp, struct tcphdr *th,
- struct sk_buff *skb)
-{
- tp->delayed_acks++;
-
- /* Tiny-grams with PSH set artifically deflate our
- * ato measurement, but with a lower bound.
- */
- if(th->psh && (skb->len < (tp->rcv_mss >> 1))) {
- /* Preserve the quickack state. */
- if((tp->ato & 0x7fffffff) > HZ/50)
- tp->ato = ((tp->ato & 0x80000000) |
- (HZ/50));
- }
-}
-
/* Called to compute a smoothed rtt estimate. The data fed to this
* routine either comes from timestamps, or from segments that were
* known _not_ to have been retransmitted [see Karn/Partridge
@@ -209,10 +303,10 @@ static __inline__ void tcp_set_rto(struct tcp_opt *tp)
*/
static __inline__ void tcp_bound_rto(struct tcp_opt *tp)
{
- if (tp->rto > 120*HZ)
- tp->rto = 120*HZ;
- if (tp->rto < HZ/5)
- tp->rto = HZ/5;
+ if (tp->rto < TCP_RTO_MIN)
+ tp->rto = TCP_RTO_MIN;
+ else if (tp->rto > TCP_RTO_MAX)
+ tp->rto = TCP_RTO_MAX;
}
/* Save metrics learned by this TCP session.
@@ -224,7 +318,9 @@ static void tcp_update_metrics(struct sock *sk)
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
struct dst_entry *dst = __sk_dst_get(sk);
- if (dst) {
+ dst_confirm(dst);
+
+ if (dst && (dst->flags&DST_HOST)) {
int m;
if (tp->backoff || !tp->srtt) {
@@ -237,8 +333,6 @@ static void tcp_update_metrics(struct sock *sk)
return;
}
- dst_confirm(dst);
-
m = dst->rtt - tp->srtt;
/* If newly calculated rtt larger than stored one,
@@ -308,10 +402,18 @@ static void tcp_init_metrics(struct sock *sk)
dst_confirm(dst);
+ if (dst->mxlock&(1<<RTAX_CWND))
+ tp->snd_cwnd_clamp = dst->cwnd;
+ if (dst->ssthresh) {
+ tp->snd_ssthresh = dst->ssthresh;
+ if (tp->snd_ssthresh > tp->snd_cwnd_clamp)
+ tp->snd_ssthresh = tp->snd_cwnd_clamp;
+ }
+
if (dst->rtt == 0)
goto reset;
- if (!tp->srtt || !tp->saw_tstamp)
+ if (!tp->srtt && dst->rtt < (TCP_TIMEOUT_INIT<<3))
goto reset;
/* Initial rtt is determined from SYN,SYN-ACK.
@@ -334,14 +436,9 @@ static void tcp_init_metrics(struct sock *sk)
tp->mdev = dst->rttvar;
tcp_set_rto(tp);
tcp_bound_rto(tp);
-
- if (dst->mxlock&(1<<RTAX_CWND))
- tp->snd_cwnd_clamp = dst->cwnd;
- if (dst->ssthresh) {
- tp->snd_ssthresh = dst->ssthresh;
- if (tp->snd_ssthresh > tp->snd_cwnd_clamp)
- tp->snd_ssthresh = tp->snd_cwnd_clamp;
- }
+ if (tp->rto < TCP_TIMEOUT_INIT && !tp->saw_tstamp)
+ goto reset;
+ tp->snd_cwnd = tcp_init_cwnd(tp);
return;
@@ -357,9 +454,6 @@ reset:
}
}
-#define PAWS_24DAYS (60 * 60 * 24 * 24)
-
-
/* WARNING: this must not be called if tp->saw_tstamp was false. */
extern __inline__ void
tcp_replace_ts_recent(struct sock *sk, struct tcp_opt *tp, u32 seq)
@@ -374,7 +468,7 @@ tcp_replace_ts_recent(struct sock *sk, struct tcp_opt *tp, u32 seq)
*/
if((s32)(tp->rcv_tsval - tp->ts_recent) >= 0 ||
- xtime.tv_sec >= tp->ts_recent_stamp + PAWS_24DAYS) {
+ xtime.tv_sec >= tp->ts_recent_stamp + TCP_PAWS_24DAYS) {
tp->ts_recent = tp->rcv_tsval;
tp->ts_recent_stamp = xtime.tv_sec;
}
@@ -384,7 +478,7 @@ tcp_replace_ts_recent(struct sock *sk, struct tcp_opt *tp, u32 seq)
extern __inline__ int tcp_paws_discard(struct tcp_opt *tp, struct sk_buff *skb)
{
return ((s32)(tp->rcv_tsval - tp->ts_recent) < 0 &&
- xtime.tv_sec < tp->ts_recent_stamp + PAWS_24DAYS
+ xtime.tv_sec < tp->ts_recent_stamp + TCP_PAWS_24DAYS
/* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM
@@ -411,8 +505,13 @@ extern __inline__ int tcp_paws_discard(struct tcp_opt *tp, struct sk_buff *skb)
static int __tcp_sequence(struct tcp_opt *tp, u32 seq, u32 end_seq)
{
u32 end_window = tp->rcv_wup + tp->rcv_wnd;
+#ifdef TCP_FORMAL_WINDOW
+ u32 rcv_wnd = tcp_receive_window(tp);
+#else
+ u32 rcv_wnd = tp->rcv_wnd;
+#endif
- if (tp->rcv_wnd &&
+ if (rcv_wnd &&
after(end_seq, tp->rcv_nxt) &&
before(seq, end_window))
return 1;
@@ -424,8 +523,13 @@ static int __tcp_sequence(struct tcp_opt *tp, u32 seq, u32 end_seq)
/* This functions checks to see if the tcp header is actually acceptable. */
extern __inline__ int tcp_sequence(struct tcp_opt *tp, u32 seq, u32 end_seq)
{
+#ifdef TCP_FORMAL_WINDOW
+ u32 rcv_wnd = tcp_receive_window(tp);
+#else
+ u32 rcv_wnd = tp->rcv_wnd;
+#endif
if (seq == tp->rcv_nxt)
- return (tp->rcv_wnd || (end_seq == seq));
+ return (rcv_wnd || (end_seq == seq));
return __tcp_sequence(tp, seq, end_seq);
}
@@ -433,8 +537,6 @@ extern __inline__ int tcp_sequence(struct tcp_opt *tp, u32 seq, u32 end_seq)
/* When we get a reset we do this. */
static void tcp_reset(struct sock *sk)
{
- sk->zapped = 1;
-
/* We want the right error as BSD sees it (and indeed as we do). */
switch (sk->state) {
case TCP_SYN_SENT:
@@ -447,9 +549,8 @@ static void tcp_reset(struct sock *sk)
return;
default:
sk->err = ECONNRESET;
- };
- tcp_set_state(sk, TCP_CLOSE);
- tcp_clear_xmit_timers(sk);
+ }
+
tcp_done(sk);
}
@@ -658,17 +759,18 @@ static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup)
if (tp->high_seq == 0 || after(ack, tp->high_seq)) {
tp->dup_acks++;
if ((tp->fackets_out > 3) || (tp->dup_acks == 3)) {
- tp->snd_ssthresh = tcp_recalc_ssthresh(tp);
- if (tp->snd_ssthresh > tp->snd_cwnd_clamp)
- tp->snd_ssthresh = tp->snd_cwnd_clamp;
- tp->snd_cwnd = (tp->snd_ssthresh + 3);
- tp->high_seq = tp->snd_nxt;
+ __tcp_enter_cong_avoid(tp);
+ /* ... and account for 3 ACKs, which are
+ * already received to this time.
+ */
+ tp->snd_cwnd += 3;
+
if(!tp->fackets_out)
tcp_retransmit_skb(sk,
skb_peek(&sk->write_queue));
else
tcp_fack_retransmit(sk);
- tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
+ tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
}
} else if (++tp->dup_acks > 3) {
/* 2. Each time another duplicate ACK arrives, increment
@@ -733,7 +835,7 @@ static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup)
if (ack != tp->snd_una && before(ack, tp->high_seq)) {
tcp_retransmit_skb(sk,
skb_peek(&sk->write_queue));
- tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
+ tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
}
} else {
/* FACK style, fill any remaining holes in
@@ -752,7 +854,8 @@ static __inline__ void tcp_cong_avoid(struct tcp_opt *tp)
{
if (tp->snd_cwnd <= tp->snd_ssthresh) {
/* In "safe" area, increase. */
- tp->snd_cwnd++;
+ if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+ tp->snd_cwnd++;
} else {
/* In dangerous area, increase slowly.
* In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
@@ -826,23 +929,23 @@ static void tcp_ack_probe(struct sock *sk, __u32 ack)
{
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
- /* Our probe was answered. */
- tp->probes_out = 0;
-
/* Was it a usable window open? */
- /* should always be non-null */
- if (tp->send_head != NULL &&
- !before (ack + tp->snd_wnd, TCP_SKB_CB(tp->send_head)->end_seq)) {
- tp->backoff = 0;
- tp->pending = 0;
- tcp_clear_xmit_timer(sk, TIME_PROBE0);
- } else {
- tcp_reset_xmit_timer(sk, TIME_PROBE0,
- min(tp->rto << tp->backoff, 120*HZ));
+ if (tp->send_head != NULL) {
+ if (!after(TCP_SKB_CB(tp->send_head)->end_seq, ack + tp->snd_wnd)) {
+ tp->backoff = 0;
+ tcp_clear_xmit_timer(sk, TCP_TIME_PROBE0);
+ /* If packets_out==0, socket must be waked up by
+ * subsequent tcp_data_snd_check(). This function is
+ * not for random using!
+ */
+ } else if (!tp->packets_out) {
+ tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0,
+ min(tp->rto << tp->backoff, TCP_RTO_MAX));
+ }
}
}
-
+
/* Should we open up the congestion window? */
static __inline__ int should_advance_cwnd(struct tcp_opt *tp, int flag)
{
@@ -914,18 +1017,30 @@ static __inline__ void tcp_ack_packets_out(struct sock *sk, struct tcp_opt *tp)
{
struct sk_buff *skb = skb_peek(&sk->write_queue);
+#ifdef TCP_DEBUG
+ /* It occured in 2.3, because of racy timers. Namely,
+ * retransmit timer did not check packets_out and retransmitted
+ * send_head sometimes and, hence, messed all the write_queue.
+ * Now it is impossible, I bet. --ANK
+ */
+ if (skb == NULL) {
+ printk("Sucks! packets_out=%d, sk=%p, %d\n", tp->packets_out, sk, sk->state);
+ return;
+ }
+#endif
+
/* Some data was ACK'd, if still retransmitting (due to a
* timeout), resend more of the retransmit queue. The
* congestion window is handled properly by that code.
*/
if (tp->retransmits) {
tcp_xmit_retransmit_queue(sk);
- tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
+ tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
} else {
__u32 when = tp->rto - (tcp_time_stamp - TCP_SKB_CB(skb)->when);
if ((__s32)when < 0)
when = 1;
- tcp_reset_xmit_timer(sk, TIME_RETRANS, when);
+ tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, when);
}
}
@@ -938,13 +1053,8 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th,
u32 seq = 0;
u32 seq_rtt = 0;
- if(sk->zapped)
- return(1); /* Dead, can't ack any more so why bother */
-
- if (tp->pending == TIME_KEEPOPEN)
- tp->probes_out = 0;
-
- tp->rcv_tstamp = tcp_time_stamp;
+ if(sk->state == TCP_CLOSE)
+ return 1; /* Dead, can't ack any more so why bother */
/* If the ack is newer than sent or older than previous acks
* then we can probably ignore it.
@@ -953,10 +1063,8 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th,
goto uninteresting_ack;
/* If there is data set flag 1 */
- if (len != th->doff*4) {
+ if (len != th->doff*4)
flag |= FLAG_DATA;
- tcp_delack_estimator(tp);
- }
/* Update our send window. */
@@ -970,31 +1078,53 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th,
if ((tp->snd_wl2 != ack) || (nwin > tp->snd_wnd)) {
flag |= FLAG_WIN_UPDATE;
- tp->snd_wnd = nwin;
+ if (tp->snd_wnd != nwin) {
+ tp->snd_wnd = nwin;
+
+ /* Note, it is the only place, where
+ * fast path is recovered for sending TCP.
+ */
+ if (skb_queue_len(&tp->out_of_order_queue) == 0 &&
+#ifdef TCP_FORMAL_WINDOW
+ tcp_receive_window(tp) &&
+#endif
+ !tp->urg_data)
+ tcp_fast_path_on(tp);
+
+ if (nwin > tp->max_window) {
+ tp->max_window = nwin;
+ tcp_sync_mss(sk, tp->pmtu_cookie);
+ }
+ }
tp->snd_wl1 = ack_seq;
tp->snd_wl2 = ack;
-
- if (nwin > tp->max_window)
- tp->max_window = nwin;
}
}
+ /* BEWARE! From this place and until return from this function
+ * snd_nxt and snd_wnd are out of sync. All the routines, called
+ * from here must get "ack" as argument or they should not depend
+ * on right edge of window. It is _UGLY_. It cries to be fixed. --ANK
+ */
+
/* We passed data and got it acked, remove any soft error
* log. Something worked...
*/
sk->err_soft = 0;
+ tp->probes_out = 0;
+ tp->rcv_tstamp = tcp_time_stamp;
+
+ /* See if we can take anything off of the retransmit queue. */
+ flag |= tcp_clean_rtx_queue(sk, ack, &seq, &seq_rtt);
/* If this ack opens up a zero window, clear backoff. It was
* being used to time the probes, and is probably far higher than
* it needs to be for normal retransmission.
*/
- if (tp->pending == TIME_PROBE0)
+ if (tcp_timer_is_set(sk, TCP_TIME_PROBE0))
tcp_ack_probe(sk, ack);
- /* See if we can take anything off of the retransmit queue. */
- flag |= tcp_clean_rtx_queue(sk, ack, &seq, &seq_rtt);
-
/* We must do this here, before code below clears out important
* state contained in tp->fackets_out and tp->retransmits. -DaveM
*/
@@ -1036,7 +1166,7 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th,
if (flag & FLAG_DATA_ACKED)
tcp_ack_packets_out(sk, tp);
} else {
- tcp_clear_xmit_timer(sk, TIME_RETRANS);
+ tcp_clear_xmit_timer(sk, TCP_TIME_RETRANS);
}
flag &= (FLAG_DATA | FLAG_WIN_UPDATE);
@@ -1074,9 +1204,42 @@ uninteresting_ack:
return 0;
}
+int tcp_paws_check(struct tcp_opt *tp, int rst)
+{
+ if ((s32)(tp->rcv_tsval - tp->ts_recent) >= 0)
+ return 0;
+ if (xtime.tv_sec >= tp->ts_recent_stamp + TCP_PAWS_24DAYS)
+ return 0;
+
+ /* RST segments are not recommended to carry timestamp,
+ and, if they do, it is recommended to ignore PAWS because
+ "their cleanup function should take precedence over timestamps."
+ Certainly, it is mistake. It is necessary to understand the reasons
+ of this constraint to relax it: if peer reboots, clock may go
+ out-of-sync and half-open connections will not be reset.
+ Actually, the problem would be not existing if all
+ the implementations followed draft about maintaining clock
+ via reboots. Linux-2.2 DOES NOT!
+
+ However, we can relax time bounds for RST segments to MSL.
+ */
+ if (rst && xtime.tv_sec >= tp->ts_recent_stamp + TCP_PAWS_MSL)
+ return 0;
+ return 1;
+}
+
+static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win)
+{
+ if (seq == s_win)
+ return 1;
+ if (after(end_seq, s_win) && before(seq, e_win))
+ return 1;
+ return (seq == e_win && seq == end_seq);
+}
+
/* New-style handling of TIME_WAIT sockets. */
-/* Must be called only from BH context. */
+/* Must be called with locally disabled BHs. */
void tcp_timewait_kill(struct tcp_tw_bucket *tw)
{
struct tcp_ehash_bucket *ehead;
@@ -1121,13 +1284,6 @@ void tcp_timewait_kill(struct tcp_tw_bucket *tw)
tcp_tw_put(tw);
}
-/* We come here as a special case from the AF specific TCP input processing,
- * and the SKB has no owner. Essentially handling this is very simple,
- * we just keep silently eating rx'd packets until none show up for the
- * entire timeout period. The only special cases are for BSD TIME_WAIT
- * reconnects and SYN/RST bits being set in the TCP header.
- */
-
/*
* * Main purpose of TIME-WAIT state is to close connection gracefully,
* when one of ends sits in LAST-ACK or CLOSING retransmitting FIN
@@ -1149,6 +1305,12 @@ void tcp_timewait_kill(struct tcp_tw_bucket *tw)
* The algorithm below is based on FORMAL INTERPRETATION of RFCs.
* When you compare it to RFCs, please, read section SEGMENT ARRIVES
* from the very beginning.
+ *
+ * NOTE. With recycling (and later with fin-wait-2) TW bucket
+ * is _not_ stateless. It means, that strictly speaking we must
+ * spinlock it. I do not want! Well, probability of misbehaviour
+ * is ridiculously low and, seems, we could use some mb() tricks
+ * to avoid misread sequence numbers, states etc. --ANK
*/
enum tcp_tw_status
tcp_timewait_state_process(struct tcp_tw_bucket *tw, struct sk_buff *skb,
@@ -1157,7 +1319,75 @@ tcp_timewait_state_process(struct tcp_tw_bucket *tw, struct sk_buff *skb,
struct tcp_opt tp;
int paws_reject = 0;
- /* RFC 1122:
+ tp.saw_tstamp = 0;
+ if (th->doff > (sizeof(struct tcphdr)>>2) && tw->ts_recent_stamp) {
+ tcp_parse_options(NULL, th, &tp, 0);
+
+ if (tp.saw_tstamp) {
+ tp.ts_recent = tw->ts_recent;
+ tp.ts_recent_stamp = tw->ts_recent_stamp;
+ paws_reject = tcp_paws_check(&tp, th->rst);
+ }
+ }
+
+ if (tw->substate == TCP_FIN_WAIT2) {
+ /* Just repeat all the checks of tcp_rcv_state_process() */
+
+ /* Out of window, send ACK */
+ if (paws_reject ||
+ !tcp_in_window(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq,
+ tw->rcv_nxt, tw->rcv_nxt + tw->rcv_wnd))
+ return TCP_TW_ACK;
+
+ if (th->rst)
+ goto kill;
+
+ if (th->syn && TCP_SKB_CB(skb)->seq != tw->syn_seq)
+ goto kill_with_rst;
+
+ /* Dup ACK? */
+ if (!after(TCP_SKB_CB(skb)->end_seq, tw->rcv_nxt)) {
+ tcp_tw_put(tw);
+ return TCP_TW_SUCCESS;
+ }
+
+ /* New data or FIN. If new data arrive after half-duplex close,
+ * reset.
+ */
+ if (!th->fin || TCP_SKB_CB(skb)->end_seq != tw->rcv_nxt+1) {
+kill_with_rst:
+ tcp_tw_deschedule(tw);
+ tcp_timewait_kill(tw);
+ tcp_tw_put(tw);
+ return TCP_TW_RST;
+ }
+
+ /* FIN arrived, enter true time-wait state. */
+ tw->substate = TCP_TIME_WAIT;
+ tw->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
+ if (tp.saw_tstamp) {
+ tw->ts_recent_stamp = xtime.tv_sec;
+ tw->ts_recent = tp.rcv_tsval;
+ }
+
+ /* I am shamed, but failed to make it more elegant.
+ * Yes, it is direct reference to IP, which is impossible
+ * to generalize to IPv6. Taking into account that IPv6
+ * do not undertsnad recycling in any case, it not
+ * a big problem in practice. --ANK */
+ if (tw->family == AF_INET &&
+ sysctl_tcp_tw_recycle && tw->ts_recent_stamp &&
+ tcp_v4_tw_remember_stamp(tw))
+ tcp_tw_schedule(tw, tw->timeout);
+ else
+ tcp_tw_schedule(tw, TCP_TIMEWAIT_LEN);
+ return TCP_TW_ACK;
+ }
+
+ /*
+ * Now real TIME-WAIT state.
+ *
+ * RFC 1122:
* "When a connection is [...] on TIME-WAIT state [...]
* [a TCP] MAY accept a new SYN from the remote TCP to
* reopen the connection directly, if it:
@@ -1171,47 +1401,31 @@ tcp_timewait_state_process(struct tcp_tw_bucket *tw, struct sk_buff *skb,
* to be an old duplicate".
*/
- tp.saw_tstamp = 0;
- if (th->doff > (sizeof(struct tcphdr)>>2) && tw->ts_recent_stamp) {
- tcp_parse_options(NULL, th, &tp, 0);
-
- paws_reject = tp.saw_tstamp &&
- ((s32)(tp.rcv_tsval - tw->ts_recent) < 0 &&
- xtime.tv_sec < tw->ts_recent_stamp + PAWS_24DAYS);
- }
-
if (!paws_reject &&
(TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq &&
TCP_SKB_CB(skb)->seq == tw->rcv_nxt)) {
/* In window segment, it may be only reset or bare ack. */
if (th->rst) {
-#ifdef CONFIG_TCP_TW_RECYCLE
- /* When recycling, always follow rfc1337,
- * but mark bucket as ready to recycling immediately.
- */
- if (sysctl_tcp_tw_recycle) {
- /* May kill it now. */
- tw->rto = 0;
- tw->ttd = jiffies;
- } else
-#endif
/* This is TIME_WAIT assasination, in two flavors.
* Oh well... nobody has a sufficient solution to this
* protocol bug yet.
*/
- if(sysctl_tcp_rfc1337 == 0) {
+ if (sysctl_tcp_rfc1337 == 0) {
+kill:
tcp_tw_deschedule(tw);
tcp_timewait_kill(tw);
+ tcp_tw_put(tw);
+ return TCP_TW_SUCCESS;
}
- } else {
- tcp_tw_reschedule(tw);
}
+ tcp_tw_schedule(tw, TCP_TIMEWAIT_LEN);
if (tp.saw_tstamp) {
tw->ts_recent = tp.rcv_tsval;
tw->ts_recent_stamp = xtime.tv_sec;
}
+
tcp_tw_put(tw);
return TCP_TW_SUCCESS;
}
@@ -1235,7 +1449,7 @@ tcp_timewait_state_process(struct tcp_tw_bucket *tw, struct sk_buff *skb,
if (th->syn && !th->rst && !th->ack && !paws_reject &&
(after(TCP_SKB_CB(skb)->seq, tw->rcv_nxt) ||
- (tp.saw_tstamp && tw->ts_recent != tp.rcv_tsval))) {
+ (tp.saw_tstamp && (s32)(tw->ts_recent - tp.rcv_tsval) < 0))) {
u32 isn = tw->snd_nxt + 2;
if (isn == 0)
isn++;
@@ -1243,20 +1457,18 @@ tcp_timewait_state_process(struct tcp_tw_bucket *tw, struct sk_buff *skb,
return TCP_TW_SYN;
}
+ if (paws_reject)
+ NET_INC_STATS_BH(PAWSEstabRejected);
+
if(!th->rst) {
/* In this case we must reset the TIMEWAIT timer.
-
- If it is ACKless SYN it may be both old duplicate
- and new good SYN with random sequence number <rcv_nxt.
- Do not reschedule in the last case.
+ *
+ * If it is ACKless SYN it may be both old duplicate
+ * and new good SYN with random sequence number <rcv_nxt.
+ * Do not reschedule in the last case.
*/
- if (paws_reject || th->ack) {
- tcp_tw_reschedule(tw);
-#ifdef CONFIG_TCP_TW_RECYCLE
- tw->rto = min(120*HZ, tw->rto<<1);
- tw->ttd = jiffies + tw->rto;
-#endif
- }
+ if (paws_reject || th->ack)
+ tcp_tw_schedule(tw, TCP_TIMEWAIT_LEN);
/* Send ACK. Note, we do not put the bucket,
* it will be released by caller.
@@ -1267,8 +1479,8 @@ tcp_timewait_state_process(struct tcp_tw_bucket *tw, struct sk_buff *skb,
return TCP_TW_SUCCESS;
}
-/* Enter the time wait state. This is always called from BH
- * context. Essentially we whip up a timewait bucket, copy the
+/* Enter the time wait state. This is called with locally disabled BH.
+ * Essentially we whip up a timewait bucket, copy the
* relevant info into it from the SK, and mess with hash chains
* and list linkage.
*/
@@ -1286,6 +1498,7 @@ static void __tcp_tw_hashdance(struct sock *sk, struct tcp_tw_bucket *tw)
sk->next->pprev = sk->pprev;
*sk->pprev = sk->next;
sk->pprev = NULL;
+ sock_prot_dec_use(sk->prot);
}
/* Step 2: Hash TW into TIMEWAIT half of established hash table. */
@@ -1312,41 +1525,49 @@ static void __tcp_tw_hashdance(struct sock *sk, struct tcp_tw_bucket *tw)
tw->tb->owners = (struct sock*)tw;
tw->bind_pprev = &tw->tb->owners;
spin_unlock(&bhead->lock);
-
- /* Step 4: Un-charge protocol socket in-use count. */
- sock_prot_dec_use(sk->prot);
}
/*
- * Move a socket to time-wait.
+ * Move a socket to time-wait or dead fin-wait-2 state.
*/
-void tcp_time_wait(struct sock *sk)
+void tcp_time_wait(struct sock *sk, int state, int timeo)
{
- struct tcp_tw_bucket *tw;
+ struct tcp_tw_bucket *tw = NULL;
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ int recycle_ok = 0;
+
+ if (sysctl_tcp_tw_recycle && tp->ts_recent_stamp)
+ recycle_ok = tp->af_specific->remember_stamp(sk);
+
+ if (tcp_tw_count < sysctl_tcp_max_tw_buckets)
+ tw = kmem_cache_alloc(tcp_timewait_cachep, SLAB_ATOMIC);
- tw = kmem_cache_alloc(tcp_timewait_cachep, SLAB_ATOMIC);
if(tw != NULL) {
+ int rto = (tp->rto<<2) - (tp->rto>>1);
+
/* Give us an identity. */
tw->daddr = sk->daddr;
tw->rcv_saddr = sk->rcv_saddr;
tw->bound_dev_if= sk->bound_dev_if;
tw->num = sk->num;
tw->state = TCP_TIME_WAIT;
+ tw->substate = state;
tw->sport = sk->sport;
tw->dport = sk->dport;
tw->family = sk->family;
tw->reuse = sk->reuse;
- tw->hashent = sk->hashent;
- tw->rcv_nxt = sk->tp_pinfo.af_tcp.rcv_nxt;
- tw->snd_nxt = sk->tp_pinfo.af_tcp.snd_nxt;
- tw->ts_recent = sk->tp_pinfo.af_tcp.ts_recent;
- tw->ts_recent_stamp= sk->tp_pinfo.af_tcp.ts_recent_stamp;
-#ifdef CONFIG_TCP_TW_RECYCLE
- tw->rto = sk->tp_pinfo.af_tcp.rto;
- tw->ttd = jiffies + 2*tw->rto;
-#endif
+ tw->rcv_wscale = tp->rcv_wscale;
atomic_set(&tw->refcnt, 0);
+ tw->hashent = sk->hashent;
+ tw->rcv_nxt = tp->rcv_nxt;
+ tw->snd_nxt = tp->snd_nxt;
+ tw->rcv_wnd = tcp_receive_window(tp);
+ tw->syn_seq = tp->syn_seq;
+ tw->ts_recent = tp->ts_recent;
+ tw->ts_recent_stamp= tp->ts_recent_stamp;
+ tw->pprev_death = NULL;
+
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
if(tw->family == PF_INET6) {
memcpy(&tw->v6_daddr,
@@ -1361,22 +1582,28 @@ void tcp_time_wait(struct sock *sk)
__tcp_tw_hashdance(sk, tw);
/* Get the TIME_WAIT timeout firing. */
- tcp_tw_schedule(tw);
+ if (timeo < rto)
+ timeo = rto;
- /* CLOSE the SK. */
- if(sk->state == TCP_ESTABLISHED)
- tcp_statistics[smp_processor_id()*2].TcpCurrEstab--;
- sk->state = TCP_CLOSE;
+ if (recycle_ok) {
+ tw->timeout = rto;
+ } else {
+ tw->timeout = TCP_TIMEWAIT_LEN;
+ if (state == TCP_TIME_WAIT)
+ timeo = TCP_TIMEWAIT_LEN;
+ }
+
+ tcp_tw_schedule(tw, timeo);
} else {
- /* Sorry, we're out of memory, just CLOSE this
+ /* Sorry, if we're out of memory, just CLOSE this
* socket up. We've got bigger problems than
* non-graceful socket closings.
*/
- tcp_set_state(sk, TCP_CLOSE);
+ if (net_ratelimit())
+ printk(KERN_INFO "TCP: time wait bucket table overflow\n");
}
tcp_update_metrics(sk);
- tcp_clear_xmit_timers(sk);
tcp_done(sk);
}
@@ -1397,10 +1624,13 @@ void tcp_time_wait(struct sock *sk)
static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th)
{
- sk->tp_pinfo.af_tcp.fin_seq = TCP_SKB_CB(skb)->end_seq;
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ tp->fin_seq = TCP_SKB_CB(skb)->end_seq;
tcp_send_ack(sk);
+ sk->shutdown |= RCV_SHUTDOWN;
+
switch(sk->state) {
case TCP_SYN_RECV:
case TCP_ESTABLISHED:
@@ -1427,7 +1657,7 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th)
break;
case TCP_FIN_WAIT2:
/* Received a FIN -- send ACK and enter TIME_WAIT. */
- tcp_time_wait(sk);
+ tcp_time_wait(sk, TCP_TIME_WAIT, 0);
break;
default:
/* Only TCP_LISTEN and TCP_CLOSE are left, in these
@@ -1435,9 +1665,17 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th)
*/
printk("tcp_fin: Impossible, sk->state=%d\n", sk->state);
break;
- }
+ };
+
+ /* It _is_ possible, that we have something out-of-order _after_ FIN.
+ * Probably, we should reset in this case. For now drop them.
+ */
+ __skb_queue_purge(&tp->out_of_order_queue);
+ if (tp->sack_ok)
+ tp->num_sacks = 0;
+
if (!sk->dead) {
- wake_up_interruptible(sk->sleep);
+ sk->state_change(sk);
sock_wake_async(sk->socket, 1, POLL_HUP);
}
}
@@ -1622,6 +1860,7 @@ static void tcp_sack_extend(struct tcp_opt *tp, struct sk_buff *old_skb, struct
sp->end_seq = TCP_SKB_CB(new_skb)->end_seq;
}
+
/* This one checks to see if we can put data from the
* out_of_order queue into the receive_queue.
*/
@@ -1658,6 +1897,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
{
struct sk_buff *skb1;
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ int eaten = 0;
/* Queue data for delivery to the user.
* Packets in sequence go to the receive queue.
@@ -1665,33 +1905,68 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
*/
if (TCP_SKB_CB(skb)->seq == tp->rcv_nxt) {
/* Ok. In sequence. */
- queue_and_out:
+ if (tp->ucopy.task == current &&
+ tp->copied_seq == tp->rcv_nxt &&
+ tp->ucopy.len &&
+ sk->lock.users &&
+ !tp->urg_data) {
+ int chunk = min(skb->len, tp->ucopy.len);
+
+ local_bh_enable();
+ if (memcpy_toiovec(tp->ucopy.iov, skb->data, chunk)) {
+ sk->err = EFAULT;
+ sk->error_report(sk);
+ }
+ local_bh_disable();
+ tp->ucopy.len -= chunk;
+ tp->copied_seq += chunk;
+ eaten = (chunk == skb->len && !skb->h.th->fin);
+ }
+
+ if (!eaten) {
+queue_and_out:
+ skb_set_owner_r(skb, sk);
+ __skb_queue_tail(&sk->receive_queue, skb);
+ }
dst_confirm(sk->dst_cache);
- __skb_queue_tail(&sk->receive_queue, skb);
tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
- if(skb->h.th->fin) {
+ if(skb->len)
+ tcp_event_data_recv(tp, skb);
+ if(skb->h.th->fin)
tcp_fin(skb, sk, skb->h.th);
- } else {
- tcp_remember_ack(tp, skb->h.th, skb);
- }
+
/* This may have eaten into a SACK block. */
if(tp->sack_ok && tp->num_sacks)
tcp_sack_remove_skb(tp, skb);
tcp_ofo_queue(sk);
/* Turn on fast path. */
- if (skb_queue_len(&tp->out_of_order_queue) == 0)
- tp->pred_flags = htonl(((tp->tcp_header_len >> 2) << 28) |
- ntohl(TCP_FLAG_ACK) |
- tp->snd_wnd);
+ if (skb_queue_len(&tp->out_of_order_queue) == 0 &&
+#ifdef TCP_FORMAL_WINDOW
+ tcp_receive_window(tp) &&
+#endif
+ !tp->urg_data)
+ tcp_fast_path_on(tp);
+
+ if (eaten)
+ kfree_skb(skb);
+
+ if (!sk->dead) {
+ wake_up_interruptible(sk->sleep);
+ sock_wake_async(sk->socket,1, POLL_IN);
+ }
return;
}
-
+
/* An old packet, either a retransmit or some packet got lost. */
if (!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt)) {
- /* A retransmit, 2nd most common case. Force an imediate ack. */
- SOCK_DEBUG(sk, "retransmit received: seq %X\n", TCP_SKB_CB(skb)->seq);
+ /* A retransmit, 2nd most common case. Force an imediate ack.
+ *
+ * It is impossible, seq is checked by top level.
+ */
+ NETDEBUG(printk("retransmit in tcp_data_queue: seq %X\n", TCP_SKB_CB(skb)->seq));
tcp_enter_quickack_mode(tp);
+ tp->ack.pending = 1;
kfree_skb(skb);
return;
}
@@ -1706,15 +1981,17 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
}
/* Ok. This is an out_of_order segment, force an ack. */
- tp->delayed_acks++;
- tcp_enter_quickack_mode(tp);
+ tp->ack.pending = 1;
/* Disable header prediction. */
tp->pred_flags = 0;
+
SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n",
tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
+ skb_set_owner_r(skb, sk);
+
if (skb_peek(&tp->out_of_order_queue) == NULL) {
/* Initial out of order segment, build 1 SACK. */
if(tp->sack_ok) {
@@ -1758,6 +2035,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
}
}
}
+ return;
}
@@ -1767,7 +2045,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
* room, then we will just have to discard the packet.
*/
-static int tcp_data(struct sk_buff *skb, struct sock *sk, unsigned int len)
+static void tcp_data(struct sk_buff *skb, struct sock *sk, unsigned int len)
{
struct tcphdr *th;
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
@@ -1777,11 +2055,11 @@ static int tcp_data(struct sk_buff *skb, struct sock *sk, unsigned int len)
skb_trim(skb, len - (th->doff*4));
if (skb->len == 0 && !th->fin)
- return(0);
+ goto drop;
/*
* If our receive queue has grown past its limits shrink it.
- * Make sure to do this before moving snd_nxt, otherwise
+ * Make sure to do this before moving rcv_nxt, otherwise
* data might be acked for that we don't have enough room.
*/
if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf) {
@@ -1789,7 +2067,7 @@ static int tcp_data(struct sk_buff *skb, struct sock *sk, unsigned int len)
/* Still not enough room. That can happen when
* skb->true_size differs significantly from skb->len.
*/
- return 0;
+ goto drop;
}
}
@@ -1799,29 +2077,20 @@ static int tcp_data(struct sk_buff *skb, struct sock *sk, unsigned int len)
printk(KERN_DEBUG "*** tcp.c:tcp_data bug acked < copied\n");
tp->rcv_nxt = tp->copied_seq;
}
+ return;
- /* Above, tcp_data_queue() increments delayed_acks appropriately.
- * Now tell the user we may have some data.
- */
- if (!sk->dead) {
- wake_up_interruptible(sk->sleep);
- sock_wake_async(sk->socket,1, POLL_IN);
- }
- return(1);
+drop:
+ kfree_skb(skb);
}
static void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb)
{
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
- if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) &&
- tcp_packets_in_flight(tp) < tp->snd_cwnd) {
- /* Put more data onto the wire. */
- tcp_write_xmit(sk);
- } else if (tp->packets_out == 0 && !tp->pending) {
- /* Start probing the receivers window. */
- tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto);
- }
+ if (after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) ||
+ tcp_packets_in_flight(tp) >= tp->snd_cwnd ||
+ tcp_write_xmit(sk))
+ tcp_check_probe_timer(sk, tp);
}
static __inline__ void tcp_data_snd_check(struct sock *sk)
@@ -1832,57 +2101,6 @@ static __inline__ void tcp_data_snd_check(struct sock *sk)
__tcp_data_snd_check(sk, skb);
}
-/*
- * Adapt the MSS value used to make delayed ack decision to the
- * real world.
- *
- * The constant 536 hasn't any good meaning. In IPv4 world
- * MTU may be smaller, though it contradicts to RFC1122, which
- * states that MSS must be at least 536.
- * We use the constant to do not ACK each second
- * packet in a stream of tiny size packets.
- * It means that super-low mtu links will be aggressively delacked.
- * Seems, it is even good. If they have so low mtu, they are weirdly
- * slow.
- *
- * AK: BTW it may be useful to add an option to lock the rcv_mss.
- * this way the beowulf people wouldn't need ugly patches to get the
- * ack frequencies they want and it would be an elegant way to tune delack.
- */
-static __inline__ void tcp_measure_rcv_mss(struct sock *sk, struct sk_buff *skb)
-{
- struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
- unsigned int len, lss;
-
- lss = tp->last_seg_size;
- tp->last_seg_size = 0;
-
- /* skb->len may jitter because of SACKs, even if peer
- * sends good full-sized frames.
- */
- len = skb->len;
- if (len >= tp->rcv_mss) {
- tp->rcv_mss = len;
- } else {
- /* Otherwise, we make more careful check taking into account,
- * that SACKs block is variable.
- *
- * "len" is invariant segment length, including TCP header.
- */
- len = skb->tail - skb->h.raw;
- if (len >= 536 + sizeof(struct tcphdr)) {
- /* Subtract also invariant (if peer is RFC compliant),
- * tcp header plus fixed timestamp option length.
- * Resulting "len" is MSS free of SACK jitter.
- */
- len -= tp->tcp_header_len;
- if (len == lss)
- tp->rcv_mss = len;
- tp->last_seg_size = len;
- }
- }
-}
-
/*
* Check if sending an ack is needed.
*/
@@ -1904,26 +2122,25 @@ static __inline__ void __tcp_ack_snd_check(struct sock *sk, int ofo_possible)
* start in an expediant manner.
*/
- /* Two full frames received or... */
- if (((tp->rcv_nxt - tp->rcv_wup) >= tp->rcv_mss * MAX_DELAY_ACK) ||
- /* We will update the window "significantly" or... */
- tcp_raise_window(sk) ||
- /* We entered "quick ACK" mode or... */
+ /* More than one full frame received or... */
+ if (((tp->rcv_nxt - tp->rcv_wup) > tp->ack.rcv_mss) ||
+ /* We ACK each frame or... */
tcp_in_quickack_mode(tp) ||
- /* We have out of order data */
- (ofo_possible && (skb_peek(&tp->out_of_order_queue) != NULL))) {
+ /* We have out of order data or */
+ (ofo_possible &&
+ skb_peek(&tp->out_of_order_queue) != NULL)) {
/* Then ack it now */
tcp_send_ack(sk);
} else {
/* Else, send delayed ack. */
- tcp_send_delayed_ack(sk, HZ/2);
+ tcp_send_delayed_ack(sk);
}
}
static __inline__ void tcp_ack_snd_check(struct sock *sk)
{
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
- if (tp->delayed_acks == 0) {
+ if (tp->ack.pending == 0) {
/* We sent a data segment already. */
return;
}
@@ -1975,7 +2192,7 @@ static void tcp_check_urg(struct sock * sk, struct tcphdr * th)
*/
if (tp->urg_seq == tp->copied_seq)
tp->copied_seq++; /* Move the copied sequence on correctly */
- tp->urg_data = URG_NOTYET;
+ tp->urg_data = TCP_URG_NOTYET;
tp->urg_seq = ptr;
/* Disable header prediction. */
@@ -1992,12 +2209,12 @@ static inline void tcp_urg(struct sock *sk, struct tcphdr *th, unsigned long len
tcp_check_urg(sk,th);
/* Do we wait for any urgent data? - normally not... */
- if (tp->urg_data == URG_NOTYET) {
+ if (tp->urg_data == TCP_URG_NOTYET) {
u32 ptr = tp->urg_seq - ntohl(th->seq) + (th->doff*4);
/* Is the urgent pointer pointing into this packet? */
if (ptr < len) {
- tp->urg_data = URG_VALID | *(ptr + (unsigned char *) th);
+ tp->urg_data = TCP_URG_VALID | *(ptr + (unsigned char *) th);
if (!sk->dead)
sk->data_ready(sk,0);
}
@@ -2014,7 +2231,8 @@ static inline void tcp_urg(struct sock *sk, struct tcphdr *th, unsigned long len
static int prune_queue(struct sock *sk)
{
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
- struct sk_buff * skb;
+ struct sk_buff *skb;
+ int pruned = 0;
SOCK_DEBUG(sk, "prune_queue: c=%x\n", tp->copied_seq);
@@ -2024,7 +2242,9 @@ static int prune_queue(struct sock *sk)
skb = __skb_dequeue_tail(&tp->out_of_order_queue);
if(skb != NULL) {
/* Free it all. */
- do { net_statistics[smp_processor_id()*2].OfoPruned += skb->len;
+ do {
+ pruned += skb->len;
+ net_statistics[smp_processor_id()*2].OfoPruned += skb->len;
kfree_skb(skb);
skb = __skb_dequeue_tail(&tp->out_of_order_queue);
} while(skb != NULL);
@@ -2059,13 +2279,47 @@ static int prune_queue(struct sock *sk)
* if we are really having our buffer space abused we stop accepting
* new receive data.
*
+ * 8) The arguments are interesting, but I even cannot imagine
+ * what kind of arguments could force us to drop NICE, ALREADY
+ * RECEIVED DATA only to get one more packet? --ANK
+ *
* FIXME: it should recompute SACK state and only remove enough
* buffers to get into bounds again. The current scheme loses
- * badly sometimes on links with large RTT, especially when
- * the driver has high overhead per skb.
- * (increasing the rcvbuf is not enough because it inflates the
- * the window too, disabling flow control effectively) -AK
+ * badly sometimes on links with large RTT, especially when
+ * the driver has high overhead per skb.
+ * (increasing the rcvbuf is not enough because it inflates the
+ * the window too, disabling flow control effectively) -AK
+ *
+ * Mmm... Why not to scale it seprately then? Just replace
+ * / WINDOW_ADVERTISE_DIVISOR with >> sk->window_advertise_scale
+ * and adjust it dynamically, when TCP window flow control
+ * fails? -ANK
+ */
+
+ /* F.e. one possible tactics is: */
+ do {
+ u32 new_clamp = (tp->rcv_nxt-tp->copied_seq) + pruned;
+
+ /* This guy is not a good guy. I bet, he martirized cats,
+ * when was child and grew up to finished sadist. Clamp him!
+ */
+ if (new_clamp > 3*tp->ack.rcv_mss)
+ new_clamp -= tp->ack.rcv_mss;
+ else
+ new_clamp = 2*tp->ack.rcv_mss;
+ tp->window_clamp = min(tp->window_clamp, new_clamp);
+ } while (0);
+ /* Though it should be made earlier, when we are still not
+ * congested. This header prediction logic sucks
+ * without true implementation of VJ algorithm.
+ * I am really anxious. How was it possible to combine
+ * header prediction and sending ACKs outside of recvmsg() context?
+ * They _are_ incompatible. We should not advance window so
+ * brainlessly and we should not advertise so huge window from the very
+ * beginning. BTW window "prediction" does not speedup anything!
+ * SIlly, silly, silly.
*/
+
if(atomic_read(&sk->rmem_alloc) < (sk->rcvbuf << 1))
return 0;
@@ -2073,6 +2327,57 @@ static int prune_queue(struct sock *sk)
return -1;
}
+static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen)
+{
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ int chunk = skb->len - hlen;
+ int err;
+
+ local_bh_enable();
+ if (skb->ip_summed==CHECKSUM_UNNECESSARY)
+ err = memcpy_toiovec(tp->ucopy.iov, skb->h.raw + hlen, chunk);
+ else
+ err = copy_and_csum_toiovec(tp->ucopy.iov, skb, hlen);
+
+ if (!err) {
+update:
+ tp->ucopy.len -= chunk;
+ tp->copied_seq += chunk;
+ local_bh_disable();
+ return 0;
+ }
+
+ if (err == -EFAULT) {
+ sk->err = EFAULT;
+ sk->error_report(sk);
+ goto update;
+ }
+
+ local_bh_disable();
+ return err;
+}
+
+static int __tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
+{
+ int result;
+
+ if (sk->lock.users) {
+ local_bh_enable();
+ result = __tcp_checksum_complete(skb);
+ local_bh_disable();
+ } else {
+ result = __tcp_checksum_complete(skb);
+ }
+ return result;
+}
+
+static __inline__ int
+tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
+{
+ return skb->ip_summed != CHECKSUM_UNNECESSARY &&
+ __tcp_checksum_complete_user(sk, skb);
+}
+
/*
* TCP receive function for the ESTABLISHED state.
*
@@ -2080,7 +2385,33 @@ static int prune_queue(struct sock *sk)
* disabled when:
* - A zero window was announced from us - zero window probing
* is only handled properly in the slow path.
- * - Out of order segments arrived.
+ * [ NOTE: actually, it was made incorrectly and nobody ever noticed
+ * this! Reason is clear: 1. Correct senders do not send
+ * to zero window. 2. Even if a sender sends to zero window,
+ * nothing terrible occurs.
+ *
+ * For now I cleaned this and fast path is really always disabled,
+ * when window is zero, but I would be more happy to remove these
+ * checks. Code will be only cleaner and _faster_. --ANK
+ *
+ * Later note. I've just found that slow path also accepts
+ * out of window segments, look at tcp_sequence(). So...
+ * it is the last argument: I repair all and comment out
+ * repaired code by TCP_FORMAL_WINDOW.
+ * [ I remember one rhyme from a chidren's book. (I apologize,
+ * the trasnlation is not rhymed 8)): people in one (jewish) village
+ * decided to build sauna, but divided to two parties.
+ * The first one insisted that battens should not be dubbed,
+ * another objected that foots will suffer of splinters,
+ * the first fended that dubbed wet battens are too slippy
+ * and people will fall and it is much more serious!
+ * Certaiinly, all they went to rabbi.
+ * After some thinking, he judged: "Do not be lazy!
+ * Certainly, dub the battens! But put them by dubbed surface down."
+ * ]
+ * ]
+ *
+ * - Out of order segments arrived.
* - Urgent data is expected.
* - There is no buffer space left
* - Unexpected TCP flags/window values/header lengths are received
@@ -2088,7 +2419,7 @@ static int prune_queue(struct sock *sk)
* - Data is sent in both directions. Fast path only supports pure senders
* or pure receivers (this means either the sequence number or the ack
* value must stay constant)
- * - Unexpected TCP option.
+ * - Unexpected TCP option.
*
* When these conditions are not satisfied it drops into a standard
* receive procedure patterned after RFC793 to handle all cases.
@@ -2116,7 +2447,6 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
* We do checksum and copy also but from device to kernel.
*/
-
/* RED-PEN. Using static variables to pass function arguments
* cannot be good idea...
*/
@@ -2133,13 +2463,12 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
if ((tcp_flag_word(th) & ~(TCP_RESERVED_BITS|TCP_FLAG_PSH)) == tp->pred_flags &&
TCP_SKB_CB(skb)->seq == tp->rcv_nxt) {
- int tcp_header_len = th->doff*4;
-
- /* Timestamp header prediction */
+ int tcp_header_len = tp->tcp_header_len;
- /* Non-standard header f.e. SACKs -> slow path */
- if (tcp_header_len != tp->tcp_header_len)
- goto slow_path;
+ /* Timestamp header prediction: tcp_header_len
+ * is automatically equal to th->doff*4 due to pred_flags
+ * match.
+ */
/* Check timestamp */
if (tcp_header_len == sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) {
@@ -2161,8 +2490,8 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
goto slow_path;
/* Predicted packet is in window by definition.
- seq == rcv_nxt and last_ack_sent <= rcv_nxt.
- Hence, check seq<=last_ack_sent reduces to:
+ * seq == rcv_nxt and last_ack_sent <= rcv_nxt.
+ * Hence, check seq<=last_ack_sent reduces to:
*/
if (tp->rcv_nxt == tp->last_ack_sent) {
tp->ts_recent = tp->rcv_tsval;
@@ -2173,6 +2502,9 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
if (len <= tcp_header_len) {
/* Bulk data transfer: sender */
if (len == tcp_header_len) {
+ /* We know that such packets are checksummed
+ * on entry.
+ */
tcp_ack(sk, th, TCP_SKB_CB(skb)->seq,
TCP_SKB_CB(skb)->ack_seq, len);
kfree_skb(skb);
@@ -2182,19 +2514,42 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
TCP_INC_STATS_BH(TcpInErrs);
goto discard;
}
- } else if (TCP_SKB_CB(skb)->ack_seq == tp->snd_una &&
- atomic_read(&sk->rmem_alloc) <= sk->rcvbuf) {
- /* Bulk data transfer: receiver */
- __skb_pull(skb,tcp_header_len);
+ } else if (TCP_SKB_CB(skb)->ack_seq == tp->snd_una) {
+ int eaten = 0;
- /* Is it possible to simplify this? */
- tcp_measure_rcv_mss(sk, skb);
+ if (tp->ucopy.task == current &&
+ tp->copied_seq == tp->rcv_nxt &&
+ len - tcp_header_len <= tp->ucopy.len &&
+ sk->lock.users) {
+ eaten = 1;
+
+ NET_INC_STATS_BH(TCPHPHitsToUser);
+
+ if (tcp_copy_to_iovec(sk, skb, tcp_header_len))
+ goto csum_error;
+
+ __skb_pull(skb,tcp_header_len);
+ } else {
+ if (tcp_checksum_complete_user(sk, skb))
+ goto csum_error;
+
+ if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf)
+ goto step5;
+
+ NET_INC_STATS_BH(TCPHPHits);
+
+ /* Bulk data transfer: receiver */
+ __skb_pull(skb,tcp_header_len);
+
+ /* DO NOT notify forward progress here.
+ * It saves dozen of CPU instructions in fast path. --ANK
+ * And where is it signaled then ? -AK
+ * Nowhere. 8) --ANK
+ */
+ __skb_queue_tail(&sk->receive_queue, skb);
+ skb_set_owner_r(skb, sk);
+ }
- /* DO NOT notify forward progress here.
- * It saves dozen of CPU instructions in fast path. --ANK
- * And where is it signaled then ? -AK
- */
- __skb_queue_tail(&sk->receive_queue, skb);
tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
/* FIN bit check is not done since if FIN is set in
@@ -2202,27 +2557,43 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
*/
wake_up_interruptible(sk->sleep);
sock_wake_async(sk->socket,1, POLL_IN);
- tcp_delack_estimator(tp);
- tcp_remember_ack(tp, th, skb);
+ tcp_event_data_recv(tp, skb);
+#if 1/*def CONFIG_TCP_MORE_COARSE_ACKS*/
+ if (eaten) {
+ if (tcp_in_quickack_mode(tp)) {
+ tcp_send_ack(sk);
+ } else {
+ tcp_send_delayed_ack(sk);
+ }
+ } else
+#endif
__tcp_ack_snd_check(sk, 0);
+
+ if (eaten)
+ kfree_skb(skb);
return 0;
}
/* Packet is in sequence, flags are trivial;
- * only ACK is strange or we are tough on memory.
- * Jump to step 5.
+ * only ACK is strange. Jump to step 5.
*/
+ if (tcp_checksum_complete_user(sk, skb))
+ goto csum_error;
goto step5;
}
slow_path:
+ if (tcp_checksum_complete_user(sk, skb))
+ goto csum_error;
+
/*
* RFC1323: H1. Apply PAWS check first.
*/
if (tcp_fast_parse_options(sk, th, tp) && tp->saw_tstamp &&
tcp_paws_discard(tp, skb)) {
if (!th->rst) {
+ NET_INC_STATS_BH(PAWSEstabRejected);
tcp_send_ack(sk);
goto discard;
}
@@ -2251,7 +2622,9 @@ slow_path:
TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq,
tp->rcv_wup, tp->rcv_wnd);
}
+ tcp_enter_quickack_mode(tp);
tcp_send_ack(sk);
+ NET_INC_STATS_BH(DelayedACKLost);
goto discard;
}
@@ -2279,11 +2652,8 @@ step5:
/* Process urgent data. */
tcp_urg(sk, th, len);
- {
/* step 7: process the segment text */
- int queued = tcp_data(skb, sk, len);
-
- tcp_measure_rcv_mss(sk, skb);
+ tcp_data(skb, sk, len);
/* Be careful, tcp_data() may have put this into TIME_WAIT. */
if(sk->state != TCP_CLOSE) {
@@ -2291,12 +2661,13 @@ step5:
tcp_ack_snd_check(sk);
}
- if (!queued) {
- discard:
- kfree_skb(skb);
- }
- }
+ return 0;
+
+csum_error:
+ TCP_INC_STATS_BH(TcpInErrs);
+discard:
+ kfree_skb(skb);
return 0;
}
@@ -2328,6 +2699,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
newsk->dport = req->rmt_port;
sock_lock_init(newsk);
+ bh_lock_sock(newsk);
atomic_set(&newsk->rmem_alloc, 0);
skb_queue_head_init(&newsk->receive_queue);
@@ -2351,22 +2723,27 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
newtp->rcv_nxt = req->rcv_isn + 1;
newtp->snd_nxt = req->snt_isn + 1;
newtp->snd_una = req->snt_isn + 1;
- newtp->srtt = 0;
- newtp->ato = 0;
+ newtp->snd_sml = req->snt_isn + 1;
+
+ tcp_delack_init(newtp);
+ if (skb->len >= 536)
+ newtp->ack.last_seg_size = skb->len;
+
+ tcp_prequeue_init(newtp);
+
newtp->snd_wl1 = req->rcv_isn;
newtp->snd_wl2 = req->snt_isn;
- /* RFC1323: The window in SYN & SYN/ACK segments
- * is never scaled.
- */
- newtp->snd_wnd = ntohs(skb->h.th->window);
-
- newtp->max_window = newtp->snd_wnd;
- newtp->pending = 0;
newtp->retransmits = 0;
- newtp->last_ack_sent = req->rcv_isn + 1;
newtp->backoff = 0;
+ newtp->srtt = 0;
newtp->mdev = TCP_TIMEOUT_INIT;
+ newtp->rto = TCP_TIMEOUT_INIT;
+
+ newtp->packets_out = 0;
+ newtp->fackets_out = 0;
+ newtp->retrans_out = 0;
+ newtp->snd_ssthresh = 0x7fffffff;
/* So many TCP implementations out there (incorrectly) count the
* initial SYN frame in their delayed-ACK and congestion control
@@ -2374,22 +2751,11 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
* efficiently to them. -DaveM
*/
newtp->snd_cwnd = 2;
-
- newtp->rto = TCP_TIMEOUT_INIT;
- newtp->packets_out = 0;
- newtp->fackets_out = 0;
- newtp->retrans_out = 0;
- newtp->high_seq = 0;
- newtp->snd_ssthresh = 0x7fffffff;
newtp->snd_cwnd_cnt = 0;
+ newtp->high_seq = 0;
+
newtp->dup_acks = 0;
- newtp->delayed_acks = 0;
- init_timer(&newtp->retransmit_timer);
- newtp->retransmit_timer.function = &tcp_retransmit_timer;
- newtp->retransmit_timer.data = (unsigned long) newsk;
- init_timer(&newtp->delack_timer);
- newtp->delack_timer.function = &tcp_delack_timer;
- newtp->delack_timer.data = (unsigned long) newsk;
+ tcp_init_xmit_timers(newsk);
skb_queue_head_init(&newtp->out_of_order_queue);
newtp->send_head = newtp->retrans_head = NULL;
newtp->rcv_wup = req->rcv_isn + 1;
@@ -2397,31 +2763,25 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
newtp->copied_seq = req->rcv_isn + 1;
newtp->saw_tstamp = 0;
+ newtp->last_ack_sent = req->rcv_isn + 1;
- init_timer(&newtp->probe_timer);
- newtp->probe_timer.function = &tcp_probe_timer;
- newtp->probe_timer.data = (unsigned long) newsk;
newtp->probes_out = 0;
newtp->syn_seq = req->rcv_isn;
newtp->fin_seq = req->rcv_isn;
newtp->urg_data = 0;
- tcp_synq_init(newtp);
- newtp->syn_backlog = 0;
- if (skb->len >= 536)
- newtp->last_seg_size = skb->len;
+ newtp->listen_opt = NULL;
+ newtp->accept_queue = NULL;
+ /* Deinitialize syn_wait_lock to trap illegal accesses. */
+ memset(&newtp->syn_wait_lock, 0, sizeof(newtp->syn_wait_lock));
/* Back to base struct sock members. */
newsk->err = 0;
- newsk->ack_backlog = 0;
- newsk->max_ack_backlog = SOMAXCONN;
newsk->priority = 0;
atomic_set(&newsk->refcnt, 1);
+#ifdef INET_REFCNT_DEBUG
atomic_inc(&inet_sock_nr);
+#endif
- spin_lock_init(&sk->timer_lock);
- init_timer(&newsk->timer);
- newsk->timer.function = &tcp_keepalive_timer;
- newsk->timer.data = (unsigned long) newsk;
if (newsk->keepopen)
tcp_reset_keepalive_timer(newsk, keepalive_time_when(newtp));
newsk->socket = NULL;
@@ -2440,6 +2800,9 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
newtp->snd_wscale = newtp->rcv_wscale = 0;
newtp->window_clamp = min(newtp->window_clamp,65535);
}
+ newtp->snd_wnd = ntohs(skb->h.th->window) << newtp->snd_wscale;
+ newtp->max_window = newtp->snd_wnd;
+
if (newtp->tstamp_ok) {
newtp->ts_recent = req->ts_recent;
newtp->ts_recent_stamp = xtime.tv_sec;
@@ -2453,16 +2816,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
return newsk;
}
-static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win)
-{
- if (seq == s_win)
- return 1;
- if (after(end_seq, s_win) && before(seq, e_win))
- return 1;
- return (seq == e_win && seq == end_seq);
-}
-
-
/*
* Process an incoming packet for SYN_RECV sockets represented
* as an open_request.
@@ -2470,30 +2823,28 @@ static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win)
struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
struct open_request *req,
- struct open_request *prev)
+ struct open_request **prev)
{
struct tcphdr *th = skb->h.th;
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
u32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK);
int paws_reject = 0;
struct tcp_opt ttp;
-
- /* If socket has already been created, process
- packet in its context.
-
- We fall here only due to race, when packets were enqueued
- to backlog of listening socket.
- */
- if (req->sk)
- return req->sk;
+ struct sock *child;
ttp.saw_tstamp = 0;
if (th->doff > (sizeof(struct tcphdr)>>2)) {
-
tcp_parse_options(NULL, th, &ttp, 0);
- paws_reject = ttp.saw_tstamp &&
- (s32)(ttp.rcv_tsval - req->ts_recent) < 0;
+ if (ttp.saw_tstamp) {
+ ttp.ts_recent = req->ts_recent;
+ /* We do not store true stamp, but it is not required,
+ * it can be estimated (approximately)
+ * from another data.
+ */
+ ttp.ts_recent_stamp = xtime.tv_sec - ((TCP_TIMEOUT_INIT/HZ)<<req->retrans);
+ paws_reject = tcp_paws_check(&ttp, th->rst);
+ }
}
/* Check for pure retransmited SYN. */
@@ -2517,7 +2868,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
* Enforce "SYN-ACK" according to figure 8, figure 6
* of RFC793, fixed by RFC1122.
*/
- req->class->rtx_syn_ack(sk, req);
+ req->class->rtx_syn_ack(sk, req, NULL);
return NULL;
}
@@ -2544,6 +2895,8 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
/* Out of window: send ACK and drop. */
if (!(flg & TCP_FLAG_RST))
req->class->send_ack(skb, req);
+ if (paws_reject)
+ NET_INC_STATS_BH(PAWSEstabRejected);
return NULL;
}
@@ -2572,35 +2925,78 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
/* Invalid ACK: reset will be sent by listening socket */
if (TCP_SKB_CB(skb)->ack_seq != req->snt_isn+1)
return sk;
-
- /* OK, ACK is valid, create big socket and
- feed this segment to it. It will repeat all
- the tests. THIS SEGMENT MUST MOVE SOCKET TO
- ESTABLISHED STATE. If it will be dropped after
- socket is created, wait for troubles.
+ /* Also, it would be not so bad idea to check rcv_tsecr, which
+ * is essentially ACK extension and too early or too late values
+ * should cause reset in unsynchronized states.
*/
- sk = tp->af_specific->syn_recv_sock(sk, skb, req, NULL);
- if (sk == NULL)
+
+ /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */
+ if (tp->defer_accept && TCP_SKB_CB(skb)->end_seq == req->rcv_isn+1) {
+ req->acked = 1;
return NULL;
+ }
- tcp_dec_slow_timer(TCP_SLT_SYNACK);
- req->sk = sk;
- return sk;
+ /* OK, ACK is valid, create big socket and
+ * feed this segment to it. It will repeat all
+ * the tests. THIS SEGMENT MUST MOVE SOCKET TO
+ * ESTABLISHED STATE. If it will be dropped after
+ * socket is created, wait for troubles.
+ */
+ child = tp->af_specific->syn_recv_sock(sk, skb, req, NULL);
+ if (child == NULL)
+ goto listen_overflow;
-embryonic_reset:
tcp_synq_unlink(tp, req, prev);
- tp->syn_backlog--;
- tcp_dec_slow_timer(TCP_SLT_SYNACK);
+ tcp_synq_removed(sk, req);
+
+ tcp_acceptq_queue(sk, req, child);
+ return child;
+listen_overflow:
+ if (!sysctl_tcp_abort_on_overflow) {
+ req->acked = 1;
+ return NULL;
+ }
+
+embryonic_reset:
NET_INC_STATS_BH(EmbryonicRsts);
if (!(flg & TCP_FLAG_RST))
req->class->send_reset(skb);
- req->class->destructor(req);
- tcp_openreq_free(req);
+ tcp_synq_drop(sk, req, prev);
return NULL;
}
+/*
+ * Queue segment on the new socket if the new socket is active,
+ * otherwise we just shortcircuit this and continue with
+ * the new socket.
+ */
+
+int tcp_child_process(struct sock *parent, struct sock *child,
+ struct sk_buff *skb)
+{
+ int ret = 0;
+ int state = child->state;
+
+ if (child->lock.users == 0) {
+ ret = tcp_rcv_state_process(child, skb, skb->h.th, skb->len);
+
+ /* Wakeup parent, send SIGIO */
+ if (state == TCP_SYN_RECV && child->state != state)
+ parent->data_ready(parent, 0);
+ } else {
+ /* Alas, it is possible again, because we do lookup
+ * in main socket hash table and lock on listening
+ * socket does not protect us more.
+ */
+ sk_add_backlog(child, skb);
+ }
+
+ bh_unlock_sock(child);
+ return ret;
+}
+
static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
struct tcphdr *th, unsigned len)
{
@@ -2608,25 +3004,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
tcp_parse_options(sk, th, tp, 0);
-#ifdef CONFIG_TCP_TW_RECYCLE
- if (tp->ts_recent_stamp && tp->saw_tstamp && !th->rst &&
- (s32)(tp->rcv_tsval - tp->ts_recent) < 0 &&
- xtime.tv_sec < tp->ts_recent_stamp + PAWS_24DAYS) {
- /* Old duplicate segment. We remember last
- ts_recent from this host in timewait bucket.
-
- Actually, we could implement per host cache
- to truncate timewait state after RTO. Paranoidal arguments
- of rfc1337 are not enough to close this nice possibility.
- */
- if (net_ratelimit())
- printk(KERN_DEBUG "TCP: tw recycle, PAWS worked. Good.\n");
- if (th->ack)
- return 1;
- goto discard;
- }
-#endif
-
if (th->ack) {
/* rfc793:
* "If the state is SYN-SENT then
@@ -2646,10 +3023,36 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
* We do not send data with SYN, so that RFC-correct
* test reduces to:
*/
- if (sk->zapped ||
- TCP_SKB_CB(skb)->ack_seq != tp->snd_nxt)
+ if (TCP_SKB_CB(skb)->ack_seq != tp->snd_nxt)
return 1;
+ /* Check not from any RFC, but it is evident consequence
+ * of combining PAWS and usual SYN-SENT logic: ACK _is_
+ * checked in SYN-SENT unlike another states, hence
+ * echoed tstamp must be checked too.
+ */
+ if (tp->saw_tstamp) {
+ if (tp->rcv_tsecr == 0) {
+ /* Workaround for bug in linux-2.1 and early
+ * 2.2 kernels. Let's pretend that we did not
+ * see such timestamp to avoid bogus rtt value,
+ * calculated by tcp_ack().
+ */
+ tp->saw_tstamp = 0;
+
+ /* But do not forget to store peer's timestamp! */
+ if (th->syn) {
+ tp->ts_recent = tp->rcv_tsval;
+ tp->ts_recent_stamp = xtime.tv_sec;
+ }
+ } else if ((__s32)(tp->rcv_tsecr - tcp_time_stamp) > 0 ||
+ (__s32)(tp->rcv_tsecr - tp->syn_stamp) < 0) {
+ NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "TCP: synsent reject.\n"));
+ NET_INC_STATS_BH(PAWSActiveRejected);
+ return 1;
+ }
+ }
+
/* Now ACK is acceptable.
*
* "If the RST bit is set
@@ -2689,18 +3092,13 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
* because tcp_ack check is too weak for SYN-SENT)
* causes moving socket to invalid semi-SYN-SENT,
* semi-ESTABLISHED state and connection hangs.
- *
- * There exist buggy stacks, which really send
- * such ACKs: f.e. 202.226.91.94 (okigate.oki.co.jp)
- * Actually, if this host did not try to get something
- * from ftp.inr.ac.ru I'd never find this bug 8)
- *
* --ANK (990514)
*
- * I was wrong, I apologize. Bare ACK is valid.
+ * Bare ACK is valid, however.
* Actually, RFC793 requires to send such ACK
* in reply to any out of window packet.
- * It is wrong, but Linux also does it sometimes.
+ * It is wrong, but Linux also send such
+ * useless ACKs sometimes.
* --ANK (990724)
*/
@@ -2717,7 +3115,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
/* RFC1323: The window in SYN & SYN/ACK segments is
* never scaled.
*/
- tp->snd_wnd = htons(th->window);
+ tp->snd_wnd = ntohs(th->window);
tp->snd_wl1 = TCP_SKB_CB(skb)->seq;
tp->snd_wl2 = TCP_SKB_CB(skb)->ack_seq;
tp->fin_seq = TCP_SKB_CB(skb)->seq;
@@ -2742,26 +3140,35 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
tcp_initialize_rcv_mss(sk);
tcp_init_metrics(sk);
+ if (sk->keepopen)
+ tcp_reset_keepalive_timer(sk, keepalive_time_when(tp));
+
+ tp->copied_seq = tp->rcv_nxt;
+ __tcp_fast_path_on(tp, tp->snd_wnd);
+
+ if(!sk->dead) {
+ sk->state_change(sk);
+ sock_wake_async(sk->socket, 0, POLL_OUT);
+ }
+
if (tp->write_pending) {
/* Save one ACK. Data will be ready after
* several ticks, if write_pending is set.
*
- * How to make this correctly?
+ * It may be deleted, but with this feature tcpdumps
+ * look so _wonderfully_ clever, that I was not able
+ * to stand against the temptation 8) --ANK
*/
- tp->delayed_acks++;
- if (tp->ato == 0)
- tp->ato = tp->rto;
- tcp_send_delayed_ack(sk, tp->rto);
+ tp->ack.pending = 1;
+ tp->ack.lrcvtime = tcp_time_stamp;
+ tcp_enter_quickack_mode(tp);
+ tp->ack.pingpong = 1;
+ tp->ack.ato = TCP_ATO_MIN;
+ tcp_reset_xmit_timer(sk, TCP_TIME_DACK, TCP_DELACK_MIN);
+ goto discard;
} else {
tcp_send_ack(sk);
}
-
- tp->copied_seq = tp->rcv_nxt;
-
- if(!sk->dead) {
- wake_up_interruptible(sk->sleep);
- sock_wake_async(sk->socket, 0, POLL_OUT);
- }
return -1;
}
@@ -2777,6 +3184,10 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
goto discard;
}
+ /* PAWS check. */
+ if (tp->ts_recent_stamp && tp->saw_tstamp && tcp_paws_check(tp, 0))
+ goto discard;
+
if (th->syn) {
/* We see SYN without ACK. It is attempt of
* simultaneous connect with crossed SYNs.
@@ -2800,8 +3211,9 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
/* RFC1323: The window in SYN & SYN/ACK segments is
* never scaled.
*/
- tp->snd_wnd = htons(th->window);
+ tp->snd_wnd = ntohs(th->window);
tp->snd_wl1 = TCP_SKB_CB(skb)->seq;
+ tp->max_window = tp->snd_wnd;
tcp_sync_mss(sk, tp->pmtu_cookie);
tcp_initialize_rcv_mss(sk);
@@ -2960,6 +3372,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
#endif
) {
if (!th->rst) {
+ NET_INC_STATS_BH(DelayedACKLost);
+ tcp_enter_quickack_mode(tp);
tcp_send_ack(sk);
}
goto discard;
@@ -3011,28 +3425,29 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
tp->copied_seq = tp->rcv_nxt;
/* Note, that this wakeup is only for marginal
- crossed SYN case. Passively open sockets
- are not waked up, because sk->sleep == NULL
- and sk->socket == NULL.
+ * crossed SYN case. Passively open sockets
+ * are not waked up, because sk->sleep == NULL
+ * and sk->socket == NULL.
*/
- if (!sk->dead && sk->sleep) {
- wake_up_interruptible(sk->sleep);
+ if (!sk->dead) {
+ sk->state_change(sk);
sock_wake_async(sk->socket,0,POLL_OUT);
}
tp->snd_una = TCP_SKB_CB(skb)->ack_seq;
- tp->snd_wnd = htons(th->window) << tp->snd_wscale;
+ tp->snd_wnd = ntohs(th->window) << tp->snd_wscale;
tp->snd_wl1 = TCP_SKB_CB(skb)->seq;
tp->snd_wl2 = TCP_SKB_CB(skb)->ack_seq;
/* tcp_ack considers this ACK as duplicate
- * and does not calculate rtt. It is wrong.
+ * and does not calculate rtt.
* Fix it at least with timestamps.
*/
if (tp->saw_tstamp && !tp->srtt)
tcp_ack_saw_tstamp(sk, tp, 0, 0, FLAG_SYN_ACKED);
tcp_init_metrics(sk);
+ tcp_fast_path_on(tp);
} else {
SOCK_DEBUG(sk, "bad ack\n");
return 1;
@@ -3041,26 +3456,50 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
case TCP_FIN_WAIT1:
if (tp->snd_una == tp->write_seq) {
- sk->shutdown |= SEND_SHUTDOWN;
tcp_set_state(sk, TCP_FIN_WAIT2);
- if (!sk->dead)
- sk->state_change(sk);
- else
- tcp_reset_keepalive_timer(sk, sysctl_tcp_fin_timeout);
+ sk->shutdown |= SEND_SHUTDOWN;
dst_confirm(sk->dst_cache);
+
+ if (!sk->dead) {
+ /* Wake up lingering close() */
+ sk->state_change(sk);
+ } else {
+ int tmo;
+
+ if (tp->linger2 < 0 ||
+ after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) {
+ tcp_done(sk);
+ return 1;
+ }
+
+ tmo = tcp_fin_time(tp);
+ if (tmo > TCP_TIMEWAIT_LEN) {
+ tcp_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN);
+ } else if (th->fin || sk->lock.users) {
+ /* Bad case. We could lose such FIN otherwise.
+ * It is not a big problem, but it looks confusing
+ * and not so rare event. We still can lose it now,
+ * if it spins in bh_lock_sock(), but it is really
+ * marginal case.
+ */
+ tcp_reset_keepalive_timer(sk, tmo);
+ } else {
+ tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
+ goto discard;
+ }
+ }
}
break;
- case TCP_CLOSING:
+ case TCP_CLOSING:
if (tp->snd_una == tp->write_seq) {
- tcp_time_wait(sk);
+ tcp_time_wait(sk, TCP_TIME_WAIT, 0);
goto discard;
}
break;
case TCP_LAST_ACK:
if (tp->snd_una == tp->write_seq) {
- tcp_set_state(sk,TCP_CLOSE);
tcp_update_metrics(sk);
tcp_done(sk);
goto discard;
@@ -3080,27 +3519,22 @@ step6:
case TCP_CLOSING:
if (!before(TCP_SKB_CB(skb)->seq, tp->fin_seq))
break;
-
case TCP_FIN_WAIT1:
case TCP_FIN_WAIT2:
/* RFC 793 says to queue data in these states,
* RFC 1122 says we MUST send a reset.
* BSD 4.4 also does reset.
*/
- if ((sk->shutdown & RCV_SHUTDOWN) && sk->dead) {
+ if (sk->shutdown & RCV_SHUTDOWN) {
if (after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) {
tcp_reset(sk);
return 1;
}
}
-
+ /* Fall through */
case TCP_ESTABLISHED:
- queued = tcp_data(skb, sk, len);
-
- /* This must be after tcp_data() does the skb_pull() to
- * remove the header size from skb->len.
- */
- tcp_measure_rcv_mss(sk, skb);
+ tcp_data(skb, sk, len);
+ queued = 1;
break;
}
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 22c35a191..7420e268f 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_ipv4.c,v 1.194 2000/01/09 02:19:41 davem Exp $
+ * Version: $Id: tcp_ipv4.c,v 1.197 2000/01/21 06:37:28 davem Exp $
*
* IPv4 specific functions
*
@@ -52,7 +52,6 @@
#include <linux/fcntl.h>
#include <linux/random.h>
#include <linux/init.h>
-#include <linux/ipsec.h>
#include <net/icmp.h>
#include <net/tcp.h>
@@ -61,15 +60,9 @@
#include <linux/inet.h>
#include <linux/stddef.h>
+#include <linux/ipsec.h>
-extern int sysctl_tcp_timestamps;
-extern int sysctl_tcp_window_scaling;
-extern int sysctl_tcp_sack;
-extern int sysctl_tcp_syncookies;
-extern int sysctl_tcp_tw_recycle;
extern int sysctl_ip_dynaddr;
-extern __u32 sysctl_wmem_max;
-extern __u32 sysctl_rmem_max;
/* Check TCP sequence numbers in ICMP packets. */
#define ICMP_MIN_LENGTH 8
@@ -319,89 +312,13 @@ void tcp_put_port(struct sock *sk)
local_bh_enable();
}
-#ifdef CONFIG_TCP_TW_RECYCLE
-/*
- Very stupid pseudo-"algoritm". If the approach will be successful
- (and it will!), we have to make it more reasonable.
- Now it eats lots of CPU, when we are tough on ports.
-
- Apparently, it should be hash table indexed by daddr/dport.
-
- How does it work? We allow to truncate time-wait state, if:
- 1. PAWS works on it.
- 2. timewait bucket did not receive data for timeout:
- - initially timeout := 2*RTO, so that if our ACK to first
- transmitted peer's FIN is lost, we will see first retransmit.
- - if we receive anything, the timout is increased exponentially
- to follow normal TCP backoff pattern.
- It is important that minimal RTO (HZ/5) > minimal timestamp
- step (1ms).
- 3. When creating new socket, we inherit sequence number
- and ts_recent of time-wait bucket, increasinf them a bit.
-
- These two conditions guarantee, that data will not be corrupted
- both by retransmitted and by delayed segments. They do not guarantee
- that peer will leave LAST-ACK/CLOSING state gracefully, it will be
- reset sometimes, namely, when more than two our ACKs to its FINs are lost.
- This reset is harmless and even good.
+/* This lock without TASK_EXCLUSIVE is good on UP and it can be very bad on SMP.
+ * Look, when several writers sleep and reader wakes them up, all but one
+ * immediately hit write lock and grab all the cpus. Exclusive sleep solves
+ * this, _but_ remember, it adds useless work on UP machines (wake up each
+ * exclusive lock release). It should be ifdefed really.
*/
-int tcp_v4_tw_recycle(struct sock *sk, u32 daddr, u16 dport)
-{
- static int tw_rover;
-
- struct tcp_tw_bucket *tw;
- struct tcp_bind_hashbucket *head;
- struct tcp_bind_bucket *tb;
-
- int low = sysctl_local_port_range[0];
- int high = sysctl_local_port_range[1];
- unsigned long now = jiffies;
- int i, rover;
-
- rover = tw_rover;
-
- local_bh_disable();
- for (i=0; i<tcp_bhash_size; i++, rover++) {
- rover &= (tcp_bhash_size-1);
- head = &tcp_bhash[rover];
-
- spin_lock(&head->lock);
- for (tb = head->chain; tb; tb = tb->next) {
- tw = (struct tcp_tw_bucket*)tb->owners;
-
- if (tw->state != TCP_TIME_WAIT ||
- tw->dport != dport ||
- tw->daddr != daddr ||
- tw->rcv_saddr != sk->rcv_saddr ||
- tb->port < low ||
- tb->port >= high ||
- !TCP_INET_FAMILY(tw->family) ||
- tw->ts_recent_stamp == 0 ||
- (long)(now - tw->ttd) <= 0)
- continue;
- tw_rover = rover;
- goto hit;
- }
- spin_unlock(&head->lock);
- }
- local_bh_enable();
- tw_rover = rover;
- return -EAGAIN;
-
-hit:
- sk->num = tw->num;
- if ((sk->bind_next = tb->owners) != NULL)
- tb->owners->bind_pprev = &sk->bind_next;
- tb->owners = sk;
- sk->bind_pprev = &tb->owners;
- sk->prev = (struct sock *) tb;
- spin_unlock_bh(&head->lock);
- return 0;
-}
-#endif
-
-
void tcp_listen_wlock(void)
{
write_lock(&tcp_lhash_lock);
@@ -409,9 +326,9 @@ void tcp_listen_wlock(void)
if (atomic_read(&tcp_lhash_users)) {
DECLARE_WAITQUEUE(wait, current);
- add_wait_queue(&tcp_lhash_wait, &wait);
+ add_wait_queue_exclusive(&tcp_lhash_wait, &wait);
for (;;) {
- set_current_state(TASK_UNINTERRUPTIBLE);
+ set_current_state(TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE);
if (atomic_read(&tcp_lhash_users) == 0)
break;
write_unlock_bh(&tcp_lhash_lock);
@@ -445,6 +362,8 @@ static __inline__ void __tcp_v4_hash(struct sock *sk)
sk->pprev = skp;
sock_prot_inc_use(sk->prot);
write_unlock(lock);
+ if (sk->state == TCP_LISTEN)
+ wake_up(&tcp_lhash_wait);
}
static void tcp_v4_hash(struct sock *sk)
@@ -478,6 +397,8 @@ void tcp_unhash(struct sock *sk)
sock_prot_dec_use(sk->prot);
}
write_unlock_bh(lock);
+ if (sk->state == TCP_LISTEN)
+ wake_up(&tcp_lhash_wait);
}
/* Don't inline this cruft. Here are some nice properties to
@@ -546,8 +467,9 @@ sherry_cache:
*
* Local BH must be disabled here.
*/
-static inline struct sock *__tcp_v4_lookup(u32 saddr, u16 sport,
- u32 daddr, u16 hnum, int dif)
+
+static inline struct sock *__tcp_v4_lookup_established(u32 saddr, u16 sport,
+ u32 daddr, u16 hnum, int dif)
{
struct tcp_ehash_bucket *head;
TCP_V4_ADDR_COOKIE(acookie, saddr, daddr)
@@ -572,7 +494,7 @@ static inline struct sock *__tcp_v4_lookup(u32 saddr, u16 sport,
goto hit;
read_unlock(&head->lock);
- return tcp_v4_lookup_listener(daddr, hnum, dif);
+ return NULL;
hit:
sock_hold(sk);
@@ -580,6 +502,19 @@ hit:
return sk;
}
+static inline struct sock *__tcp_v4_lookup(u32 saddr, u16 sport,
+ u32 daddr, u16 hnum, int dif)
+{
+ struct sock *sk;
+
+ sk = __tcp_v4_lookup_established(saddr, sport, daddr, hnum, dif);
+
+ if (sk)
+ return sk;
+
+ return tcp_v4_lookup_listener(daddr, hnum, dif);
+}
+
__inline__ struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
{
struct sock *sk;
@@ -609,21 +544,16 @@ static int tcp_v4_check_established(struct sock *sk)
int hash = tcp_hashfn(daddr, sk->num, saddr, sk->dport);
struct tcp_ehash_bucket *head = &tcp_ehash[hash];
struct sock *sk2, **skp;
-#ifdef CONFIG_TCP_TW_RECYCLE
struct tcp_tw_bucket *tw;
-#endif
write_lock_bh(&head->lock);
/* Check TIME-WAIT sockets first. */
for(skp = &(head + tcp_ehash_size)->chain; (sk2=*skp) != NULL;
skp = &sk2->next) {
-#ifdef CONFIG_TCP_TW_RECYCLE
tw = (struct tcp_tw_bucket*)sk2;
-#endif
if(TCP_IPV4_MATCH(sk2, acookie, saddr, daddr, ports, dif)) {
-#ifdef CONFIG_TCP_TW_RECYCLE
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
/* With PAWS, it is safe from the viewpoint
@@ -631,12 +561,17 @@ static int tcp_v4_check_established(struct sock *sk)
is safe provided sequence spaces do not
overlap i.e. at data rates <= 80Mbit/sec.
- Actually, the idea is close to VJ's (rfc1332)
- one, only timestamp cache is held not per host,
+ Actually, the idea is close to VJ's one,
+ only timestamp cache is held not per host,
but per port pair and TW bucket is used
as state holder.
+
+ If TW bucket has been already destroyed we
+ fall back to VJ's scheme and use initial
+ timestamp retrieved from peer table.
*/
- if (sysctl_tcp_tw_recycle && tw->ts_recent_stamp) {
+ if (tw->substate == TCP_TIME_WAIT &&
+ sysctl_tcp_tw_recycle && tw->ts_recent_stamp) {
if ((tp->write_seq = tw->snd_nxt + 2) == 0)
tp->write_seq = 1;
tp->ts_recent = tw->ts_recent;
@@ -645,13 +580,10 @@ static int tcp_v4_check_established(struct sock *sk)
skp = &head->chain;
goto unique;
} else
-#endif
- goto not_unique;
+ goto not_unique;
}
}
-#ifdef CONFIG_TCP_TW_RECYCLE
tw = NULL;
-#endif
/* And established part... */
for(skp = &head->chain; (sk2=*skp)!=NULL; skp = &sk2->next) {
@@ -659,9 +591,7 @@ static int tcp_v4_check_established(struct sock *sk)
goto not_unique;
}
-#ifdef CONFIG_TCP_TW_RECYCLE
unique:
-#endif
BUG_TRAP(sk->pprev==NULL);
if ((sk->next = *skp) != NULL)
(*skp)->pprev = &sk->next;
@@ -671,17 +601,17 @@ unique:
sock_prot_inc_use(sk->prot);
write_unlock_bh(&head->lock);
-#ifdef CONFIG_TCP_TW_RECYCLE
if (tw) {
/* Silly. Should hash-dance instead... */
local_bh_disable();
tcp_tw_deschedule(tw);
tcp_timewait_kill(tw);
+ NET_INC_STATS_BH(TimeWaitRecycled);
local_bh_enable();
tcp_tw_put(tw);
}
-#endif
+
return 0;
not_unique:
@@ -727,9 +657,6 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
int tmp;
int err;
- if (sk->state != TCP_CLOSE)
- return(-EISCONN);
-
if (addr_len < sizeof(struct sockaddr_in))
return(-EINVAL);
@@ -759,8 +686,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
daddr = rt->rt_dst;
err = -ENOBUFS;
- buff = sock_wmalloc(sk, (MAX_HEADER + sk->prot->max_header),
- 0, GFP_KERNEL);
+ buff = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 0, GFP_KERNEL);
if (buff == NULL)
goto failure;
@@ -769,27 +695,28 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
sk->saddr = rt->rt_src;
sk->rcv_saddr = sk->saddr;
- if (!sk->num) {
- if (sk->prot->get_port(sk, 0)
-#ifdef CONFIG_TCP_TW_RECYCLE
- && (!sysctl_tcp_tw_recycle ||
- tcp_v4_tw_recycle(sk, daddr, usin->sin_port))
-#endif
- ) {
- kfree_skb(buff);
- err = -EAGAIN;
- goto failure;
- }
- sk->sport = htons(sk->num);
- }
-#ifdef CONFIG_TCP_TW_RECYCLE
- else if (tp->ts_recent_stamp && sk->daddr != daddr) {
+ if (tp->ts_recent_stamp && sk->daddr != daddr) {
/* Reset inherited state */
tp->ts_recent = 0;
tp->ts_recent_stamp = 0;
tp->write_seq = 0;
}
-#endif
+
+ if (sysctl_tcp_tw_recycle &&
+ !tp->ts_recent_stamp &&
+ rt->rt_dst == daddr) {
+ struct inet_peer *peer = rt_get_peer(rt);
+
+ /* VJ's idea. We save last timestamp seen from
+ * the destination in peer table, when entering state TIME-WAIT
+ * and initialize ts_recent from it, when trying new connection.
+ */
+
+ if (peer && peer->tcp_ts_stamp + TCP_PAWS_MSL >= xtime.tv_sec) {
+ tp->ts_recent_stamp = peer->tcp_ts_stamp;
+ tp->ts_recent = peer->tcp_ts;
+ }
+ }
sk->dport = usin->sin_port;
sk->daddr = daddr;
@@ -814,85 +741,62 @@ failure:
return err;
}
-static int tcp_v4_sendmsg(struct sock *sk, struct msghdr *msg, int len)
+static __inline__ int tcp_v4_iif(struct sk_buff *skb)
{
- int retval = -EINVAL;
-
- lock_sock(sk);
-
- /* Do sanity checking for sendmsg/sendto/send. */
- if (msg->msg_flags & ~(MSG_OOB|MSG_DONTROUTE|MSG_DONTWAIT|MSG_NOSIGNAL))
- goto out;
- if (msg->msg_name) {
- struct sockaddr_in *addr=(struct sockaddr_in *)msg->msg_name;
-
- if (msg->msg_namelen < sizeof(*addr))
- goto out;
- if (addr->sin_family && addr->sin_family != AF_INET)
- goto out;
- retval = -ENOTCONN;
- if(sk->state == TCP_CLOSE)
- goto out;
- retval = -EISCONN;
- if (addr->sin_port != sk->dport)
- goto out;
- if (addr->sin_addr.s_addr != sk->daddr)
- goto out;
- }
- retval = tcp_do_sendmsg(sk, msg);
-
-out:
- release_sock(sk);
- return retval;
+ return ((struct rtable*)skb->dst)->rt_iif;
}
+static __inline__ unsigned tcp_v4_synq_hash(u32 raddr, u16 rport)
+{
+ unsigned h = raddr ^ rport;
+ h ^= h>>16;
+ h ^= h>>8;
+ return h&(TCP_SYNQ_HSIZE-1);
+}
-/*
- * Do a linear search in the socket open_request list.
- * This should be replaced with a global hash table.
- */
static struct open_request *tcp_v4_search_req(struct tcp_opt *tp,
struct iphdr *iph,
struct tcphdr *th,
- struct open_request **prevp)
+ struct open_request ***prevp)
{
- struct open_request *req, *prev;
- __u16 rport = th->source;
-
- /* assumption: the socket is not in use.
- * as we checked the user count on tcp_rcv and we're
- * running from a soft interrupt.
- */
- prev = (struct open_request *) (&tp->syn_wait_queue);
- for (req = prev->dl_next; req; req = req->dl_next) {
- if (req->af.v4_req.rmt_addr == iph->saddr &&
+ struct tcp_listen_opt *lopt = tp->listen_opt;
+ struct open_request *req, **prev;
+ __u16 rport = th->source;
+ __u32 raddr = iph->saddr;
+
+ for (prev = &lopt->syn_table[tcp_v4_synq_hash(raddr, rport)];
+ (req = *prev) != NULL;
+ prev = &req->dl_next) {
+ if (req->rmt_port == rport &&
+ req->af.v4_req.rmt_addr == raddr &&
req->af.v4_req.loc_addr == iph->daddr &&
- req->rmt_port == rport &&
TCP_INET_FAMILY(req->class->family)) {
- if (req->sk) {
- /* Weird case: connection was established
- and then killed by RST before user accepted
- it. This connection is dead, but we cannot
- kill openreq to avoid blocking in accept().
-
- accept() will collect this garbage,
- but such reqs must be ignored, when talking
- to network.
- */
- bh_lock_sock(req->sk);
- BUG_TRAP(req->sk->lock.users==0);
- if (req->sk->state == TCP_CLOSE) {
- bh_unlock_sock(req->sk);
- prev = req;
- continue;
- }
- }
+ BUG_TRAP(req->sk == NULL);
*prevp = prev;
return req;
}
- prev = req;
}
- return NULL;
+
+ return NULL;
+}
+
+static void tcp_v4_synq_add(struct sock *sk, struct open_request *req)
+{
+ struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
+ struct tcp_listen_opt *lopt = tp->listen_opt;
+ unsigned h = tcp_v4_synq_hash(req->af.v4_req.rmt_addr, req->rmt_port);
+
+ req->expires = jiffies + TCP_TIMEOUT_INIT;
+ req->retrans = 0;
+ req->sk = NULL;
+ req->index = h;
+ req->dl_next = lopt->syn_table[h];
+
+ write_lock(&tp->syn_wait_lock);
+ lopt->syn_table[h] = req;
+ write_unlock(&tp->syn_wait_lock);
+
+ tcp_synq_added(sk);
}
@@ -984,7 +888,7 @@ void tcp_v4_err(struct sk_buff *skb, unsigned char *dp, int len)
th = (struct tcphdr*)(dp+(iph->ihl<<2));
- sk = tcp_v4_lookup(iph->daddr, th->dest, iph->saddr, th->source, skb->dev->ifindex);
+ sk = tcp_v4_lookup(iph->daddr, th->dest, iph->saddr, th->source, tcp_v4_iif(skb));
if (sk == NULL) {
ICMP_INC_STATS_BH(IcmpInErrors);
return;
@@ -1001,6 +905,9 @@ void tcp_v4_err(struct sk_buff *skb, unsigned char *dp, int len)
if (sk->lock.users != 0)
NET_INC_STATS_BH(LockDroppedIcmps);
+ if (sk->state == TCP_CLOSE)
+ goto out;
+
tp = &sk->tp_pinfo.af_tcp;
seq = ntohl(th->seq);
if (sk->state != TCP_LISTEN && !between(seq, tp->snd_una, tp->snd_nxt)) {
@@ -1010,14 +917,11 @@ void tcp_v4_err(struct sk_buff *skb, unsigned char *dp, int len)
switch (type) {
case ICMP_SOURCE_QUENCH:
-#ifndef OLD_SOURCE_QUENCH /* This is deprecated */
- if (sk->lock.users == 0) {
- tp->snd_ssthresh = tcp_recalc_ssthresh(tp);
- tp->snd_cwnd = tp->snd_ssthresh;
- tp->snd_cwnd_cnt = 0;
- tp->high_seq = tp->snd_nxt;
- }
-#endif
+ /* This is deprecated, but if someone generated it,
+ * we have no reasons to ignore it.
+ */
+ if (sk->lock.users == 0)
+ tcp_enter_cong_avoid(tp);
goto out;
case ICMP_PARAMETERPROB:
err = EPROTO;
@@ -1042,7 +946,7 @@ void tcp_v4_err(struct sk_buff *skb, unsigned char *dp, int len)
}
switch (sk->state) {
- struct open_request *req, *prev;
+ struct open_request *req, **prev;
case TCP_LISTEN:
if (sk->lock.users != 0)
goto out;
@@ -1060,47 +964,25 @@ void tcp_v4_err(struct sk_buff *skb, unsigned char *dp, int len)
if (!req)
goto out;
- if (req->sk) {
- struct sock *nsk = req->sk;
-
- /*
- * Already in ESTABLISHED and a big socket is created,
- * set error code there.
- * The error will _not_ be reported in the accept(),
- * but only with the next operation on the socket after
- * accept.
- */
- sock_hold(nsk);
- bh_unlock_sock(sk);
- sock_put(sk);
- sk = nsk;
-
- BUG_TRAP(sk->lock.users == 0);
- tp = &sk->tp_pinfo.af_tcp;
- if (!between(seq, tp->snd_una, tp->snd_nxt)) {
- NET_INC_STATS(OutOfWindowIcmps);
- goto out;
- }
- } else {
- if (seq != req->snt_isn) {
- NET_INC_STATS(OutOfWindowIcmps);
- goto out;
- }
+ /* ICMPs are not backlogged, hence we cannot get
+ an established socket here.
+ */
+ BUG_TRAP(req->sk == NULL);
- /*
- * Still in SYN_RECV, just remove it silently.
- * There is no good way to pass the error to the newly
- * created socket, and POSIX does not want network
- * errors returned from accept().
- */
- tp->syn_backlog--;
- tcp_synq_unlink(tp, req, prev);
- tcp_dec_slow_timer(TCP_SLT_SYNACK);
- req->class->destructor(req);
- tcp_openreq_free(req);
+ if (seq != req->snt_isn) {
+ NET_INC_STATS_BH(OutOfWindowIcmps);
goto out;
}
- break;
+
+ /*
+ * Still in SYN_RECV, just remove it silently.
+ * There is no good way to pass the error to the newly
+ * created socket, and POSIX does not want network
+ * errors returned from accept().
+ */
+ tcp_synq_drop(sk, req, prev);
+ goto out;
+
case TCP_SYN_SENT:
case TCP_SYN_RECV: /* Cannot happen.
It can f.e. if SYNs crossed.
@@ -1110,10 +992,9 @@ void tcp_v4_err(struct sk_buff *skb, unsigned char *dp, int len)
if (sk->lock.users == 0) {
TCP_INC_STATS_BH(TcpAttemptFails);
sk->err = err;
- /* Wake people up to see the error (see connect in sock.c) */
+
sk->error_report(sk);
- tcp_set_state(sk, TCP_CLOSE);
tcp_done(sk);
} else {
sk->err_soft = err;
@@ -1270,28 +1151,23 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
{
struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk;
- tcp_v4_send_ack(skb, tw->snd_nxt, tw->rcv_nxt, 0, tw->ts_recent);
+ tcp_v4_send_ack(skb, tw->snd_nxt, tw->rcv_nxt,
+ tw->rcv_wnd>>tw->rcv_wscale, tw->ts_recent);
tcp_tw_put(tw);
}
static void tcp_v4_or_send_ack(struct sk_buff *skb, struct open_request *req)
{
- tcp_v4_send_ack(skb, req->snt_isn+1, req->rcv_isn+1, req->rcv_wnd, req->ts_recent);
+ tcp_v4_send_ack(skb, req->snt_isn+1, req->rcv_isn+1, req->rcv_wnd,
+ req->ts_recent);
}
-/*
- * Send a SYN-ACK after having received an ACK.
- * This still operates on a open_request only, not on a big
- * socket.
- */
-static void tcp_v4_send_synack(struct sock *sk, struct open_request *req)
+static struct dst_entry* tcp_v4_route_req(struct sock *sk, struct open_request *req)
{
struct rtable *rt;
struct ip_options *opt;
- struct sk_buff * skb;
- /* First, grab a route. */
opt = req->af.v4_req.opt;
if(ip_route_output(&rt, ((opt && opt->srr) ?
opt->faddr :
@@ -1300,15 +1176,33 @@ static void tcp_v4_send_synack(struct sock *sk, struct open_request *req)
RT_TOS(sk->protinfo.af_inet.tos) | RTO_CONN | sk->localroute,
sk->bound_dev_if)) {
IP_INC_STATS_BH(IpOutNoRoutes);
- return;
+ return NULL;
}
- if(opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) {
+ if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) {
ip_rt_put(rt);
IP_INC_STATS_BH(IpOutNoRoutes);
- return;
+ return NULL;
}
+ return &rt->u.dst;
+}
+
+/*
+ * Send a SYN-ACK after having received an ACK.
+ * This still operates on a open_request only, not on a big
+ * socket.
+ */
+static int tcp_v4_send_synack(struct sock *sk, struct open_request *req,
+ struct dst_entry *dst)
+{
+ int err = -1;
+ struct sk_buff * skb;
- skb = tcp_make_synack(sk, &rt->u.dst, req);
+ /* First, grab a route. */
+ if (dst == NULL &&
+ (dst = tcp_v4_route_req(sk, req)) == NULL)
+ goto out;
+
+ skb = tcp_make_synack(sk, dst, req);
if (skb) {
struct tcphdr *th = skb->h.th;
@@ -1317,10 +1211,15 @@ static void tcp_v4_send_synack(struct sock *sk, struct open_request *req)
req->af.v4_req.loc_addr, req->af.v4_req.rmt_addr,
csum_partial((char *)th, skb->len, skb->csum));
- ip_build_and_send_pkt(skb, sk, req->af.v4_req.loc_addr,
- req->af.v4_req.rmt_addr, req->af.v4_req.opt);
+ err = ip_build_and_send_pkt(skb, sk, req->af.v4_req.loc_addr,
+ req->af.v4_req.rmt_addr, req->af.v4_req.opt);
+ if (err == NET_XMIT_CN)
+ err = 0;
}
- ip_rt_put(rt);
+
+out:
+ dst_release(dst);
+ return err;
}
/*
@@ -1328,7 +1227,7 @@ static void tcp_v4_send_synack(struct sock *sk, struct open_request *req)
*/
static void tcp_v4_or_free(struct open_request *req)
{
- if(!req->sk && req->af.v4_req.opt)
+ if (req->af.v4_req.opt)
kfree_s(req->af.v4_req.opt, optlength(req->af.v4_req.opt));
}
@@ -1372,8 +1271,14 @@ tcp_v4_save_options(struct sock *sk, struct sk_buff *skb)
* It would be better to replace it with a global counter for all sockets
* but then some measure against one socket starving all other sockets
* would be needed.
+ *
+ * It was 128 by default. Experiments with real servers show, that
+ * it is absolutely not enough even at 100conn/sec. 256 cures most
+ * of problems. This value is adjusted to 128 for very small machines
+ * (<=32Mb of memory) and to 1024 on normal or better ones (>=256Mb).
+ * Further increasing requires to change hash table size.
*/
-int sysctl_max_syn_backlog = 128;
+int sysctl_max_syn_backlog = 256;
struct or_calltable or_ipv4 = {
PF_INET,
@@ -1383,9 +1288,6 @@ struct or_calltable or_ipv4 = {
tcp_v4_send_reset
};
-#define BACKLOG(sk) ((sk)->tp_pinfo.af_tcp.syn_backlog) /* lvalue! */
-#define BACKLOGMAX(sk) sysctl_max_syn_backlog
-
int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
{
struct tcp_opt tp;
@@ -1394,6 +1296,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
__u32 saddr = skb->nh.iph->saddr;
__u32 daddr = skb->nh.iph->daddr;
__u32 isn = TCP_SKB_CB(skb)->when;
+ struct dst_entry *dst = NULL;
#ifdef CONFIG_SYN_COOKIES
int want_cookie = 0;
#else
@@ -1405,84 +1308,108 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
(RTCF_BROADCAST|RTCF_MULTICAST))
goto drop;
- /* XXX: Check against a global syn pool counter. */
- if (BACKLOG(sk) > BACKLOGMAX(sk)) {
+ /* TW buckets are converted to open requests without
+ * limitations, they conserve resources and peer is
+ * evidently real one.
+ */
+ if (tcp_synq_is_full(sk) && !isn) {
#ifdef CONFIG_SYN_COOKIES
- if (sysctl_tcp_syncookies && !isn) {
- syn_flood_warning(skb);
+ if (sysctl_tcp_syncookies) {
want_cookie = 1;
} else
#endif
goto drop;
- } else {
- if (isn == 0)
- isn = tcp_v4_init_sequence(sk, skb);
- BACKLOG(sk)++;
}
- req = tcp_openreq_alloc();
- if (req == NULL) {
- goto dropbacklog;
- }
+ /* Accept backlog is full. If we have already queued enough
+ * of warm entries in syn queue, drop request. It is better than
+ * clogging syn queue with openreqs with exponentially increasing
+ * timeout.
+ */
+ if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
+ goto drop;
- req->rcv_wnd = 0; /* So that tcp_send_synack() knows! */
+ req = tcp_openreq_alloc();
+ if (req == NULL)
+ goto drop;
- req->rcv_isn = TCP_SKB_CB(skb)->seq;
tp.tstamp_ok = tp.sack_ok = tp.wscale_ok = tp.snd_wscale = 0;
-
tp.mss_clamp = 536;
tp.user_mss = sk->tp_pinfo.af_tcp.user_mss;
tcp_parse_options(NULL, th, &tp, want_cookie);
- req->mss = tp.mss_clamp;
- req->ts_recent = tp.saw_tstamp ? tp.rcv_tsval : 0;
- req->tstamp_ok = tp.tstamp_ok;
- req->sack_ok = tp.sack_ok;
- req->snd_wscale = tp.snd_wscale;
- req->wscale_ok = tp.wscale_ok;
- req->rmt_port = th->source;
+ tcp_openreq_init(req, &tp, skb);
+
req->af.v4_req.loc_addr = daddr;
req->af.v4_req.rmt_addr = saddr;
+ req->af.v4_req.opt = tcp_v4_save_options(sk, skb);
+ req->class = &or_ipv4;
- /* Note that we ignore the isn passed from the TIME_WAIT
- * state here. That's the price we pay for cookies.
- *
- * RED-PEN. The price is high... Then we cannot kill TIME-WAIT
- * and should reject connection attempt, duplicates with random
- * sequence number can corrupt data. Right?
- * I disabled sending cookie to request matching to a timewait
- * bucket.
- */
- if (want_cookie)
+ if (want_cookie) {
+#ifdef CONFIG_SYN_COOKIES
+ syn_flood_warning(skb);
+#endif
isn = cookie_v4_init_sequence(sk, skb, &req->mss);
+ } else if (isn == 0) {
+ struct inet_peer *peer = NULL;
- req->snt_isn = isn;
-
- req->af.v4_req.opt = tcp_v4_save_options(sk, skb);
+ /* VJ's idea. We save last timestamp seen
+ * from the destination in peer table, when entering
+ * state TIME-WAIT, and check against it before
+ * accepting new connection request.
+ *
+ * If "isn" is not zero, this request hit alive
+ * timewait bucket, so that all the necessary checks
+ * are made in the function processing timewait state.
+ */
+ if (tp.saw_tstamp &&
+ sysctl_tcp_tw_recycle &&
+ (dst = tcp_v4_route_req(sk, req)) != NULL &&
+ (peer = rt_get_peer((struct rtable*)dst)) != NULL &&
+ peer->v4daddr == saddr) {
+ if (xtime.tv_sec < peer->tcp_ts_stamp + TCP_PAWS_MSL &&
+ (s32)(peer->tcp_ts - req->ts_recent) > TCP_PAWS_WINDOW) {
+ NETDEBUG(printk(KERN_DEBUG "TW_REC: reject openreq %u/%u %08x/%u\n", peer->tcp_ts, req->ts_recent, saddr, ntohs(skb->h.th->source)));
+ NET_INC_STATS_BH(PAWSPassiveRejected);
+ dst_release(dst);
+ goto drop_and_free;
+ }
+ }
+ /* Kill the following clause, if you dislike this way. */
+ else if (!sysctl_tcp_syncookies &&
+ (sysctl_max_syn_backlog - tcp_synq_len(sk)
+ < (sysctl_max_syn_backlog>>2)) &&
+ (!peer || !peer->tcp_ts_stamp) &&
+ (!dst || !dst->rtt)) {
+ /* Without syncookies last quarter of
+ * backlog is filled with destinations, proven to be alive.
+ * It means that we continue to communicate
+ * to destinations, already remembered
+ * to the moment of synflood.
+ */
+ NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "TCP: drop open request from %08x/%u\n", saddr, ntohs(skb->h.th->source)));
+ TCP_INC_STATS_BH(TcpAttemptFails);
+ dst_release(dst);
+ goto drop_and_free;
+ }
- req->class = &or_ipv4;
- req->retrans = 0;
- req->sk = NULL;
+ isn = tcp_v4_init_sequence(sk, skb);
+ }
+ req->snt_isn = isn;
- tcp_v4_send_synack(sk, req);
+ if (tcp_v4_send_synack(sk, req, dst))
+ goto drop_and_free;
if (want_cookie) {
- if (req->af.v4_req.opt)
- kfree(req->af.v4_req.opt);
- tcp_v4_or_free(req);
tcp_openreq_free(req);
} else {
- req->expires = jiffies + TCP_TIMEOUT_INIT;
- tcp_inc_slow_timer(TCP_SLT_SYNACK);
- tcp_synq_queue(&sk->tp_pinfo.af_tcp, req);
+ tcp_v4_synq_add(sk, req);
}
-
return 0;
-dropbacklog:
- if (!want_cookie)
- BACKLOG(sk)--;
+drop_and_free:
+ tcp_openreq_free(req);
drop:
TCP_INC_STATS_BH(TcpAttemptFails);
return 0;
@@ -1497,29 +1424,20 @@ struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
struct open_request *req,
struct dst_entry *dst)
{
- struct ip_options *opt = req->af.v4_req.opt;
struct tcp_opt *newtp;
struct sock *newsk;
- if (sk->ack_backlog > sk->max_ack_backlog)
- goto exit; /* head drop */
- if (dst == NULL) {
- struct rtable *rt;
-
- if (ip_route_output(&rt,
- opt && opt->srr ? opt->faddr : req->af.v4_req.rmt_addr,
- req->af.v4_req.loc_addr, sk->protinfo.af_inet.tos|RTO_CONN, 0))
- return NULL;
- dst = &rt->u.dst;
- }
+ if (tcp_acceptq_is_full(sk))
+ goto exit_overflow;
+
+ if (dst == NULL &&
+ (dst = tcp_v4_route_req(sk, req)) == NULL)
+ goto exit;
newsk = tcp_create_openreq_child(sk, req, skb);
if (!newsk)
goto exit;
- sk->tp_pinfo.af_tcp.syn_backlog--;
- sk->ack_backlog++;
-
newsk->dst_cache = dst;
newtp = &(newsk->tp_pinfo.af_tcp);
@@ -1527,7 +1445,8 @@ struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
newsk->saddr = req->af.v4_req.loc_addr;
newsk->rcv_saddr = req->af.v4_req.loc_addr;
newsk->protinfo.af_inet.opt = req->af.v4_req.opt;
- newsk->protinfo.af_inet.mc_index = ((struct rtable*)skb->dst)->rt_iif;
+ req->af.v4_req.opt = NULL;
+ newsk->protinfo.af_inet.mc_index = tcp_v4_iif(skb);
newsk->protinfo.af_inet.mc_ttl = skb->nh.iph->ttl;
newtp->ext_header_len = 0;
if (newsk->protinfo.af_inet.opt)
@@ -1535,28 +1454,26 @@ struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
tcp_sync_mss(newsk, dst->pmtu);
tcp_initialize_rcv_mss(newsk);
+ newtp->advmss = dst->advmss;
- if (newsk->rcvbuf < (3 * (dst->advmss+40+MAX_HEADER+15)))
- newsk->rcvbuf = min ((3 * (dst->advmss+40+MAX_HEADER+15)), sysctl_rmem_max);
- if (newsk->sndbuf < (3 * (newtp->mss_clamp+40+MAX_HEADER+15)))
- newsk->sndbuf = min ((3 * (newtp->mss_clamp+40+MAX_HEADER+15)), sysctl_wmem_max);
+ tcp_init_buffer_space(newsk);
- bh_lock_sock(newsk);
-
__tcp_v4_hash(newsk);
__tcp_inherit_port(sk, newsk);
return newsk;
+exit_overflow:
+ NET_INC_STATS_BH(ListenOverflows);
exit:
+ NET_INC_STATS_BH(ListenDrops);
dst_release(dst);
return NULL;
}
-
static struct sock *tcp_v4_hnd_req(struct sock *sk,struct sk_buff *skb)
{
- struct open_request *req, *prev;
+ struct open_request *req, **prev;
struct tcphdr *th = skb->h.th;
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
@@ -1565,6 +1482,25 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk,struct sk_buff *skb)
if (req)
return tcp_check_req(sk, skb, req, prev);
+ if (tp->accept_queue) {
+ struct sock *nsk;
+
+ nsk = __tcp_v4_lookup_established(skb->nh.iph->saddr,
+ th->source,
+ skb->nh.iph->daddr,
+ ntohs(th->dest),
+ tcp_v4_iif(skb));
+
+ if (nsk) {
+ if (nsk->state != TCP_TIME_WAIT) {
+ bh_lock_sock(nsk);
+ return nsk;
+ }
+ tcp_tw_put((struct tcp_tw_bucket*)sk);
+ return NULL;
+ }
+ }
+
#ifdef CONFIG_SYN_COOKIES
if (!th->rst && (th->syn || th->ack))
sk = cookie_v4_check(sk, skb, &(IPCB(skb)->opt));
@@ -1572,27 +1508,26 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk,struct sk_buff *skb)
return sk;
}
-static int tcp_csum_verify(struct sk_buff *skb)
+static int tcp_v4_checksum_init(struct sk_buff *skb)
{
- switch (skb->ip_summed) {
- case CHECKSUM_NONE:
- skb->csum = csum_partial((char *)skb->h.th, skb->len, 0);
- case CHECKSUM_HW:
- if (tcp_v4_check(skb->h.th,skb->len,skb->nh.iph->saddr,skb->nh.iph->daddr,skb->csum)) {
- NETDEBUG(printk(KERN_DEBUG "TCPv4 bad checksum "
- "from %d.%d.%d.%d:%04x to %d.%d.%d.%d:%04x, "
- "len=%d/%d\n",
- NIPQUAD(skb->nh.iph->saddr),
- ntohs(skb->h.th->source),
- NIPQUAD(skb->nh.iph->daddr),
- ntohs(skb->h.th->dest),
- skb->len,
- ntohs(skb->nh.iph->tot_len)));
- return 1;
+ if (skb->ip_summed == CHECKSUM_HW) {
+ if (tcp_v4_check(skb->h.th,skb->len,skb->nh.iph->saddr,
+ skb->nh.iph->daddr,skb->csum)) {
+ NETDEBUG(printk(KERN_DEBUG "hw tcp v4 csum failed\n"));
+ return -1;
}
skb->ip_summed = CHECKSUM_UNNECESSARY;
- default:
- /* CHECKSUM_UNNECESSARY */
+ } else if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
+ if (skb->len <= 68) {
+ if (tcp_v4_check(skb->h.th,skb->len,skb->nh.iph->saddr,
+ skb->nh.iph->daddr,
+ csum_partial((char *)skb->h.th, skb->len, 0)))
+ return -1;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else {
+ skb->csum = ~tcp_v4_check(skb->h.th,skb->len,skb->nh.iph->saddr,
+ skb->nh.iph->daddr,0);
+ }
}
return 0;
}
@@ -1614,66 +1549,35 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
goto discard;
#endif /* CONFIG_FILTER */
- /*
- * This doesn't check if the socket has enough room for the packet.
- * Either process the packet _without_ queueing it and then free it,
- * or do the check later.
- */
- skb_set_owner_r(skb, sk);
+ IP_INC_STATS_BH(IpInDelivers);
if (sk->state == TCP_ESTABLISHED) { /* Fast path */
- /* Ready to move deeper ... */
- if (tcp_csum_verify(skb))
- goto csum_err;
+ TCP_CHECK_TIMER(sk);
if (tcp_rcv_established(sk, skb, skb->h.th, skb->len))
goto reset;
+ TCP_CHECK_TIMER(sk);
return 0;
- }
+ }
- if (tcp_csum_verify(skb))
+ if (tcp_checksum_complete(skb))
goto csum_err;
if (sk->state == TCP_LISTEN) {
- struct sock *nsk;
-
- nsk = tcp_v4_hnd_req(sk, skb);
+ struct sock *nsk = tcp_v4_hnd_req(sk, skb);
if (!nsk)
goto discard;
- /*
- * Queue it on the new socket if the new socket is active,
- * otherwise we just shortcircuit this and continue with
- * the new socket..
- */
if (nsk != sk) {
- int ret;
- int state = nsk->state;
-
- skb_orphan(skb);
-
- BUG_TRAP(nsk->lock.users == 0);
- skb_set_owner_r(skb, nsk);
- ret = tcp_rcv_state_process(nsk, skb, skb->h.th, skb->len);
-
- /* Wakeup parent, send SIGIO, if this packet changed
- socket state from SYN-RECV.
-
- It still looks ugly, however it is much better
- than miracleous double wakeup in syn_recv_sock()
- and tcp_rcv_state_process().
- */
- if (state == TCP_SYN_RECV && nsk->state != state)
- sk->data_ready(sk, 0);
-
- bh_unlock_sock(nsk);
- if (ret)
+ if (tcp_child_process(sk, nsk, skb))
goto reset;
return 0;
}
}
-
+
+ TCP_CHECK_TIMER(sk);
if (tcp_rcv_state_process(sk, skb, skb->h.th, skb->len))
goto reset;
+ TCP_CHECK_TIMER(sk);
return 0;
reset:
@@ -1716,6 +1620,9 @@ int tcp_v4_rcv(struct sk_buff *skb, unsigned short len)
if (len < sizeof(struct tcphdr))
goto bad_packet;
+ if (tcp_v4_checksum_init(skb) < 0)
+ goto bad_packet;
+
TCP_SKB_CB(skb)->seq = ntohl(th->seq);
TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
len - th->doff*4);
@@ -1724,7 +1631,7 @@ int tcp_v4_rcv(struct sk_buff *skb, unsigned short len)
skb->used = 0;
sk = __tcp_v4_lookup(skb->nh.iph->saddr, th->source,
- skb->nh.iph->daddr, ntohs(th->dest), skb->dev->ifindex);
+ skb->nh.iph->daddr, ntohs(th->dest), tcp_v4_iif(skb));
if (!sk)
goto no_tcp_socket;
@@ -1738,9 +1645,10 @@ process:
bh_lock_sock(sk);
ret = 0;
- if (!sk->lock.users)
- ret = tcp_v4_do_rcv(sk, skb);
- else
+ if (!sk->lock.users) {
+ if (!tcp_prequeue(sk, skb))
+ ret = tcp_v4_do_rcv(sk, skb);
+ } else
sk_add_backlog(sk, skb);
bh_unlock_sock(sk);
@@ -1749,7 +1657,7 @@ process:
return ret;
no_tcp_socket:
- if (tcp_csum_verify(skb)) {
+ if (tcp_checksum_complete(skb)) {
bad_packet:
TCP_INC_STATS_BH(TcpInErrs);
} else {
@@ -1766,7 +1674,7 @@ discard_and_relse:
goto discard_it;
do_time_wait:
- if (tcp_csum_verify(skb)) {
+ if (tcp_checksum_complete(skb)) {
TCP_INC_STATS_BH(TcpInErrs);
goto discard_and_relse;
}
@@ -1776,7 +1684,7 @@ do_time_wait:
{
struct sock *sk2;
- sk2 = tcp_v4_lookup_listener(skb->nh.iph->daddr, ntohs(th->dest), skb->dev->ifindex);
+ sk2 = tcp_v4_lookup_listener(skb->nh.iph->daddr, ntohs(th->dest), tcp_v4_iif(skb));
if (sk2 != NULL) {
tcp_tw_deschedule((struct tcp_tw_bucket *)sk);
tcp_timewait_kill((struct tcp_tw_bucket *)sk);
@@ -1796,36 +1704,39 @@ do_time_wait:
goto discard_it;
}
+/* With per-bucket locks this operation is not-atomic, so that
+ * this version is not worse.
+ */
static void __tcp_v4_rehash(struct sock *sk)
{
- struct tcp_ehash_bucket *oldhead = &tcp_ehash[sk->hashent];
- struct tcp_ehash_bucket *head = &tcp_ehash[(sk->hashent = tcp_sk_hashfn(sk))];
- struct sock **skp = &head->chain;
-
- write_lock_bh(&oldhead->lock);
- if(sk->pprev) {
- if(sk->next)
- sk->next->pprev = sk->pprev;
- *sk->pprev = sk->next;
- sk->pprev = NULL;
- }
- write_unlock(&oldhead->lock);
- write_lock(&head->lock);
- if((sk->next = *skp) != NULL)
- (*skp)->pprev = &sk->next;
- *skp = sk;
- sk->pprev = skp;
- write_unlock_bh(&head->lock);
+ sk->prot->unhash(sk);
+ sk->prot->hash(sk);
}
int tcp_v4_rebuild_header(struct sock *sk)
{
- struct rtable *rt = (struct rtable *)__sk_dst_get(sk);
+ struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0);
__u32 new_saddr;
int want_rewrite = sysctl_ip_dynaddr && sk->state == TCP_SYN_SENT;
- if(rt == NULL)
- return 0;
+ if (rt == NULL) {
+ int err;
+
+ u32 daddr = sk->daddr;
+
+ if(sk->protinfo.af_inet.opt && sk->protinfo.af_inet.opt->srr)
+ daddr = sk->protinfo.af_inet.opt->faddr;
+
+ err = ip_route_output(&rt, daddr, sk->saddr,
+ RT_TOS(sk->protinfo.af_inet.tos) | RTO_CONN | sk->localroute,
+ sk->bound_dev_if);
+ if (err) {
+ sk->err_soft=-err;
+ sk->error_report(sk);
+ return -1;
+ }
+ __sk_dst_set(sk, &rt->u.dst);
+ }
/* Force route checking if want_rewrite.
* The idea is good, the implementation is disguisting.
@@ -1855,16 +1766,6 @@ int tcp_v4_rebuild_header(struct sock *sk)
dst_release(&new_rt->u.dst);
}
}
- if (rt->u.dst.obsolete) {
- int err;
- err = ip_route_output(&rt, rt->rt_dst, rt->rt_src, rt->key.tos|RTO_CONN, rt->key.oif);
- if (err) {
- sk->err_soft=-err;
- sk->error_report(sk);
- return -1;
- }
- __sk_dst_set(sk, &rt->u.dst);
- }
return 0;
@@ -1877,7 +1778,7 @@ do_rewrite:
"saddr=%08X rcv_saddr=%08X\n",
ntohl(sk->saddr),
ntohl(sk->rcv_saddr));
- return 0;
+ return -1;
}
if (new_saddr != sk->saddr) {
@@ -1895,7 +1796,7 @@ do_rewrite:
* XXX really change the sockets identity after
* XXX it has entered the hashes. -DaveM
*
- * Besides that, it does not check for connetion
+ * Besides that, it does not check for connection
* uniqueness. Wait for troubles.
*/
__tcp_v4_rehash(sk);
@@ -1913,6 +1814,63 @@ static void v4_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
sin->sin_port = sk->dport;
}
+/* VJ's idea. Save last timestamp seen from this destination
+ * and hold it at least for normal timewait interval to use for duplicate
+ * segment detection in subsequent connections, before they enter synchronized
+ * state.
+ */
+
+int tcp_v4_remember_stamp(struct sock *sk)
+{
+ struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
+ struct rtable *rt = (struct rtable*)__sk_dst_get(sk);
+ struct inet_peer *peer = NULL;
+ int release_it = 0;
+
+ if (rt == NULL || rt->rt_dst != sk->daddr) {
+ peer = inet_getpeer(sk->daddr, 1);
+ release_it = 1;
+ } else {
+ if (rt->peer == NULL)
+ rt_bind_peer(rt, 1);
+ peer = rt->peer;
+ }
+
+ if (peer) {
+ if ((s32)(peer->tcp_ts - tp->ts_recent) <= 0 ||
+ (peer->tcp_ts_stamp + TCP_PAWS_MSL < xtime.tv_sec &&
+ peer->tcp_ts_stamp <= tp->ts_recent_stamp)) {
+ peer->tcp_ts_stamp = tp->ts_recent_stamp;
+ peer->tcp_ts = tp->ts_recent;
+ }
+ if (release_it)
+ inet_putpeer(peer);
+ return 1;
+ }
+
+ return 0;
+}
+
+int tcp_v4_tw_remember_stamp(struct tcp_tw_bucket *tw)
+{
+ struct inet_peer *peer = NULL;
+
+ peer = inet_getpeer(tw->daddr, 1);
+
+ if (peer) {
+ if ((s32)(peer->tcp_ts - tw->ts_recent) <= 0 ||
+ (peer->tcp_ts_stamp + TCP_PAWS_MSL < xtime.tv_sec &&
+ peer->tcp_ts_stamp <= tw->ts_recent_stamp)) {
+ peer->tcp_ts_stamp = tw->ts_recent_stamp;
+ peer->tcp_ts = tw->ts_recent;
+ }
+ inet_putpeer(peer);
+ return 1;
+ }
+
+ return 0;
+}
+
struct tcp_func ipv4_specific = {
ip_queue_xmit,
tcp_v4_send_check,
@@ -1920,6 +1878,7 @@ struct tcp_func ipv4_specific = {
tcp_v4_conn_request,
tcp_v4_syn_recv_sock,
tcp_v4_hash_connecting,
+ tcp_v4_remember_stamp,
sizeof(struct iphdr),
ip_setsockopt,
@@ -1937,6 +1896,7 @@ static int tcp_v4_init_sock(struct sock *sk)
skb_queue_head_init(&tp->out_of_order_queue);
tcp_init_xmit_timers(sk);
+ tcp_prequeue_init(tp);
tp->rto = TCP_TIMEOUT_INIT;
tp->mdev = TCP_TIMEOUT_INIT;
@@ -1951,19 +1911,14 @@ static int tcp_v4_init_sock(struct sock *sk)
/* See draft-stevens-tcpca-spec-01 for discussion of the
* initialization of these values.
*/
- tp->snd_cwnd_cnt = 0;
tp->snd_ssthresh = 0x7fffffff; /* Infinity */
tp->snd_cwnd_clamp = ~0;
tp->mss_cache = 536;
sk->state = TCP_CLOSE;
- sk->max_ack_backlog = SOMAXCONN;
sk->write_space = tcp_write_space;
- /* Init SYN queue. */
- tcp_synq_init(tp);
-
sk->tp_pinfo.af_tcp.af_specific = &ipv4_specific;
return 0;
@@ -1981,9 +1936,10 @@ static int tcp_v4_destroy_sock(struct sock *sk)
/* Cleans up our, hopefuly empty, out_of_order_queue. */
__skb_queue_purge(&tp->out_of_order_queue);
- /* Clean up a referenced TCP bind bucket, this only happens if a
- * port is allocated for a socket, but it never fully connects.
- */
+ /* Clean prequeue, it must be empty really */
+ __skb_queue_purge(&tp->ucopy.prequeue);
+
+ /* Clean up a referenced TCP bind bucket. */
if(sk->prev != NULL)
tcp_put_port(sk);
@@ -1993,17 +1949,19 @@ static int tcp_v4_destroy_sock(struct sock *sk)
/* Proc filesystem TCP sock list dumping. */
static void get_openreq(struct sock *sk, struct open_request *req, char *tmpbuf, int i)
{
- sprintf(tmpbuf, "%4d: %08lX:%04X %08lX:%04X"
- " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p",
+ int ttd = req->expires - jiffies;
+
+ sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
+ " %02X %08X:%08X %02X:%08X %08X %5d %8d %u %d %p",
i,
- (long unsigned int)req->af.v4_req.loc_addr,
+ req->af.v4_req.loc_addr,
ntohs(sk->sport),
- (long unsigned int)req->af.v4_req.rmt_addr,
+ req->af.v4_req.rmt_addr,
ntohs(req->rmt_port),
TCP_SYN_RECV,
0,0, /* could print option size, but that is af dependent. */
1, /* timers active (only the expire timer) */
- (unsigned long)(req->expires - jiffies),
+ ttd,
req->retrans,
sk->socket ? sk->socket->inode->i_uid : 0,
0, /* non standard timer */
@@ -2017,7 +1975,7 @@ static void get_tcp_sock(struct sock *sp, char *tmpbuf, int i)
{
unsigned int dest, src;
__u16 destp, srcp;
- int timer_active, timer_active1, timer_active2;
+ int timer_active;
unsigned long timer_expires;
struct tcp_opt *tp = &sp->tp_pinfo.af_tcp;
@@ -2025,15 +1983,16 @@ static void get_tcp_sock(struct sock *sp, char *tmpbuf, int i)
src = sp->rcv_saddr;
destp = ntohs(sp->dport);
srcp = ntohs(sp->sport);
- timer_active1 = tp->retransmit_timer.prev != NULL;
- timer_active2 = sp->timer.prev != NULL;
timer_active = 0;
timer_expires = (unsigned) -1;
- if (timer_active1 && tp->retransmit_timer.expires < timer_expires) {
+ if (tp->retransmit_timer.prev != NULL && tp->retransmit_timer.expires < timer_expires) {
timer_active = 1;
timer_expires = tp->retransmit_timer.expires;
+ } else if (tp->probe_timer.prev != NULL && tp->probe_timer.expires < timer_expires) {
+ timer_active = 4;
+ timer_expires = tp->probe_timer.expires;
}
- if (timer_active2 && sp->timer.expires < timer_expires) {
+ if (sp->timer.prev != NULL && sp->timer.expires < timer_expires) {
timer_active = 2;
timer_expires = sp->timer.expires;
}
@@ -2041,38 +2000,37 @@ static void get_tcp_sock(struct sock *sp, char *tmpbuf, int i)
timer_expires = jiffies;
sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
- " %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p",
+ " %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p %u %u %u %u",
i, src, srcp, dest, destp, sp->state,
tp->write_seq-tp->snd_una, tp->rcv_nxt-tp->copied_seq,
timer_active, timer_expires-jiffies,
tp->retransmits,
sp->socket ? sp->socket->inode->i_uid : 0,
- 0,
+ tp->probes_out,
sp->socket ? sp->socket->inode->i_ino : 0,
- atomic_read(&sp->refcnt), sp);
+ atomic_read(&sp->refcnt), sp,
+ tp->rto, tp->ack.ato, tp->ack.quick, tp->ack.pingpong
+ );
}
static void get_timewait_sock(struct tcp_tw_bucket *tw, char *tmpbuf, int i)
{
unsigned int dest, src;
__u16 destp, srcp;
- int slot_dist;
+ int ttd = tw->ttd - jiffies;
+
+ if (ttd < 0)
+ ttd = 0;
dest = tw->daddr;
src = tw->rcv_saddr;
destp = ntohs(tw->dport);
srcp = ntohs(tw->sport);
- slot_dist = tw->death_slot;
- if(slot_dist > tcp_tw_death_row_slot)
- slot_dist = (TCP_TWKILL_SLOTS - slot_dist) + tcp_tw_death_row_slot;
- else
- slot_dist = tcp_tw_death_row_slot - slot_dist;
-
sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
" %02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p",
- i, src, srcp, dest, destp, TCP_TIME_WAIT, 0, 0,
- 3, slot_dist * TCP_TWKILL_PERIOD, 0, 0, 0, 0,
+ i, src, srcp, dest, destp, tw->substate, 0, 0,
+ 3, ttd, 0, 0, 0, 0,
atomic_read(&tw->refcnt), tw);
}
@@ -2093,6 +2051,8 @@ int tcp_get_info(char *buffer, char **start, off_t offset, int length)
tcp_listen_lock();
for(i = 0; i < TCP_LHTABLE_SIZE; i++) {
struct sock *sk = tcp_listening_hash[i];
+ struct tcp_listen_opt *lopt;
+ int k;
for (sk = tcp_listening_hash[i]; sk; sk = sk->next, num++) {
struct open_request *req;
@@ -2112,25 +2072,30 @@ int tcp_get_info(char *buffer, char **start, off_t offset, int length)
}
skip_listen:
- lock_sock(sk);
- for (req = tp->syn_wait_queue; req; req = req->dl_next, num++) {
- if (req->sk)
- continue;
- if (!TCP_INET_FAMILY(req->class->family))
- continue;
-
- pos += 128;
- if (pos < offset)
- continue;
- get_openreq(sk, req, tmpbuf, num);
- len += sprintf(buffer+len, "%-127s\n", tmpbuf);
- if(len >= length) {
- tcp_listen_unlock();
- release_sock(sk);
- goto out_no_bh;
+ read_lock_bh(&tp->syn_wait_lock);
+ lopt = tp->listen_opt;
+ if (lopt && lopt->qlen != 0) {
+ for (k=0; k<TCP_SYNQ_HSIZE; k++) {
+ for (req = lopt->syn_table[k]; req; req = req->dl_next, num++) {
+ if (!TCP_INET_FAMILY(req->class->family))
+ continue;
+
+ pos += 128;
+ if (pos < offset)
+ continue;
+ get_openreq(sk, req, tmpbuf, num);
+ len += sprintf(buffer+len, "%-127s\n", tmpbuf);
+ if(len >= length) {
+ read_unlock_bh(&tp->syn_wait_lock);
+ tcp_listen_unlock();
+ goto out_no_bh;
+ }
+ }
}
}
- release_sock(sk);
+ read_unlock_bh(&tp->syn_wait_lock);
+
+ /* Completed requests are in normal socket hash table */
}
}
tcp_listen_unlock();
@@ -2194,28 +2159,24 @@ struct proto tcp_prot = {
tcp_v4_connect, /* connect */
tcp_disconnect, /* disconnect */
tcp_accept, /* accept */
- NULL, /* retransmit */
- tcp_write_wakeup, /* write_wakeup */
- tcp_read_wakeup, /* read_wakeup */
- tcp_poll, /* poll */
tcp_ioctl, /* ioctl */
tcp_v4_init_sock, /* init */
tcp_v4_destroy_sock, /* destroy */
tcp_shutdown, /* shutdown */
tcp_setsockopt, /* setsockopt */
tcp_getsockopt, /* getsockopt */
- tcp_v4_sendmsg, /* sendmsg */
+ tcp_sendmsg, /* sendmsg */
tcp_recvmsg, /* recvmsg */
NULL, /* bind */
tcp_v4_do_rcv, /* backlog_rcv */
tcp_v4_hash, /* hash */
tcp_unhash, /* unhash */
tcp_v4_get_port, /* get_port */
- 128, /* max_header */
- 0, /* retransmits */
"TCP", /* name */
};
+
+
void __init tcp_v4_init(struct net_proto_family *ops)
{
int err;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index e3d884dda..d6bc8a205 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_output.c,v 1.116 2000/01/13 00:19:49 davem Exp $
+ * Version: $Id: tcp_output.c,v 1.119 2000/01/19 04:06:15 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -31,6 +31,7 @@
* during syn/ack processing.
* David S. Miller : Output engine completely rewritten.
* Andrea Arcangeli: SYNACK carry ts_recent in tsecr.
+ * Cacophonix Gaul : draft-minshall-nagle-01
*
*/
@@ -38,75 +39,65 @@
#include <linux/smp_lock.h>
-extern int sysctl_tcp_timestamps;
-extern int sysctl_tcp_window_scaling;
-extern int sysctl_tcp_sack;
-
/* People can turn this off for buggy TCP's found in printers etc. */
int sysctl_tcp_retrans_collapse = 1;
-/* Get rid of any delayed acks, we sent one already.. */
-static __inline__ void clear_delayed_acks(struct sock * sk)
-{
- struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-
- tp->delayed_acks = 0;
- if(tcp_in_quickack_mode(tp))
- tcp_exit_quickack_mode(tp);
- tcp_clear_xmit_timer(sk, TIME_DACK);
-}
-
static __inline__ void update_send_head(struct sock *sk)
{
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-
+
tp->send_head = tp->send_head->next;
if (tp->send_head == (struct sk_buff *) &sk->write_queue)
tp->send_head = NULL;
}
/* Calculate mss to advertise in SYN segment.
- RFC1122, RFC1063, draft-ietf-tcpimpl-pmtud-01 state that:
-
- 1. It is independent of path mtu.
- 2. Ideally, it is maximal possible segment size i.e. 65535-40.
- 3. For IPv4 it is reasonable to calculate it from maximal MTU of
- attached devices, because some buggy hosts are confused by
- large MSS.
- 4. We do not make 3, we advertise MSS, calculated from first
- hop device mtu, but allow to raise it to ip_rt_min_advmss.
- This may be overriden via information stored in routing table.
- 5. Value 65535 for MSS is valid in IPv6 and means "as large as possible,
- probably even Jumbo".
+ * RFC1122, RFC1063, draft-ietf-tcpimpl-pmtud-01 state that:
+ *
+ * 1. It is independent of path mtu.
+ * 2. Ideally, it is maximal possible segment size i.e. 65535-40.
+ * 3. For IPv4 it is reasonable to calculate it from maximal MTU of
+ * attached devices, because some buggy hosts are confused by
+ * large MSS.
+ * 4. We do not make 3, we advertise MSS, calculated from first
+ * hop device mtu, but allow to raise it to ip_rt_min_advmss.
+ * This may be overriden via information stored in routing table.
+ * 5. Value 65535 for MSS is valid in IPv6 and means "as large as possible,
+ * probably even Jumbo".
*/
static __u16 tcp_advertise_mss(struct sock *sk)
{
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
struct dst_entry *dst = __sk_dst_get(sk);
- int mss;
+ int mss = tp->advmss;
- if (dst) {
+ if (dst && dst->advmss < mss) {
mss = dst->advmss;
- } else {
- struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ tp->advmss = mss;
+ }
- /* No dst. It is bad. Guess some reasonable value.
- * Actually, this case should not be possible.
- * SANITY.
- */
- BUG_TRAP(dst!=NULL);
+ return (__u16)mss;
+}
- mss = tp->mss_cache;
- mss += (tp->tcp_header_len - sizeof(struct tcphdr)) +
- tp->ext_header_len;
+static __inline__ void tcp_event_data_sent(struct tcp_opt *tp, struct sk_buff *skb)
+{
+ /* If we had a reply for ato after last received
+ * packet, enter pingpong mode.
+ */
+ if ((u32)(tp->lsndtime - tp->ack.lrcvtime) < tp->ack.ato)
+ tp->ack.pingpong = 1;
- /* Minimal MSS to include full set of of TCP/IP options
- plus 8 bytes of data. It corresponds to mtu 128.
- */
- if (mss < 88)
- mss = 88;
- }
+ tp->lsndtime = tcp_time_stamp;
+}
- return (__u16)mss;
+static __inline__ void tcp_event_ack_sent(struct sock *sk)
+{
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+
+ tp->last_ack_sent = tp->rcv_nxt;
+ tcp_dec_quickack_mode(tp);
+ tp->ack.pending = 0;
+ tcp_clear_xmit_timer(sk, TCP_TIME_DACK);
}
/* This routine actually transmits TCP packets queued in by
@@ -120,7 +111,7 @@ static __u16 tcp_advertise_mss(struct sock *sk)
* We are working here with either a clone of the original
* SKB, or a fresh unique copy made by the retransmit engine.
*/
-void tcp_transmit_skb(struct sock *sk, struct sk_buff *skb)
+int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb)
{
if(skb != NULL) {
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
@@ -128,6 +119,7 @@ void tcp_transmit_skb(struct sock *sk, struct sk_buff *skb)
int tcp_header_size = tp->tcp_header_len;
struct tcphdr *th;
int sysctl_flags;
+ int err;
#define SYSCTL_FLAG_TSTAMPS 0x1
#define SYSCTL_FLAG_WSCALE 0x2
@@ -190,11 +182,29 @@ void tcp_transmit_skb(struct sock *sk, struct sk_buff *skb)
}
tp->af_specific->send_check(sk, th, skb->len, skb);
- clear_delayed_acks(sk);
- tp->last_ack_sent = tp->rcv_nxt;
+ if (th->ack)
+ tcp_event_ack_sent(sk);
+
+ if (skb->len != tcp_header_size)
+ tcp_event_data_sent(tp, skb);
+
TCP_INC_STATS(TcpOutSegs);
- tp->af_specific->queue_xmit(skb);
+
+ err = tp->af_specific->queue_xmit(skb);
+ if (err <= 0)
+ return err;
+
+ tcp_enter_cong_avoid(tp);
+
+ /* NET_XMIT_CN is special. It does not guarantee,
+ * that this packet is lost. It tells that device
+ * is about to start to drop packets or already
+ * drops some packets of the same priority and
+ * invokes us to send less aggressively.
+ */
+ return err == NET_XMIT_CN ? 0 : err;
}
+ return -ENOBUFS;
#undef SYSCTL_FLAG_TSTAMPS
#undef SYSCTL_FLAG_WSCALE
#undef SYSCTL_FLAG_SACK
@@ -202,32 +212,33 @@ void tcp_transmit_skb(struct sock *sk, struct sk_buff *skb)
/* This is the main buffer sending routine. We queue the buffer
* and decide whether to queue or transmit now.
+ *
+ * NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames,
+ * otherwise socket can stall.
*/
-void tcp_send_skb(struct sock *sk, struct sk_buff *skb, int force_queue)
+void tcp_send_skb(struct sock *sk, struct sk_buff *skb, int force_queue, unsigned cur_mss)
{
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
/* Advance write_seq and place onto the write_queue. */
- tp->write_seq += (TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq);
+ tp->write_seq = TCP_SKB_CB(skb)->end_seq;
__skb_queue_tail(&sk->write_queue, skb);
- if (!force_queue && tp->send_head == NULL && tcp_snd_test(sk, skb)) {
+ if (!force_queue && tp->send_head == NULL && tcp_snd_test(tp, skb, cur_mss, 1)) {
/* Send it out now. */
TCP_SKB_CB(skb)->when = tcp_time_stamp;
- tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
- tp->packets_out++;
- tcp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL));
- if(!tcp_timer_is_set(sk, TIME_RETRANS))
- tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
- } else {
- /* Queue it, remembering where we must start sending. */
- if (tp->send_head == NULL)
- tp->send_head = skb;
- if (!force_queue && tp->packets_out == 0 && !tp->pending) {
- tp->pending = TIME_PROBE0;
- tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto);
+ if (tcp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL)) == 0) {
+ tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
+ tcp_minshall_update(tp, cur_mss, skb->len);
+ tp->packets_out++;
+ if(!tcp_timer_is_set(sk, TCP_TIME_RETRANS))
+ tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
+ return;
}
}
+ /* Queue it, remembering where we must start sending. */
+ if (tp->send_head == NULL)
+ tp->send_head = skb;
}
/* Function to create two new TCP segments. Shrinks the given segment
@@ -243,13 +254,13 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len)
/* Get a new skb... force flag on. */
buff = sock_wmalloc(sk,
- (nsize + MAX_HEADER + sk->prot->max_header),
+ (nsize + MAX_TCP_HEADER + 15),
1, GFP_ATOMIC);
if (buff == NULL)
- return -1; /* We'll just try again later. */
+ return -ENOMEM; /* We'll just try again later. */
/* Reserve space for headers. */
- skb_reserve(buff, MAX_HEADER + sk->prot->max_header);
+ skb_reserve(buff, MAX_TCP_HEADER);
/* Correct the sequence numbers. */
TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len;
@@ -276,8 +287,8 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len)
TCP_SKB_CB(buff)->sacked = 0;
/* Copy and checksum data tail into the new buffer. */
- buff->csum = csum_partial_copy(skb->data + len, skb_put(buff, nsize),
- nsize, 0);
+ buff->csum = csum_partial_copy_nocheck(skb->data + len, skb_put(buff, nsize),
+ nsize, 0);
/* This takes care of the FIN sequence number too. */
TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq;
@@ -288,6 +299,11 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len)
/* Looks stupid, but our code really uses when of
* skbs, which it never sent before. --ANK
+ *
+ * NOTE: several days after I added this, Dave repaired
+ * tcp_simple_retransmit() and it should not use ->when
+ * of never sent skbs more. I am not sure, so that
+ * this line remains until more careful investigation. --ANK
*/
TCP_SKB_CB(buff)->when = TCP_SKB_CB(skb)->when;
@@ -335,20 +351,19 @@ int tcp_sync_mss(struct sock *sk, u32 pmtu)
if (mss_now > tp->mss_clamp)
mss_now = tp->mss_clamp;
- /* Now subtract TCP options size, not including SACKs */
- mss_now -= tp->tcp_header_len - sizeof(struct tcphdr);
-
/* Now subtract optional transport overhead */
mss_now -= tp->ext_header_len;
- /* It we got too small (or even negative) value,
- clamp it by 8 from below. Why 8 ?
- Well, it could be 1 with the same success,
- but if IP accepted segment of length 1,
- it would love 8 even more 8) --ANK (980731)
- */
- if (mss_now < 8)
- mss_now = 8;
+ /* Then reserve room for full set of TCP options and 8 bytes of data */
+ if (mss_now < 48)
+ mss_now = 48;
+
+ /* Now subtract TCP options size, not including SACKs */
+ mss_now -= tp->tcp_header_len - sizeof(struct tcphdr);
+
+ /* Bound mss with half of window */
+ if (tp->max_window && mss_now > (tp->max_window>>1))
+ mss_now = max((tp->max_window>>1), 1);
/* And store cached results */
tp->pmtu_cookie = pmtu;
@@ -360,27 +375,30 @@ int tcp_sync_mss(struct sock *sk, u32 pmtu)
/* This routine writes packets to the network. It advances the
* send_head. This happens as incoming acks open up the remote
* window for us.
+ *
+ * Returns 1, if no segments are in flight and we have queued segments, but
+ * cannot send anything now because of SWS or another problem.
*/
-void tcp_write_xmit(struct sock *sk)
+int tcp_write_xmit(struct sock *sk)
{
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
unsigned int mss_now;
- /* Account for SACKS, we may need to fragment due to this.
- * It is just like the real MSS changing on us midstream.
- * We also handle things correctly when the user adds some
- * IP options mid-stream. Silly to do, but cover it.
- */
- mss_now = tcp_current_mss(sk);
-
- /* If we are zapped, the bytes will have to remain here.
- * In time closedown will empty the write queue and all
+ /* If we are closed, the bytes will have to remain here.
+ * In time closedown will finish, we empty the write queue and all
* will be happy.
*/
- if(!sk->zapped) {
+ if(sk->state != TCP_CLOSE) {
struct sk_buff *skb;
int sent_pkts = 0;
+ /* Account for SACKS, we may need to fragment due to this.
+ * It is just like the real MSS changing on us midstream.
+ * We also handle things correctly when the user adds some
+ * IP options mid-stream. Silly to do, but cover it.
+ */
+ mss_now = tcp_current_mss(sk);
+
/* Anything on the transmit queue that fits the window can
* be added providing we are:
*
@@ -388,27 +406,36 @@ void tcp_write_xmit(struct sock *sk)
* b) not exceeding our congestion window.
* c) not retransmitting [Nagle]
*/
- while((skb = tp->send_head) && tcp_snd_test(sk, skb)) {
+ while((skb = tp->send_head) &&
+ tcp_snd_test(tp, skb, mss_now, tcp_skb_is_last(sk, skb))) {
if (skb->len > mss_now) {
if (tcp_fragment(sk, skb, mss_now))
break;
}
- /* Advance the send_head. This one is going out. */
- update_send_head(sk);
TCP_SKB_CB(skb)->when = tcp_time_stamp;
+ if (tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)))
+ break;
+ /* Advance the send_head. This one is sent out. */
+ update_send_head(sk);
tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
+ tcp_minshall_update(tp, mss_now, skb->len);
tp->packets_out++;
- tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
sent_pkts = 1;
}
/* If we sent anything, make sure the retransmit
* timer is active.
*/
- if (sent_pkts && !tcp_timer_is_set(sk, TIME_RETRANS))
- tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
+ if (sent_pkts) {
+ if (!tcp_timer_is_set(sk, TCP_TIME_RETRANS))
+ tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
+ return 0;
+ }
+
+ return !tp->packets_out && tp->send_head;
}
+ return 0;
}
/* This function returns the amount that we can raise the
@@ -471,7 +498,7 @@ u32 __tcp_select_window(struct sock *sk)
* but may be worse for the performance because of rcv_mss
* fluctuations. --SAW 1998/11/1
*/
- unsigned int mss = tp->rcv_mss;
+ unsigned int mss = tp->ack.rcv_mss;
int free_space;
u32 window;
@@ -481,11 +508,19 @@ u32 __tcp_select_window(struct sock *sk)
free_space = tp->window_clamp;
if (tp->window_clamp < mss)
mss = tp->window_clamp;
-
- if ((free_space < (tcp_full_space(sk) / 2)) &&
+
+ if ((free_space < (min((int)tp->window_clamp, tcp_full_space(sk)) / 2)) &&
(free_space < ((int) (mss/2)))) {
window = 0;
- tp->pred_flags = 0;
+
+ /* THIS IS _VERY_ GOOD PLACE to play window clamp.
+ * if free_space becomes suspiciously low
+ * verify ratio rmem_alloc/(rcv_nxt - copied_seq),
+ * and if we predict that when free_space will be lower mss,
+ * rmem_alloc will run out of rcvbuf*2, shrink window_clamp.
+ * It will eliminate most of prune events! Very simple,
+ * it is the next thing to do. --ANK
+ */
} else {
/* Get the largest window that is a nice multiple of mss.
* Window clamp already applied above.
@@ -542,9 +577,9 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m
/* Optimize, actually we could also combine next_skb->csum
* to skb->csum using a single add w/carry operation too.
*/
- skb->csum = csum_partial_copy(next_skb->data,
- skb_put(skb, next_skb_size),
- next_skb_size, skb->csum);
+ skb->csum = csum_partial_copy_nocheck(next_skb->data,
+ skb_put(skb, next_skb_size),
+ next_skb_size, skb->csum);
}
/* Update sequence range on original skb. */
@@ -603,8 +638,10 @@ void tcp_simple_retransmit(struct sock *sk)
if (old_next_skb != skb || skb->len > mss)
resend_skb = 1;
old_next_skb = skb->next;
- if (resend_skb != 0)
- tcp_retransmit_skb(sk, skb);
+ if (resend_skb != 0) {
+ if (tcp_retransmit_skb(sk, skb))
+ break;
+ }
}
}
@@ -629,9 +666,21 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
unsigned int cur_mss = tcp_current_mss(sk);
+#ifdef TCP_DEBUG
+ /* It was possible this summer, that retransmit timer
+ * raced with its deletion and hit socket with packets_out==0.
+ * I fixed it, but preserved the check in the place,
+ * where the fault occured. --ANK
+ */
+ if (skb == NULL) {
+ printk("tcp_retransmit_skb: bug, skb==NULL, caller=%p\n", NET_CALLER(sk));
+ return -EFAULT;
+ }
+#endif
+
if(skb->len > cur_mss) {
if(tcp_fragment(sk, skb, cur_mss))
- return 1; /* We'll try again later. */
+ return -ENOMEM; /* We'll try again later. */
/* New SKB created, account for it. */
tp->packets_out++;
@@ -646,7 +695,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
tcp_retrans_try_collapse(sk, skb, cur_mss);
if(tp->af_specific->rebuild_header(sk))
- return 1; /* Routing failure or similar. */
+ return -EHOSTUNREACH; /* Routing failure or similar. */
/* Some Solaris stacks overoptimize and ignore the FIN on a
* retransmit when old data is attached. So strip it off
@@ -673,13 +722,10 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
else
skb = skb_clone(skb, GFP_ATOMIC);
- tcp_transmit_skb(sk, skb);
-
/* Update global TCP statistics and return success. */
- sk->prot->retransmits++;
TCP_INC_STATS(TcpRetransSegs);
- return 0;
+ return tcp_transmit_skb(sk, skb);
}
/* This gets called after a retransmit timeout, and the initially
@@ -774,7 +820,11 @@ void tcp_send_fin(struct sock *sk)
*/
mss_now = tcp_current_mss(sk);
- if((tp->send_head != NULL) && (skb->len < mss_now)) {
+ /* Please, find seven differences of 2.3.33 and loook
+ * what I broke here. 8) --ANK
+ */
+
+ if(tp->send_head != NULL) {
/* tcp_write_xmit() takes care of the rest. */
TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_FIN;
TCP_SKB_CB(skb)->end_seq++;
@@ -783,31 +833,34 @@ void tcp_send_fin(struct sock *sk)
/* Special case to avoid Nagle bogosity. If this
* segment is the last segment, and it was queued
* due to Nagle/SWS-avoidance, send it out now.
+ *
+ * Hmm... actually it overrides also congestion
+ * avoidance (OK for FIN) and retransmit phase
+ * (not OK? Added.).
*/
if(tp->send_head == skb &&
- !sk->nonagle &&
- skb->len < (tp->rcv_mss >> 1) &&
- tp->packets_out &&
- !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_URG)) {
- update_send_head(sk);
+ !after(tp->write_seq, tp->snd_una + tp->snd_wnd) &&
+ !tp->retransmits) {
TCP_SKB_CB(skb)->when = tcp_time_stamp;
- tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
- tp->packets_out++;
- tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
- if(!tcp_timer_is_set(sk, TIME_RETRANS))
- tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
+ if (!tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))) {
+ update_send_head(sk);
+ tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
+ tp->packets_out++;
+ if(!tcp_timer_is_set(sk, TCP_TIME_RETRANS))
+ tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
+ } else
+ tcp_check_probe_timer(sk, tp);
}
} else {
/* Socket is locked, keep trying until memory is available. */
do {
skb = sock_wmalloc(sk,
- (MAX_HEADER +
- sk->prot->max_header),
+ MAX_TCP_HEADER + 15,
1, GFP_KERNEL);
} while (skb == NULL);
/* Reserve space for headers and prepare control bits. */
- skb_reserve(skb, MAX_HEADER + sk->prot->max_header);
+ skb_reserve(skb, MAX_TCP_HEADER);
skb->csum = 0;
TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_FIN);
TCP_SKB_CB(skb)->sacked = 0;
@@ -816,7 +869,8 @@ void tcp_send_fin(struct sock *sk)
/* FIN eats a sequence byte, write_seq advanced by tcp_send_skb(). */
TCP_SKB_CB(skb)->seq = tp->write_seq;
TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1;
- tcp_send_skb(sk, skb, 0);
+ tcp_send_skb(sk, skb, 0, mss_now);
+ __tcp_push_pending_frames(sk, tp, mss_now);
}
}
@@ -831,19 +885,19 @@ void tcp_send_active_reset(struct sock *sk, int priority)
struct sk_buff *skb;
/* NOTE: No TCP options attached and we never retransmit this. */
- skb = alloc_skb(MAX_HEADER + sk->prot->max_header, priority);
+ skb = alloc_skb(MAX_TCP_HEADER + 15, priority);
if (!skb)
return;
/* Reserve space for headers and prepare control bits. */
- skb_reserve(skb, MAX_HEADER + sk->prot->max_header);
+ skb_reserve(skb, MAX_TCP_HEADER);
skb->csum = 0;
TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_RST);
TCP_SKB_CB(skb)->sacked = 0;
TCP_SKB_CB(skb)->urg_ptr = 0;
/* Send it off. */
- TCP_SKB_CB(skb)->seq = tp->write_seq;
+ TCP_SKB_CB(skb)->seq = tp->snd_nxt;
TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
TCP_SKB_CB(skb)->when = tcp_time_stamp;
tcp_transmit_skb(sk, skb);
@@ -859,13 +913,13 @@ int tcp_send_synack(struct sock *sk)
struct tcp_opt* tp = &(sk->tp_pinfo.af_tcp);
struct sk_buff* skb;
- skb = sock_wmalloc(sk, (MAX_HEADER + sk->prot->max_header),
+ skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15,
1, GFP_ATOMIC);
if (skb == NULL)
return -ENOMEM;
/* Reserve space for headers and prepare control bits. */
- skb_reserve(skb, MAX_HEADER + sk->prot->max_header);
+ skb_reserve(skb, MAX_TCP_HEADER);
skb->csum = 0;
TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_SYN);
TCP_SKB_CB(skb)->sacked = 0;
@@ -877,8 +931,7 @@ int tcp_send_synack(struct sock *sk)
__skb_queue_tail(&sk->write_queue, skb);
TCP_SKB_CB(skb)->when = tcp_time_stamp;
tp->packets_out++;
- tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
- return 0;
+ return tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
}
/*
@@ -887,16 +940,17 @@ int tcp_send_synack(struct sock *sk)
struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
struct open_request *req)
{
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
struct tcphdr *th;
int tcp_header_size;
struct sk_buff *skb;
- skb = sock_wmalloc(sk, MAX_HEADER + sk->prot->max_header, 1, GFP_ATOMIC);
+ skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC);
if (skb == NULL)
return NULL;
/* Reserve space for headers. */
- skb_reserve(skb, MAX_HEADER + sk->prot->max_header);
+ skb_reserve(skb, MAX_TCP_HEADER);
skb->dst = dst_clone(dst);
@@ -919,7 +973,7 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */
__u8 rcv_wscale;
/* Set this up on the first call only */
- req->window_clamp = skb->dst->window;
+ req->window_clamp = tp->window_clamp ? : skb->dst->window;
/* tcp_full_space because it is guaranteed to be the first packet */
tcp_select_initial_window(tcp_full_space(sk),
dst->advmss - (req->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0),
@@ -951,7 +1005,7 @@ int tcp_connect(struct sock *sk, struct sk_buff *buff)
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
/* Reserve space for headers. */
- skb_reserve(buff, MAX_HEADER + sk->prot->max_header);
+ skb_reserve(buff, MAX_TCP_HEADER + 15);
/* We'll fix this up when we get a response from the other end.
* See tcp_input.c:tcp_rcv_state_process case TCP_SYN_SENT.
@@ -962,12 +1016,16 @@ int tcp_connect(struct sock *sk, struct sk_buff *buff)
/* If user gave his TCP_MAXSEG, record it to clamp */
if (tp->user_mss)
tp->mss_clamp = tp->user_mss;
+ tp->max_window = 0;
tcp_sync_mss(sk, dst->pmtu);
+ tcp_initialize_rcv_mss(sk);
- tp->window_clamp = dst->window;
+ if (!tp->window_clamp)
+ tp->window_clamp = dst->window;
+ tp->advmss = dst->advmss;
tcp_select_initial_window(tcp_full_space(sk),
- dst->advmss - (tp->tcp_header_len - sizeof(struct tcphdr)),
+ tp->advmss - (tp->tcp_header_len - sizeof(struct tcphdr)),
&tp->rcv_wnd,
&tp->window_clamp,
sysctl_tcp_window_scaling,
@@ -982,10 +1040,12 @@ int tcp_connect(struct sock *sk, struct sk_buff *buff)
goto err_out;
sk->err = 0;
+ sk->done = 0;
tp->snd_wnd = 0;
tp->snd_wl1 = 0;
tp->snd_wl2 = tp->write_seq;
tp->snd_una = tp->write_seq;
+ tp->snd_sml = tp->write_seq;
tp->rcv_nxt = 0;
tp->rcv_wup = 0;
tp->copied_seq = 0;
@@ -1006,13 +1066,14 @@ int tcp_connect(struct sock *sk, struct sk_buff *buff)
/* Send it off. */
TCP_SKB_CB(buff)->when = tcp_time_stamp;
+ tp->syn_stamp = TCP_SKB_CB(buff)->when;
__skb_queue_tail(&sk->write_queue, buff);
tp->packets_out++;
tcp_transmit_skb(sk, skb_clone(buff, GFP_KERNEL));
TCP_INC_STATS(TcpActiveOpens);
/* Timer for repeating the SYN until an answer. */
- tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
+ tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
return 0;
err_out:
@@ -1025,16 +1086,14 @@ err_out:
* to see if we should even be here. See tcp_input.c:tcp_ack_snd_check()
* for details.
*/
-void tcp_send_delayed_ack(struct sock *sk, int max_timeout)
+void tcp_send_delayed_ack(struct sock *sk)
{
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
unsigned long timeout;
/* Stay within the limit we were given */
- timeout = (tp->ato << 1) >> 1;
- if (timeout > max_timeout)
- timeout = max_timeout;
- timeout += jiffies;
+ timeout = tp->ack.ato;
+ timeout += jiffies + (timeout>>2);
/* Use new timeout only if there wasn't a older one earlier. */
spin_lock_bh(&sk->timer_lock);
@@ -1042,18 +1101,46 @@ void tcp_send_delayed_ack(struct sock *sk, int max_timeout)
sock_hold(sk);
tp->delack_timer.expires = timeout;
} else {
+ /* If delack timer was blocked or is about to expire,
+ * send ACK now.
+ */
+ if (tp->ack.blocked || time_before_eq(tp->delack_timer.expires, jiffies+(tp->ack.ato>>2))) {
+ spin_unlock_bh(&sk->timer_lock);
+
+ tcp_send_ack(sk);
+ __sock_put(sk);
+ return;
+ }
+
if (time_before(timeout, tp->delack_timer.expires))
tp->delack_timer.expires = timeout;
}
add_timer(&tp->delack_timer);
spin_unlock_bh(&sk->timer_lock);
+
+#ifdef TCP_FORMAL_WINDOW
+ /* Explanation. Header prediction path does not handle
+ * case of zero window. If we send ACK immediately, pred_flags
+ * are reset when sending ACK. If rcv_nxt is advanced and
+ * ack is not sent, than delayed ack is scheduled.
+ * Hence, it is the best place to check for zero window.
+ */
+ if (tp->pred_flags) {
+ if (tcp_receive_window(tp) == 0)
+ tp->pred_flags = 0;
+ } else {
+ if (skb_queue_len(&tp->out_of_order_queue) == 0 &&
+ !tp->urg_data)
+ tcp_fast_path_on(tp);
+ }
+#endif
}
/* This routine sends an ack and also updates the window. */
void tcp_send_ack(struct sock *sk)
{
/* If we have been reset, we may not send again. */
- if(!sk->zapped) {
+ if(sk->state != TCP_CLOSE) {
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
struct sk_buff *buff;
@@ -1061,29 +1148,15 @@ void tcp_send_ack(struct sock *sk)
* tcp_transmit_skb() will set the ownership to this
* sock.
*/
- buff = alloc_skb(MAX_HEADER + sk->prot->max_header, GFP_ATOMIC);
+ buff = alloc_skb(MAX_TCP_HEADER + 15, GFP_ATOMIC);
if (buff == NULL) {
- /* Force it to send an ack. We don't have to do this
- * (ACK is unreliable) but it's much better use of
- * bandwidth on slow links to send a spare ack than
- * resend packets.
- *
- * This is the one possible way that we can delay an
- * ACK and have tp->ato indicate that we are in
- * quick ack mode, so clear it. It is also the only
- * possible way for ato to be zero, when ACK'ing a
- * SYNACK because we've taken no ATO measurement yet.
- */
- if (tcp_in_quickack_mode(tp))
- tcp_exit_quickack_mode(tp);
- if (!tp->ato)
- tp->ato = tp->rto;
- tcp_send_delayed_ack(sk, HZ/2);
+ tp->ack.pending = 1;
+ tcp_reset_xmit_timer(sk, TCP_TIME_DACK, TCP_DELACK_MAX);
return;
}
/* Reserve space for headers and prepare control bits. */
- skb_reserve(buff, MAX_HEADER + sk->prot->max_header);
+ skb_reserve(buff, MAX_TCP_HEADER);
buff->csum = 0;
TCP_SKB_CB(buff)->flags = TCPCB_FLAG_ACK;
TCP_SKB_CB(buff)->sacked = 0;
@@ -1099,24 +1172,20 @@ void tcp_send_ack(struct sock *sk)
/* This routine sends a packet with an out of date sequence
* number. It assumes the other end will try to ack it.
*/
-void tcp_write_wakeup(struct sock *sk)
+int tcp_write_wakeup(struct sock *sk)
{
- /* After a valid reset we can send no more. */
- if (!sk->zapped) {
+ if (sk->state != TCP_CLOSE) {
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
struct sk_buff *skb;
- /* Write data can still be transmitted/retransmitted in the
- * following states. If any other state is encountered, return.
- * [listen/close will never occur here anyway]
+ /* Now this function is never called, while
+ * we have something not ACKed in queue.
*/
- if ((1 << sk->state) &
- ~(TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_FIN_WAIT1|
- TCPF_FIN_WAIT2|TCPF_LAST_ACK|TCPF_CLOSING))
- return;
+ BUG_TRAP(tp->snd_una == tp->snd_nxt);
- if (before(tp->snd_nxt, tp->snd_una + tp->snd_wnd) &&
- ((skb = tp->send_head) != NULL)) {
+ if (tp->snd_wnd > (tp->snd_nxt-tp->snd_una)
+ && ((skb = tp->send_head) != NULL)) {
+ int err;
unsigned long win_size;
/* We are probing the opening of a window
@@ -1126,24 +1195,26 @@ void tcp_write_wakeup(struct sock *sk)
win_size = tp->snd_wnd - (tp->snd_nxt - tp->snd_una);
if (win_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq) {
if (tcp_fragment(sk, skb, win_size))
- return; /* Let a retransmit get it. */
+ return -1;
}
- update_send_head(sk);
TCP_SKB_CB(skb)->when = tcp_time_stamp;
- tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
- tp->packets_out++;
- tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
- if (!tcp_timer_is_set(sk, TIME_RETRANS))
- tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
+ err = tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
+ if (!err) {
+ update_send_head(sk);
+ tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
+ tp->packets_out++;
+ if (!tcp_timer_is_set(sk, TCP_TIME_RETRANS))
+ tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
+ }
+ return err;
} else {
/* We don't queue it, tcp_transmit_skb() sets ownership. */
- skb = alloc_skb(MAX_HEADER + sk->prot->max_header,
- GFP_ATOMIC);
+ skb = alloc_skb(MAX_TCP_HEADER + 15, GFP_ATOMIC);
if (skb == NULL)
- return;
+ return -1;
/* Reserve space for headers and set control bits. */
- skb_reserve(skb, MAX_HEADER + sk->prot->max_header);
+ skb_reserve(skb, MAX_TCP_HEADER);
skb->csum = 0;
TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK;
TCP_SKB_CB(skb)->sacked = 0;
@@ -1152,13 +1223,18 @@ void tcp_write_wakeup(struct sock *sk)
/* Use a previous sequence. This should cause the other
* end to send an ack. Don't queue or clone SKB, just
* send it.
+ *
+ * RED-PEN: logically it should be snd_una-1.
+ * snd_nxt-1 will not be acked. snd_una==snd_nxt
+ * in this place however. Right?
*/
- TCP_SKB_CB(skb)->seq = tp->snd_nxt - 1;
+ TCP_SKB_CB(skb)->seq = tp->snd_una - 1;
TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
TCP_SKB_CB(skb)->when = tcp_time_stamp;
- tcp_transmit_skb(sk, skb);
+ return tcp_transmit_skb(sk, skb);
}
}
+ return -1;
}
/* A window probe timeout has occurred. If window is not closed send
@@ -1167,11 +1243,32 @@ void tcp_write_wakeup(struct sock *sk)
void tcp_send_probe0(struct sock *sk)
{
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ int err;
+
+ err = tcp_write_wakeup(sk);
+
+ if (tp->packets_out || !tp->send_head) {
+ /* Cancel probe timer, if it is not required. */
+ tp->probes_out = 0;
+ tp->backoff = 0;
+ return;
+ }
- tcp_write_wakeup(sk);
- tp->pending = TIME_PROBE0;
- tp->backoff++;
- tp->probes_out++;
- tcp_reset_xmit_timer (sk, TIME_PROBE0,
- min(tp->rto << tp->backoff, 120*HZ));
+ if (err <= 0) {
+ tp->backoff++;
+ tp->probes_out++;
+ tcp_reset_xmit_timer (sk, TCP_TIME_PROBE0,
+ min(tp->rto << tp->backoff, TCP_RTO_MAX));
+ } else {
+ /* If packet was not sent due to local congestion,
+ * do not backoff and do not remember probes_out.
+ * Let local senders to fight for local resources.
+ *
+ * Use accumulated backoff yet.
+ */
+ if (!tp->probes_out)
+ tp->probes_out=1;
+ tcp_reset_xmit_timer (sk, TCP_TIME_PROBE0,
+ min(tp->rto << tp->backoff, TCP_RESOURCE_PROBE_INTERVAL));
+ }
}
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index a38724e42..bff4e872f 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_timer.c,v 1.68 1999/09/07 02:31:43 davem Exp $
+ * Version: $Id: tcp_timer.c,v 1.71 2000/01/18 08:24:19 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -23,29 +23,20 @@
#include <net/tcp.h>
int sysctl_tcp_syn_retries = TCP_SYN_RETRIES;
+int sysctl_tcp_synack_retries = TCP_SYNACK_RETRIES;
int sysctl_tcp_keepalive_time = TCP_KEEPALIVE_TIME;
int sysctl_tcp_keepalive_probes = TCP_KEEPALIVE_PROBES;
int sysctl_tcp_keepalive_intvl = TCP_KEEPALIVE_INTVL;
int sysctl_tcp_retries1 = TCP_RETR1;
int sysctl_tcp_retries2 = TCP_RETR2;
+int sysctl_tcp_orphan_retries = TCP_ORPHAN_RETRIES;
-
-static void tcp_sltimer_handler(unsigned long);
-static void tcp_syn_recv_timer(unsigned long);
+static void tcp_retransmit_timer(unsigned long);
+static void tcp_delack_timer(unsigned long);
+static void tcp_probe_timer(unsigned long);
+static void tcp_keepalive_timer (unsigned long data);
static void tcp_twkill(unsigned long);
-struct timer_list tcp_slow_timer = {
- NULL, NULL,
- 0, 0,
- tcp_sltimer_handler,
-};
-
-
-struct tcp_sl_timer tcp_slt_array[TCP_SLT_MAX] = {
- {ATOMIC_INIT(0), TCP_SYNACK_PERIOD, 0, tcp_syn_recv_timer},/* SYNACK */
- {ATOMIC_INIT(0), TCP_TWKILL_PERIOD, 0, tcp_twkill} /* TWKILL */
-};
-
const char timer_bug_msg[] = KERN_DEBUG "tcpbug: unknown timer value\n";
/*
@@ -56,17 +47,25 @@ const char timer_bug_msg[] = KERN_DEBUG "tcpbug: unknown timer value\n";
void tcp_init_xmit_timers(struct sock *sk)
{
- init_timer(&sk->tp_pinfo.af_tcp.retransmit_timer);
- sk->tp_pinfo.af_tcp.retransmit_timer.function=&tcp_retransmit_timer;
- sk->tp_pinfo.af_tcp.retransmit_timer.data = (unsigned long) sk;
-
- init_timer(&sk->tp_pinfo.af_tcp.delack_timer);
- sk->tp_pinfo.af_tcp.delack_timer.function=&tcp_delack_timer;
- sk->tp_pinfo.af_tcp.delack_timer.data = (unsigned long) sk;
-
- init_timer(&sk->tp_pinfo.af_tcp.probe_timer);
- sk->tp_pinfo.af_tcp.probe_timer.function=&tcp_probe_timer;
- sk->tp_pinfo.af_tcp.probe_timer.data = (unsigned long) sk;
+ struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
+
+ spin_lock_init(&sk->timer_lock);
+
+ init_timer(&tp->retransmit_timer);
+ tp->retransmit_timer.function=&tcp_retransmit_timer;
+ tp->retransmit_timer.data = (unsigned long) sk;
+
+ init_timer(&tp->delack_timer);
+ tp->delack_timer.function=&tcp_delack_timer;
+ tp->delack_timer.data = (unsigned long) sk;
+
+ init_timer(&tp->probe_timer);
+ tp->probe_timer.function=&tcp_probe_timer;
+ tp->probe_timer.data = (unsigned long) sk;
+
+ init_timer(&sk->timer);
+ sk->timer.function=&tcp_keepalive_timer;
+ sk->timer.data = (unsigned long) sk;
}
/*
@@ -79,7 +78,7 @@ void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long when)
spin_lock_bh(&sk->timer_lock);
switch (what) {
- case TIME_RETRANS:
+ case TCP_TIME_RETRANS:
/* When seting the transmit timer the probe timer
* should not be set.
* The delayed ack timer can be set if we are changing the
@@ -89,29 +88,25 @@ void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long when)
__sock_put(sk);
if (!tp->retransmit_timer.prev || !del_timer(&tp->retransmit_timer))
sock_hold(sk);
- if (when > 120*HZ) {
+ if (when > TCP_RTO_MAX) {
printk(KERN_DEBUG "reset_xmit_timer sk=%p when=0x%lx, caller=%p\n", sk, when, NET_CALLER(sk));
- when = 120*HZ;
+ when = TCP_RTO_MAX;
}
mod_timer(&tp->retransmit_timer, jiffies+when);
break;
- case TIME_DACK:
+ case TCP_TIME_DACK:
if (!tp->delack_timer.prev || !del_timer(&tp->delack_timer))
sock_hold(sk);
mod_timer(&tp->delack_timer, jiffies+when);
break;
- case TIME_PROBE0:
+ case TCP_TIME_PROBE0:
if (!tp->probe_timer.prev || !del_timer(&tp->probe_timer))
sock_hold(sk);
mod_timer(&tp->probe_timer, jiffies+when);
break;
- case TIME_WRITE:
- printk(KERN_DEBUG "bug: tcp_reset_xmit_timer TIME_WRITE\n");
- break;
-
default:
printk(KERN_DEBUG "bug: unknown timer value\n");
};
@@ -127,6 +122,7 @@ void tcp_clear_xmit_timers(struct sock *sk)
__sock_put(sk);
if(tp->delack_timer.prev && del_timer(&tp->delack_timer))
__sock_put(sk);
+ tp->ack.blocked = 0;
if(tp->probe_timer.prev && del_timer(&tp->probe_timer))
__sock_put(sk);
if(sk->timer.prev && del_timer(&sk->timer))
@@ -134,39 +130,33 @@ void tcp_clear_xmit_timers(struct sock *sk)
spin_unlock_bh(&sk->timer_lock);
}
-static void tcp_write_err(struct sock *sk, int force)
+static void tcp_write_err(struct sock *sk)
{
- sk->err = sk->err_soft ? sk->err_soft : ETIMEDOUT;
+ sk->err = sk->err_soft ? : ETIMEDOUT;
sk->error_report(sk);
- tcp_clear_xmit_timers(sk);
-
- /* Do not time wait the socket. It is timed out and, hence,
- * idle for 120*HZ. "force" argument is ignored, delete
- * it eventually.
- */
-
- /* Clean up time. */
- tcp_set_state(sk, TCP_CLOSE);
tcp_done(sk);
}
/* A write timeout has occurred. Process the after effects. */
-static void tcp_write_timeout(struct sock *sk)
+static int tcp_write_timeout(struct sock *sk)
{
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ int retry_until;
- /* Look for a 'soft' timeout. */
- if ((sk->state == TCP_ESTABLISHED &&
- tp->retransmits && (tp->retransmits % TCP_QUICK_TRIES) == 0) ||
- (sk->state != TCP_ESTABLISHED && tp->retransmits > sysctl_tcp_retries1)) {
- /* NOTE. draft-ietf-tcpimpl-pmtud-01.txt requires pmtu black
- hole detection. :-(
+ if ((1<<sk->state)&(TCPF_SYN_SENT|TCPF_SYN_RECV)) {
+ if (tp->retransmits)
+ dst_negative_advice(&sk->dst_cache);
+ retry_until = tp->syn_retries ? : sysctl_tcp_syn_retries;
+ } else {
+ if (tp->retransmits >= sysctl_tcp_retries1) {
+ /* NOTE. draft-ietf-tcpimpl-pmtud-01.txt requires pmtu black
+ hole detection. :-(
- It is place to make it. It is not made. I do not want
- to make it. It is disguisting. It does not work in any
- case. Let me to cite the same draft, which requires for
- us to implement this:
+ It is place to make it. It is not made. I do not want
+ to make it. It is disguisting. It does not work in any
+ case. Let me to cite the same draft, which requires for
+ us to implement this:
"The one security concern raised by this memo is that ICMP black holes
are often caused by over-zealous security administrators who block
@@ -177,57 +167,70 @@ static void tcp_write_timeout(struct sock *sk)
be far nicer to have all of the black holes fixed rather than fixing
all of the TCP implementations."
- Golden words :-).
- */
+ Golden words :-).
+ */
- dst_negative_advice(&sk->dst_cache);
+ dst_negative_advice(&sk->dst_cache);
+ }
+ retry_until = sysctl_tcp_retries2;
+ if (sk->dead)
+ retry_until = sysctl_tcp_orphan_retries;
}
-
- /* Have we tried to SYN too many times (repent repent 8)) */
- if (sk->state == TCP_SYN_SENT &&
- ((!tp->syn_retries && tp->retransmits > sysctl_tcp_syn_retries) ||
- (tp->syn_retries && tp->retransmits > tp->syn_retries))) {
- tcp_write_err(sk, 1);
- /* Don't FIN, we got nothing back */
- } else if (tp->retransmits > sysctl_tcp_retries2) {
+
+ if (tp->retransmits >= retry_until) {
/* Has it gone just too far? */
- tcp_write_err(sk, 0);
+ tcp_write_err(sk);
+ return 1;
}
+ return 0;
}
-void tcp_delack_timer(unsigned long data)
+static void tcp_delack_timer(unsigned long data)
{
struct sock *sk = (struct sock*)data;
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
bh_lock_sock(sk);
if (sk->lock.users) {
/* Try again later. */
- tcp_reset_xmit_timer(sk, TIME_DACK, HZ/5);
+ tp->ack.blocked = 1;
+ NET_INC_STATS_BH(DelayedACKLocked);
+ tcp_reset_xmit_timer(sk, TCP_TIME_DACK, TCP_DELACK_MIN);
goto out_unlock;
}
- if(!sk->zapped &&
- sk->tp_pinfo.af_tcp.delayed_acks &&
- sk->state != TCP_CLOSE)
+ if (tp->ack.pending) {
+ /* Delayed ACK missed: inflate ATO, leave pingpong mode */
+ tp->ack.ato = min(tp->ack.ato<<1, TCP_ATO_MAX);
+ tp->ack.pingpong = 0;
tcp_send_ack(sk);
+ NET_INC_STATS_BH(DelayedACKs);
+ }
+ TCP_CHECK_TIMER(sk);
out_unlock:
bh_unlock_sock(sk);
sock_put(sk);
}
-void tcp_probe_timer(unsigned long data)
+static void tcp_probe_timer(unsigned long data)
{
struct sock *sk = (struct sock*)data;
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-
- if(sk->zapped)
- goto out;
+ int max_probes;
bh_lock_sock(sk);
if (sk->lock.users) {
/* Try again later. */
- tcp_reset_xmit_timer(sk, TIME_PROBE0, HZ/5);
+ tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, HZ/5);
+ goto out_unlock;
+ }
+
+ if (sk->state == TCP_CLOSE)
+ goto out_unlock;
+
+ if (tp->packets_out || !tp->send_head) {
+ tp->probes_out = 0;
goto out_unlock;
}
@@ -246,151 +249,251 @@ void tcp_probe_timer(unsigned long data)
* with RFCs, only probe timer combines both retransmission timeout
* and probe timeout in one bottle. --ANK
*/
- if (tp->probes_out > sysctl_tcp_retries2) {
- tcp_write_err(sk, 0);
+ max_probes = sk->dead ? sysctl_tcp_orphan_retries : sysctl_tcp_retries2;
+
+ if (tp->probes_out > max_probes) {
+ tcp_write_err(sk);
} else {
/* Only send another probe if we didn't close things up. */
tcp_send_probe0(sk);
+ TCP_CHECK_TIMER(sk);
}
out_unlock:
bh_unlock_sock(sk);
-out:
sock_put(sk);
}
/* Kill off TIME_WAIT sockets once their lifetime has expired. */
-int tcp_tw_death_row_slot = 0;
-static struct tcp_tw_bucket *tcp_tw_death_row[TCP_TWKILL_SLOTS] =
- { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-static spinlock_t tw_death_lock = SPIN_LOCK_UNLOCKED;
+static int tcp_tw_death_row_slot = 0;
+int tcp_tw_count = 0;
+static struct tcp_tw_bucket *tcp_tw_death_row[TCP_TWKILL_SLOTS];
+static spinlock_t tw_death_lock = SPIN_LOCK_UNLOCKED;
+static struct timer_list tcp_tw_timer = { function: tcp_twkill };
static void tcp_twkill(unsigned long data)
{
struct tcp_tw_bucket *tw;
int killed = 0;
- /* The death-row tw chains are only ever touched
- * in BH context so no BH disabling (for now) is needed.
+ /* NOTE: compare this to previous version where lock
+ * was released after detaching chain. It was racy,
+ * because tw buckets are scheduled in not serialized context
+ * in 2.3 (with netfilter), and with softnet it is common, because
+ * soft irqs are not sequenced.
*/
spin_lock(&tw_death_lock);
- tw = tcp_tw_death_row[tcp_tw_death_row_slot];
- tcp_tw_death_row[tcp_tw_death_row_slot] = NULL;
- tcp_tw_death_row_slot =
- ((tcp_tw_death_row_slot + 1) & (TCP_TWKILL_SLOTS - 1));
- spin_unlock(&tw_death_lock);
- while(tw != NULL) {
- struct tcp_tw_bucket *next = tw->next_death;
+ if (tcp_tw_count == 0)
+ goto out;
+
+ while((tw = tcp_tw_death_row[tcp_tw_death_row_slot]) != NULL) {
+ tcp_tw_death_row[tcp_tw_death_row_slot] = tw->next_death;
+ tw->pprev_death = NULL;
+ spin_unlock(&tw_death_lock);
tcp_timewait_kill(tw);
tcp_tw_put(tw);
+
killed++;
- tw = next;
- }
- if(killed != 0) {
- struct tcp_sl_timer *slt = (struct tcp_sl_timer *)data;
- atomic_sub(killed, &slt->count);
+
+ spin_lock(&tw_death_lock);
}
+ tcp_tw_death_row_slot =
+ ((tcp_tw_death_row_slot + 1) & (TCP_TWKILL_SLOTS - 1));
+
+ if ((tcp_tw_count -= killed) != 0)
+ mod_timer(&tcp_tw_timer, jiffies+TCP_TWKILL_PERIOD);
+ net_statistics[smp_processor_id()*2].TimeWaited += killed;
+out:
+ spin_unlock(&tw_death_lock);
}
/* These are always called from BH context. See callers in
* tcp_input.c to verify this.
*/
-void tcp_tw_schedule(struct tcp_tw_bucket *tw)
-{
- struct tcp_tw_bucket **tpp;
- int slot;
+/* This is for handling early-kills of TIME_WAIT sockets. */
+void tcp_tw_deschedule(struct tcp_tw_bucket *tw)
+{
spin_lock(&tw_death_lock);
- slot = (tcp_tw_death_row_slot - 1) & (TCP_TWKILL_SLOTS - 1);
- tpp = &tcp_tw_death_row[slot];
- if((tw->next_death = *tpp) != NULL)
- (*tpp)->pprev_death = &tw->next_death;
- *tpp = tw;
- tw->pprev_death = tpp;
-
- tw->death_slot = slot;
- atomic_inc(&tw->refcnt);
+ if (tw->pprev_death) {
+ if(tw->next_death)
+ tw->next_death->pprev_death = tw->pprev_death;
+ *tw->pprev_death = tw->next_death;
+ tw->pprev_death = NULL;
+ tcp_tw_put(tw);
+ if (--tcp_tw_count == 0)
+ del_timer(&tcp_tw_timer);
+ }
spin_unlock(&tw_death_lock);
-
- tcp_inc_slow_timer(TCP_SLT_TWKILL);
}
-/* Happens rarely if at all, no care about scalability here. */
-void tcp_tw_reschedule(struct tcp_tw_bucket *tw)
+/* Short-time timewait calendar */
+
+static int tcp_twcal_hand = -1;
+static int tcp_twcal_jiffie;
+static void tcp_twcal_tick(unsigned long);
+static struct timer_list tcp_twcal_timer = {NULL, NULL, 0, 0, tcp_twcal_tick,};
+static struct tcp_tw_bucket *tcp_twcal_row[TCP_TW_RECYCLE_SLOTS];
+
+void tcp_tw_schedule(struct tcp_tw_bucket *tw, int timeo)
{
struct tcp_tw_bucket **tpp;
int slot;
+ /* timeout := RTO * 3.5
+ *
+ * 3.5 = 1+2+0.5 to wait for two retransmits.
+ *
+ * RATIONALE: if FIN arrived and we entered TIME-WAIT state,
+ * our ACK acking that FIN can be lost. If N subsequent retransmitted
+ * FINs (or previous seqments) are lost (probability of such event
+ * is p^(N+1), where p is probability to lose single packet and
+ * time to detect the loss is about RTO*(2^N - 1) with exponential
+ * backoff). Normal timewait length is calculated so, that we
+ * waited at least for one retransmitted FIN (maximal RTO is 120sec).
+ * [ BTW Linux. following BSD, violates this requirement waiting
+ * only for 60sec, we should wait at least for 240 secs.
+ * Well, 240 consumes too much of resources 8)
+ * ]
+ * This interval is not reduced to catch old duplicate and
+ * responces to our wandering segments living for two MSLs.
+ * However, if we use PAWS to detect
+ * old duplicates, we can reduce the interval to bounds required
+ * by RTO, rather than MSL. So, if peer understands PAWS, we
+ * kill tw bucket after 3.5*RTO (it is important that this number
+ * is greater than TS tick!) and detect old duplicates with help
+ * of PAWS.
+ */
+ slot = (timeo + (1<<TCP_TW_RECYCLE_TICK) - 1) >> TCP_TW_RECYCLE_TICK;
+
spin_lock(&tw_death_lock);
+
+ /* Unlink it, if it was scheduled */
if (tw->pprev_death) {
if(tw->next_death)
tw->next_death->pprev_death = tw->pprev_death;
*tw->pprev_death = tw->next_death;
tw->pprev_death = NULL;
+ tcp_tw_count--;
} else
atomic_inc(&tw->refcnt);
- slot = (tcp_tw_death_row_slot - 1) & (TCP_TWKILL_SLOTS - 1);
- tpp = &tcp_tw_death_row[slot];
+ if (slot >= TCP_TW_RECYCLE_SLOTS) {
+ /* Schedule to slow timer */
+ if (timeo >= TCP_TIMEWAIT_LEN) {
+ slot = TCP_TWKILL_SLOTS-1;
+ } else {
+ slot = (timeo + TCP_TWKILL_PERIOD-1) / TCP_TWKILL_PERIOD;
+ if (slot >= TCP_TWKILL_SLOTS)
+ slot = TCP_TWKILL_SLOTS-1;
+ }
+ tw->ttd = jiffies + timeo;
+ slot = (tcp_tw_death_row_slot + slot) & (TCP_TWKILL_SLOTS - 1);
+ tpp = &tcp_tw_death_row[slot];
+ } else {
+ tw->ttd = jiffies + (slot<<TCP_TW_RECYCLE_TICK);
+
+ if (tcp_twcal_hand < 0) {
+ tcp_twcal_hand = 0;
+ tcp_twcal_jiffie = jiffies;
+ tcp_twcal_timer.expires = tcp_twcal_jiffie + (slot<<TCP_TW_RECYCLE_TICK);
+ add_timer(&tcp_twcal_timer);
+ } else {
+ if ((long)(tcp_twcal_timer.expires - jiffies) > (slot<<TCP_TW_RECYCLE_TICK))
+ mod_timer(&tcp_twcal_timer, jiffies + (slot<<TCP_TW_RECYCLE_TICK));
+ slot = (tcp_twcal_hand + slot)&(TCP_TW_RECYCLE_SLOTS-1);
+ }
+ tpp = &tcp_twcal_row[slot];
+ }
+
if((tw->next_death = *tpp) != NULL)
(*tpp)->pprev_death = &tw->next_death;
*tpp = tw;
tw->pprev_death = tpp;
- tw->death_slot = slot;
+ if (tcp_tw_count++ == 0)
+ mod_timer(&tcp_tw_timer, jiffies+TCP_TWKILL_PERIOD);
spin_unlock(&tw_death_lock);
-
- /* Timer was incremented when we first entered the table. */
}
-/* This is for handling early-kills of TIME_WAIT sockets. */
-void tcp_tw_deschedule(struct tcp_tw_bucket *tw)
+void tcp_twcal_tick(unsigned long dummy)
{
+ int n, slot;
+ unsigned long j;
+ unsigned long now = jiffies;
+ int killed = 0;
+ int adv = 0;
+
spin_lock(&tw_death_lock);
- if (tw->pprev_death) {
- if(tw->next_death)
- tw->next_death->pprev_death = tw->pprev_death;
- *tw->pprev_death = tw->next_death;
- tw->pprev_death = NULL;
- tcp_tw_put(tw);
+ if (tcp_twcal_hand < 0)
+ goto out;
+
+ slot = tcp_twcal_hand;
+ j = tcp_twcal_jiffie;
+
+ for (n=0; n<TCP_TW_RECYCLE_SLOTS; n++) {
+ if ((long)(j - now) <= 0) {
+ struct tcp_tw_bucket *tw;
+
+ while((tw = tcp_twcal_row[slot]) != NULL) {
+ tcp_twcal_row[slot] = tw->next_death;
+ tw->pprev_death = NULL;
+
+ tcp_timewait_kill(tw);
+ tcp_tw_put(tw);
+ killed++;
+ }
+ } else {
+ if (!adv) {
+ adv = 1;
+ tcp_twcal_jiffie = j;
+ tcp_twcal_hand = slot;
+ }
+
+ if (tcp_twcal_row[slot] != NULL) {
+ mod_timer(&tcp_twcal_timer, j);
+ goto out;
+ }
+ }
+ j += (1<<TCP_TW_RECYCLE_TICK);
+ slot = (slot+1)&(TCP_TW_RECYCLE_SLOTS-1);
}
- spin_unlock(&tw_death_lock);
+ tcp_twcal_hand = -1;
- tcp_dec_slow_timer(TCP_SLT_TWKILL);
+out:
+ if ((tcp_tw_count -= killed) == 0)
+ del_timer(&tcp_tw_timer);
+ net_statistics[smp_processor_id()*2].TimeWaitKilled += killed;
+ spin_unlock(&tw_death_lock);
}
/*
* The TCP retransmit timer.
- *
- * 1. An initial rtt timeout on the probe0 should cause what we can
- * of the first write queue buffer to be split and sent.
- * 2. On a 'major timeout' as defined by RFC1122 we do not report
- * ETIMEDOUT if we know an additional 'soft' error caused this.
- * tcp_err saves a 'soft error' for us.
*/
-void tcp_retransmit_timer(unsigned long data)
+static void tcp_retransmit_timer(unsigned long data)
{
struct sock *sk = (struct sock*)data;
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
- /* We are reset. We will send no more retransmits. */
- if(sk->zapped)
- goto out;
-
bh_lock_sock(sk);
if (sk->lock.users) {
/* Try again later */
- tcp_reset_xmit_timer(sk, TIME_RETRANS, HZ/20);
+ tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, HZ/20);
goto out_unlock;
}
- /* Clear delay ack timer. */
- tcp_clear_xmit_timer(sk, TIME_DACK);
+ if (sk->state == TCP_CLOSE || tp->packets_out == 0)
+ goto out_unlock;
+
+ BUG_TRAP(!skb_queue_empty(&sk->write_queue));
+
+ if (tcp_write_timeout(sk))
+ goto out_unlock;
/* RFC 2018, clear all 'sacked' flags in retransmission queue,
* the sender may have dropped out of order frames and we must
@@ -426,11 +529,19 @@ void tcp_retransmit_timer(unsigned long data)
tp->snd_cwnd = 1;
}
- tp->retransmits++;
-
tp->dup_acks = 0;
tp->high_seq = tp->snd_nxt;
- tcp_retransmit_skb(sk, skb_peek(&sk->write_queue));
+ if (tcp_retransmit_skb(sk, skb_peek(&sk->write_queue)) > 0) {
+ /* Retransmission failed because of local congestion,
+ * do not backoff.
+ */
+ if (!tp->retransmits)
+ tp->retransmits=1;
+ tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS,
+ min(tp->rto, TCP_RESOURCE_PROBE_INTERVAL));
+ TCP_CHECK_TIMER(sk);
+ goto out_unlock;
+ }
/* Increase the timeout each time we retransmit. Note that
* we do not increase the rtt estimate. rto is initialized
@@ -448,132 +559,105 @@ void tcp_retransmit_timer(unsigned long data)
* the 120 second clamps though!
*/
tp->backoff++;
- tp->rto = min(tp->rto << 1, 120*HZ);
- tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
-
- tcp_write_timeout(sk);
+ tp->retransmits++;
+ tp->rto = min(tp->rto << 1, TCP_RTO_MAX);
+ tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
+ TCP_CHECK_TIMER(sk);
out_unlock:
bh_unlock_sock(sk);
-out:
sock_put(sk);
}
/*
- * Slow timer for SYN-RECV sockets
+ * Timer for listening sockets
*/
-static void tcp_do_syn_queue(struct sock *sk, struct tcp_opt *tp, unsigned long now)
-{
- struct open_request *prev, *req;
-
- prev = (struct open_request *) &tp->syn_wait_queue;
- for(req = tp->syn_wait_queue; req; ) {
- struct open_request *next = req->dl_next;
-
- if (!req->sk && (long)(now - req->expires) >= 0) {
- tcp_synq_unlink(tp, req, prev);
- if(req->retrans >= sysctl_tcp_retries1) {
- (*req->class->destructor)(req);
- tcp_dec_slow_timer(TCP_SLT_SYNACK);
- tp->syn_backlog--;
- tcp_openreq_free(req);
- if (! tp->syn_wait_queue)
- break;
- } else {
- unsigned long timeo;
- struct open_request *rp;
-
- (*req->class->rtx_syn_ack)(sk, req);
- req->retrans++;
- timeo = min((TCP_TIMEOUT_INIT << req->retrans),
- (120 * HZ));
- req->expires = now + timeo;
- rp = prev->dl_next;
- tcp_synq_queue(tp, req);
- if(rp != prev->dl_next)
- prev = prev->dl_next;
- }
- } else
- prev = req;
- req = next;
- }
-}
-
-/* This now scales very nicely. -DaveM */
-static void tcp_syn_recv_timer(unsigned long data)
+static void tcp_synack_timer(struct sock *sk)
{
- struct sock *sk;
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ struct tcp_listen_opt *lopt = tp->listen_opt;
+ int max_retries = tp->syn_retries ? : sysctl_tcp_synack_retries;
+ int thresh = max_retries;
unsigned long now = jiffies;
- int i;
-
- read_lock(&tcp_lhash_lock);
- for(i = 0; i < TCP_LHTABLE_SIZE; i++) {
- sk = tcp_listening_hash[i];
- while(sk) {
- struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-
- /* TCP_LISTEN is implied. */
- bh_lock_sock(sk);
- if (!sk->lock.users && tp->syn_wait_queue)
- tcp_do_syn_queue(sk, tp, now);
- bh_unlock_sock(sk);
- sk = sk->next;
+ struct open_request **reqp, *req;
+ int i, budget;
+
+ if (lopt == NULL || lopt->qlen == 0)
+ return;
+
+ /* Normally all the openreqs are young and become mature
+ * (i.e. converted to established socket) for first timeout.
+ * If synack was not acknowledged for 3 seconds, it means
+ * one of the following things: synack was lost, ack was lost,
+ * rtt is high or nobody planned to ack (i.e. synflood).
+ * When server is a bit loaded, queue is populated with old
+ * open requests, reducing effective size of queue.
+ * When server is well loaded, queue size reduces to zero
+ * after several minutes of work. It is not synflood,
+ * it is normal operation. The solution is pruning
+ * too old entries overriding normal timeout, when
+ * situation becomes dangerous.
+ *
+ * Essentially, we reserve half of room for young
+ * embrions; and abort old ones without pity, if old
+ * ones are about to clog our table.
+ */
+ if (lopt->qlen>>(lopt->max_qlen_log-1)) {
+ int young = (lopt->qlen_young<<1);
+
+ while (thresh > 2) {
+ if (lopt->qlen < young)
+ break;
+ thresh--;
+ young <<= 1;
}
}
- read_unlock(&tcp_lhash_lock);
-}
-
-void tcp_sltimer_handler(unsigned long data)
-{
- struct tcp_sl_timer *slt = tcp_slt_array;
- unsigned long next = ~0UL;
- unsigned long now = jiffies;
- int i;
- for (i=0; i < TCP_SLT_MAX; i++, slt++) {
- if (atomic_read(&slt->count)) {
- long trigger;
-
- trigger = slt->period - ((long)(now - slt->last));
-
- if (trigger <= 0) {
- (*slt->handler)((unsigned long) slt);
- slt->last = now;
- trigger = slt->period;
+ if (tp->defer_accept)
+ max_retries = tp->defer_accept;
+
+ budget = 2*(TCP_SYNQ_HSIZE/(TCP_TIMEOUT_INIT/TCP_SYNQ_INTERVAL));
+ i = lopt->clock_hand;
+
+ do {
+ reqp=&lopt->syn_table[i];
+ while ((req = *reqp) != NULL) {
+ if ((long)(now - req->expires) >= 0) {
+ if ((req->retrans < thresh ||
+ (req->acked && req->retrans < max_retries))
+ && !req->class->rtx_syn_ack(sk, req, NULL)) {
+ unsigned long timeo;
+
+ if (req->retrans++ == 0)
+ lopt->qlen_young--;
+ timeo = min((TCP_TIMEOUT_INIT << req->retrans),
+ TCP_RTO_MAX);
+ req->expires = now + timeo;
+ reqp = &req->dl_next;
+ continue;
+ }
+
+ /* Drop this request */
+ write_lock(&tp->syn_wait_lock);
+ *reqp = req->dl_next;
+ write_unlock(&tp->syn_wait_lock);
+ lopt->qlen--;
+ if (req->retrans == 0)
+ lopt->qlen_young--;
+ tcp_openreq_free(req);
}
-
- /* Only reschedule if some events remain. */
- if (atomic_read(&slt->count))
- next = min(next, trigger);
+ reqp = &req->dl_next;
}
- }
- if (next != ~0UL)
- mod_timer(&tcp_slow_timer, (now + next));
-}
-/* __tcp_inc_slow_timer is called when an slow timer is started
- * first time (slt->count was 0). There is race condition between
- * timer creation and deletion and if we do not force adding timer here,
- * we might lose timer. We could avoid it with global spinlock, but
- * it is apparently overkill, so that we restart timer ALWAYS when
- * this function is entered, it guarantees that timer will not lost.
- */
+ i = (i+1)&(TCP_SYNQ_HSIZE-1);
-void __tcp_inc_slow_timer(struct tcp_sl_timer *slt)
-{
- unsigned long now = jiffies;
- unsigned long when;
+ } while (--budget > 0);
- slt->last = now;
+ lopt->clock_hand = i;
- when = now + slt->period;
-
- if (tcp_slow_timer.prev &&
- (long)(tcp_slow_timer.expires - when) < 0)
- when = tcp_slow_timer.expires;
-
- mod_timer(&tcp_slow_timer, when);
+ if (lopt->qlen)
+ tcp_reset_keepalive_timer(sk, TCP_SYNQ_INTERVAL);
}
void tcp_delete_keepalive_timer (struct sock *sk)
@@ -595,6 +679,9 @@ void tcp_reset_keepalive_timer (struct sock *sk, unsigned long len)
void tcp_set_keepalive(struct sock *sk, int val)
{
+ if ((1<<sk->state)&(TCPF_CLOSE|TCPF_LISTEN))
+ return;
+
if (val && !sk->keepopen)
tcp_reset_keepalive_timer(sk, keepalive_time_when(&sk->tp_pinfo.af_tcp));
else if (!val)
@@ -602,7 +689,7 @@ void tcp_set_keepalive(struct sock *sk, int val)
}
-void tcp_keepalive_timer (unsigned long data)
+static void tcp_keepalive_timer (unsigned long data)
{
struct sock *sk = (struct sock *) data;
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
@@ -616,14 +703,31 @@ void tcp_keepalive_timer (unsigned long data)
goto out;
}
- if (sk->state == TCP_FIN_WAIT2 && sk->dead)
+ if (sk->state == TCP_LISTEN) {
+ tcp_synack_timer(sk);
+ goto out;
+ }
+
+ if (sk->state == TCP_FIN_WAIT2 && sk->dead) {
+ if (tp->linger2 >= 0) {
+ int tmo = tcp_fin_time(tp) - TCP_TIMEWAIT_LEN;
+
+ if (tmo > 0) {
+ tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
+ goto out;
+ }
+ }
+ tcp_send_active_reset(sk, GFP_ATOMIC);
goto death;
+ }
- if (!sk->keepopen)
+ if (!sk->keepopen || sk->state == TCP_CLOSE)
goto out;
elapsed = keepalive_time_when(tp);
- if (!((1<<sk->state) & (TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_FIN_WAIT2)))
+
+ /* It is alive without keepalive 8) */
+ if (tp->packets_out || tp->send_head)
goto resched;
elapsed = tcp_time_stamp - tp->rcv_tstamp;
@@ -632,28 +736,30 @@ void tcp_keepalive_timer (unsigned long data)
if ((!tp->keepalive_probes && tp->probes_out >= sysctl_tcp_keepalive_probes) ||
(tp->keepalive_probes && tp->probes_out >= tp->keepalive_probes)) {
tcp_send_active_reset(sk, GFP_ATOMIC);
- tcp_write_err(sk, 1);
+ tcp_write_err(sk);
goto out;
}
- tp->probes_out++;
- tp->pending = TIME_KEEPOPEN;
- tcp_write_wakeup(sk);
- elapsed = keepalive_intvl_when(tp);
+ if (tcp_write_wakeup(sk) <= 0) {
+ tp->probes_out++;
+ elapsed = keepalive_intvl_when(tp);
+ } else {
+ /* If keepalive was lost due to local congestion,
+ * try harder.
+ */
+ elapsed = TCP_RESOURCE_PROBE_INTERVAL;
+ }
} else {
/* It is tp->rcv_tstamp + keepalive_time_when(tp) */
- if (keepalive_time_when(tp) > elapsed)
- elapsed = keepalive_time_when(tp) - elapsed;
- else
- elapsed = 0;
+ elapsed = keepalive_time_when(tp) - elapsed;
}
+ TCP_CHECK_TIMER(sk);
+
resched:
tcp_reset_keepalive_timer (sk, elapsed);
goto out;
death:
- tcp_set_state(sk, TCP_CLOSE);
- tcp_clear_xmit_timers(sk);
tcp_done(sk);
out:
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 9ace56abd..c052d2eb8 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -5,7 +5,7 @@
*
* The User Datagram Protocol (UDP).
*
- * Version: $Id: udp.c,v 1.77 2000/01/09 02:19:44 davem Exp $
+ * Version: $Id: udp.c,v 1.79 2000/01/18 08:24:20 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -369,30 +369,15 @@ void udp_err(struct sk_buff *skb, unsigned char *dp, int len)
}
/*
- * Various people wanted BSD UDP semantics. Well they've come
- * back out because they slow down response to stuff like dead
- * or unreachable name servers and they screw term users something
- * chronic. Oh and it violates RFC1122. So basically fix your
- * client code people.
- */
-
- /*
* RFC1122: OK. Passes ICMP errors back to application, as per
- * 4.1.3.3. After the comment above, that should be no surprise.
- */
-
- if (!harderr && !sk->protinfo.af_inet.recverr)
- goto out;
-
- /*
- * 4.x BSD compatibility item. Break RFC1122 to
- * get BSD socket semantics.
+ * 4.1.3.3.
*/
- if(sk->bsdism && sk->state!=TCP_ESTABLISHED && !sk->protinfo.af_inet.recverr)
- goto out;
-
- if (sk->protinfo.af_inet.recverr)
+ if (!sk->protinfo.af_inet.recverr) {
+ if (!harderr || sk->state != TCP_ESTABLISHED)
+ goto out;
+ } else {
ip_icmp_error(sk, skb, err, uh->dest, info, (u8*)(uh+1));
+ }
sk->err = err;
sk->error_report(sk);
out:
@@ -629,15 +614,13 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
{
switch(cmd)
{
- case TIOCOUTQ:
+ case SIOCOUTQ:
{
- unsigned long amount;
-
- amount = sock_wspace(sk);
+ int amount = atomic_read(&sk->wmem_alloc);
return put_user(amount, (int *)arg);
}
- case TIOCINQ:
+ case SIOCINQ:
{
struct sk_buff *skb;
unsigned long amount;
@@ -663,6 +646,17 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
return(0);
}
+static __inline__ int __udp_checksum_complete(struct sk_buff *skb)
+{
+ return (unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum));
+}
+
+static __inline__ int udp_checksum_complete(struct sk_buff *skb)
+{
+ return skb->ip_summed != CHECKSUM_UNNECESSARY &&
+ __udp_checksum_complete(skb);
+}
+
/*
* This should be easy, if there is something there we
* return it, otherwise we block.
@@ -699,31 +693,21 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, int len,
msg->msg_flags |= MSG_TRUNC;
}
-#ifndef CONFIG_UDP_DELAY_CSUM
- err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
- copied);
-#else
if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
copied);
- } else if (copied > msg->msg_iov[0].iov_len || (msg->msg_flags&MSG_TRUNC)) {
- if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum)))
+ } else if (msg->msg_flags&MSG_TRUNC) {
+ if (__udp_checksum_complete(skb))
goto csum_copy_err;
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
copied);
} else {
- unsigned int csum;
+ err = copy_and_csum_toiovec(msg->msg_iov, skb, sizeof(struct udphdr));
- err = 0;
- csum = csum_partial(skb->h.raw, sizeof(struct udphdr), skb->csum);
- csum = csum_and_copy_to_user((char*)&skb->h.uh[1], msg->msg_iov[0].iov_base,
- copied, csum, &err);
if (err)
- goto out_free;
- if ((unsigned short)csum_fold(csum))
goto csum_copy_err;
}
-#endif
+
if (err)
goto out_free;
sk->stamp=skb->stamp;
@@ -744,7 +728,6 @@ out_free:
out:
return err;
-#ifdef CONFIG_UDP_DELAY_CSUM
csum_copy_err:
UDP_INC_STATS_BH(UdpInErrors);
@@ -768,7 +751,6 @@ csum_copy_err:
* as some normal condition.
*/
return (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
-#endif
}
int udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
@@ -831,9 +813,9 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
* Charge it to the socket, dropping if the queue is full.
*/
-#if defined(CONFIG_FILTER) && defined(CONFIG_UDP_DELAY_CSUM)
+#if defined(CONFIG_FILTER)
if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
- if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum))) {
+ if (__udp_checksum_complete(skb)) {
UDP_INC_STATS_BH(UdpInErrors);
IP_INC_STATS_BH(IpInDiscards);
ip_statistics[smp_processor_id()*2].IpInDelivers--;
@@ -855,12 +837,6 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
return 0;
}
-
-static inline void udp_deliver(struct sock *sk, struct sk_buff *skb)
-{
- udp_queue_rcv_skb(sk, skb);
-}
-
/*
* Multicasts and broadcasts go to each listener.
*
@@ -889,7 +865,7 @@ static int udp_v4_mcast_deliver(struct sk_buff *skb, struct udphdr *uh,
skb1 = skb_clone(skb, GFP_ATOMIC);
if(skb1)
- udp_deliver(sk, skb1);
+ udp_queue_rcv_skb(sk, skb1);
sk = sknext;
} while(sknext);
} else
@@ -898,30 +874,25 @@ static int udp_v4_mcast_deliver(struct sk_buff *skb, struct udphdr *uh,
return 0;
}
-static int udp_checksum_verify(struct sk_buff *skb, struct udphdr *uh,
- unsigned short ulen, u32 saddr, u32 daddr,
- int full_csum_deferred)
+/* Initialize UDP checksum. If exited with zero value (success),
+ * CHECKSUM_UNNECESSARY means, that no more checks are required.
+ * Otherwise, csum completion requires chacksumming packet body,
+ * including udp header and folding it to skb->csum.
+ */
+static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
+ unsigned short ulen, u32 saddr, u32 daddr)
{
- if (!full_csum_deferred) {
- if (uh->check) {
- if (skb->ip_summed == CHECKSUM_HW &&
- udp_check(uh, ulen, saddr, daddr, skb->csum))
- return -1;
- if (skb->ip_summed == CHECKSUM_NONE &&
- udp_check(uh, ulen, saddr, daddr,
- csum_partial((char *)uh, ulen, 0)))
- return -1;
- }
- } else {
- if (uh->check == 0)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else if (skb->ip_summed == CHECKSUM_HW) {
- if (udp_check(uh, ulen, saddr, daddr, skb->csum))
- return -1;
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- } else if (skb->ip_summed != CHECKSUM_UNNECESSARY)
- skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
- }
+ if (uh->check == 0) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else if (skb->ip_summed == CHECKSUM_HW) {
+ if (udp_check(uh, ulen, saddr, daddr, skb->csum))
+ return -1;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else if (skb->ip_summed != CHECKSUM_UNNECESSARY)
+ skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
+ /* Probably, we should checksum udp header (it should be in cache
+ * in any case) and data in tiny packets (< rx copybreak).
+ */
return 0;
}
@@ -961,50 +932,33 @@ int udp_rcv(struct sk_buff *skb, unsigned short len)
}
skb_trim(skb, ulen);
- if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) {
- int defer;
+ if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0)
+ goto csum_error;
-#ifdef CONFIG_UDP_DELAY_CSUM
- defer = 1;
-#else
- defer = 0;
-#endif
- if (udp_checksum_verify(skb, uh, ulen, saddr, daddr, defer))
- goto csum_error;
+ if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
return udp_v4_mcast_deliver(skb, uh, saddr, daddr);
- }
sk = udp_v4_lookup(saddr, uh->source, daddr, uh->dest, skb->dev->ifindex);
-
- if (sk == NULL) {
- /* No socket. Drop packet silently, if checksum is wrong */
- if (udp_checksum_verify(skb, uh, ulen, saddr, daddr, 0))
- goto csum_error;
-
- UDP_INC_STATS_BH(UdpNoPorts);
- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
- /*
- * Hmm. We got an UDP packet to a port to which we
- * don't wanna listen. Ignore it.
- */
- kfree_skb(skb);
- return(0);
- }
- if (udp_checksum_verify(skb, uh, ulen, saddr, daddr,
-#ifdef CONFIG_UDP_DELAY_CSUM
- 1
-#else
- (sk->no_check & UDP_CSUM_NORCV) != 0
-#endif
- )) {
+ if (sk != NULL) {
+ udp_queue_rcv_skb(sk, skb);
sock_put(sk);
- goto csum_error;
+ return 0;
}
- udp_deliver(sk, skb);
- __sock_put(sk);
- return 0;
+ /* No socket. Drop packet silently, if checksum is wrong */
+ if (udp_checksum_complete(skb))
+ goto csum_error;
+
+ UDP_INC_STATS_BH(UdpNoPorts);
+ icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+
+ /*
+ * Hmm. We got an UDP packet to a port to which we
+ * don't wanna listen. Ignore it.
+ */
+ kfree_skb(skb);
+ return(0);
csum_error:
/*
@@ -1090,10 +1044,6 @@ struct proto udp_prot = {
udp_connect, /* connect */
udp_disconnect, /* disconnect */
NULL, /* accept */
- NULL, /* retransmit */
- NULL, /* write_wakeup */
- NULL, /* read_wakeup */
- datagram_poll, /* poll */
udp_ioctl, /* ioctl */
NULL, /* init */
NULL, /* destroy */
@@ -1107,7 +1057,5 @@ struct proto udp_prot = {
udp_v4_hash, /* hash */
udp_v4_unhash, /* unhash */
udp_v4_get_port, /* good_socknum */
- 128, /* max_header */
- 0, /* retransmits */
"UDP", /* name */
};
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 8430729e5..11a435ab3 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -6,7 +6,7 @@
* Pedro Roque <roque@di.fc.ul.pt>
* Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
*
- * $Id: addrconf.c,v 1.55 1999/12/15 22:39:40 davem Exp $
+ * $Id: addrconf.c,v 1.57 2000/01/18 08:24:21 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -682,6 +682,23 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
}
return -1;
}
+
+static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev)
+{
+ int err = -1;
+ struct inet6_ifaddr *ifp;
+
+ read_lock_bh(&idev->lock);
+ for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
+ if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) {
+ memcpy(eui, ifp->addr.s6_addr+8, 8);
+ err = 0;
+ break;
+ }
+ }
+ read_unlock_bh(&idev->lock);
+ return err;
+}
#endif
/*
@@ -859,7 +876,8 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
#ifdef CONFIG_IPV6_EUI64
if (pinfo->prefix_len == 64) {
memcpy(&addr, &pinfo->prefix, 8);
- if (ipv6_generate_eui64(addr.s6_addr + 8, dev)) {
+ if (ipv6_generate_eui64(addr.s6_addr + 8, dev) &&
+ ipv6_inherit_eui64(addr.s6_addr + 8, in6_dev)) {
in6_dev_put(in6_dev);
return;
}
@@ -1519,7 +1537,7 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
*/
if (ifp->idev->cnf.forwarding == 0 &&
- (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) == 0 &&
+ (dev->flags&IFF_LOOPBACK) == 0 &&
(ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
struct in6_addr all_routers;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 68badee52..a8d396ba3 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -7,7 +7,7 @@
*
* Adapted from linux/net/ipv4/af_inet.c
*
- * $Id: af_inet6.c,v 1.49 1999/12/15 22:39:43 davem Exp $
+ * $Id: af_inet6.c,v 1.52 2000/01/18 08:24:21 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -85,13 +85,17 @@ extern void ipv6_sysctl_register(void);
extern void ipv6_sysctl_unregister(void);
#endif
+#ifdef INET_REFCNT_DEBUG
atomic_t inet6_sock_nr;
+#endif
static void inet6_sock_destruct(struct sock *sk)
{
inet_sock_destruct(sk);
+#ifdef INET_REFCNT_DEBUG
atomic_dec(&inet6_sock_nr);
+#endif
MOD_DEC_USE_COUNT;
}
@@ -140,9 +144,6 @@ static int inet6_create(struct socket *sock, int protocol)
sk->prot = prot;
sk->backlog_rcv = prot->backlog_rcv;
- sk->timer.data = (unsigned long)sk;
- sk->timer.function = &tcp_keepalive_timer;
-
sk->net_pinfo.af_inet6.hop_limit = -1;
sk->net_pinfo.af_inet6.mcast_hops = -1;
sk->net_pinfo.af_inet6.mc_loop = 1;
@@ -158,8 +159,16 @@ static int inet6_create(struct socket *sock, int protocol)
sk->protinfo.af_inet.mc_index = 0;
sk->protinfo.af_inet.mc_list = NULL;
+ if (ipv4_config.no_pmtu_disc)
+ sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT;
+ else
+ sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;
+
+
+#ifdef INET_REFCNT_DEBUG
atomic_inc(&inet6_sock_nr);
atomic_inc(&inet_sock_nr);
+#endif
MOD_INC_USE_COUNT;
if (sk->type==SOCK_RAW && protocol==IPPROTO_RAW)
@@ -421,7 +430,7 @@ struct proto_ops inet6_stream_ops = {
sock_no_socketpair, /* a do nothing */
inet_accept, /* ok */
inet6_getname,
- inet_poll, /* ok */
+ tcp_poll, /* ok */
inet6_ioctl, /* must change */
inet_listen, /* ok */
inet_shutdown, /* ok */
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index cfa18eee8..f1c211532 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -5,7 +5,7 @@
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: icmp.c,v 1.25 2000/01/09 02:19:54 davem Exp $
+ * $Id: icmp.c,v 1.26 2000/01/19 04:06:19 davem Exp $
*
* Based on net/ipv4/icmp.c
*
@@ -146,19 +146,19 @@ static int icmpv6_getfrag(const void *data, struct in6_addr *saddr,
*/
if (offset) {
- csum = csum_partial_copy((void *) msg->data +
- offset - sizeof(struct icmp6hdr),
- buff, len, msg->csum);
+ csum = csum_partial_copy_nocheck((void *) msg->data +
+ offset - sizeof(struct icmp6hdr),
+ buff, len, msg->csum);
msg->csum = csum;
return 0;
}
- csum = csum_partial_copy((void *) &msg->icmph, buff,
- sizeof(struct icmp6hdr), msg->csum);
+ csum = csum_partial_copy_nocheck((void *) &msg->icmph, buff,
+ sizeof(struct icmp6hdr), msg->csum);
- csum = csum_partial_copy((void *) msg->data,
- buff + sizeof(struct icmp6hdr),
- len - sizeof(struct icmp6hdr), csum);
+ csum = csum_partial_copy_nocheck((void *) msg->data,
+ buff + sizeof(struct icmp6hdr),
+ len - sizeof(struct icmp6hdr), csum);
icmph = (struct icmp6hdr *) buff;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 099953e53..d458adc93 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -5,7 +5,7 @@
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: ip6_fib.c,v 1.19 1999/08/31 07:04:00 davem Exp $
+ * $Id: ip6_fib.c,v 1.20 2000/01/16 05:11:37 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -926,8 +926,8 @@ int fib6_del(struct rt6_info *rt)
#if RT6_DEBUG >= 2
if (rt->u.dst.obsolete>0) {
- BUG_TRAP(rt->u.dst.obsolete<=0);
- return -EFAULT;
+ BUG_TRAP(fn==NULL || rt->u.dst.obsolete<=0);
+ return -ENOENT;
}
#endif
if (fn == NULL || rt == &ip6_null_entry)
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index eddf935a0..873d22c3d 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -7,7 +7,7 @@
*
* Based on linux/net/ipv4/ip_sockglue.c
*
- * $Id: ipv6_sockglue.c,v 1.30 2000/01/09 02:19:49 davem Exp $
+ * $Id: ipv6_sockglue.c,v 1.31 2000/01/16 05:11:38 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -192,7 +192,9 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
kfree_skb(pktopt);
sk->destruct = inet_sock_destruct;
+#ifdef INET_REFCNT_DEBUG
atomic_dec(&inet6_sock_nr);
+#endif
MOD_DEC_USE_COUNT;
retv = 0;
break;
@@ -271,7 +273,7 @@ update:
if (sk->type == SOCK_STREAM) {
if (opt) {
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
- if ((tcp_connected(sk->state) || sk->state == TCP_SYN_SENT)
+ if (!((1<<sk->state)&(TCPF_LISTEN|TCPF_CLOSE))
&& sk->daddr != LOOPBACK4_IPV6) {
tp->ext_header_len = opt->opt_flen + opt->opt_nflen;
tcp_sync_mss(sk, tp->pmtu_cookie);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index ce9f17adc..412b0b5e6 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -5,7 +5,7 @@
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: mcast.c,v 1.28 2000/01/09 02:19:50 davem Exp $
+ * $Id: mcast.c,v 1.29 2000/01/18 08:24:21 davem Exp $
*
* Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c
*
@@ -500,7 +500,8 @@ void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
if (dev->hard_header) {
unsigned char ha[MAX_ADDR_LEN];
ndisc_mc_map(snd_addr, ha, dev, 1);
- dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, full_len);
+ if (dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, full_len) < 0)
+ goto out;
}
if (ipv6_get_lladdr(dev, &addr_buf)) {
@@ -508,7 +509,7 @@ void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
printk(KERN_DEBUG "igmp6: %s no linklocal address\n",
dev->name);
#endif
- return;
+ goto out;
}
ip6_nd_hdr(sk, skb, dev, &addr_buf, snd_addr, NEXTHDR_HOP, payload_len);
@@ -532,6 +533,10 @@ void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
else
ICMP6_INC_STATS(Icmp6OutGroupMembResponses);
ICMP6_INC_STATS(Icmp6OutMsgs);
+ return;
+
+out:
+ kfree_skb(skb);
}
static void igmp6_join_group(struct ifmcaddr6 *ma)
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 04ecdea9c..574bc165c 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -7,7 +7,7 @@
*
* Adapted from linux/net/ipv4/raw.c
*
- * $Id: raw.c,v 1.31 2000/01/09 02:19:50 davem Exp $
+ * $Id: raw.c,v 1.33 2000/01/18 08:24:22 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -763,10 +763,6 @@ struct proto rawv6_prot = {
udpv6_connect, /* connect */
udp_disconnect, /* disconnect */
NULL, /* accept */
- NULL, /* retransmit */
- NULL, /* write_wakeup */
- NULL, /* read_wakeup */
- datagram_poll, /* poll */
NULL, /* ioctl */
rawv6_init_sk, /* init */
inet6_destroy_sock, /* destroy */
@@ -780,7 +776,5 @@ struct proto rawv6_prot = {
raw_v6_hash, /* hash */
raw_v6_unhash, /* unhash */
NULL, /* get_port */
- 128, /* max_header */
- 0, /* retransmits */
"RAW", /* name */
};
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 668f61bfb..dc6020c33 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -5,7 +5,7 @@
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: route.c,v 1.44 2000/01/09 02:19:51 davem Exp $
+ * $Id: route.c,v 1.45 2000/01/16 05:11:38 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -93,7 +93,7 @@ struct dst_ops ip6_dst_ops = {
struct rt6_info ip6_null_entry = {
{{NULL, ATOMIC_INIT(1), 1, &loopback_dev,
- -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-ENETUNREACH, NULL, NULL,
ip6_pkt_discard, ip6_pkt_discard,
#ifdef CONFIG_NET_CLS_ROUTE
@@ -296,6 +296,7 @@ static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr,
rt->rt6i_dst.plen = 128;
rt->rt6i_flags |= RTF_CACHE;
+ rt->u.dst.flags |= DST_HOST;
#ifdef CONFIG_IPV6_SUBTREES
if (rt->rt6i_src.plen && saddr) {
@@ -687,6 +688,8 @@ int ip6_route_add(struct in6_rtmsg *rtmsg)
ipv6_addr_copy(&rt->rt6i_dst.addr, &rtmsg->rtmsg_dst);
rt->rt6i_dst.plen = rtmsg->rtmsg_dst_len;
+ if (rt->rt6i_dst.plen == 128)
+ rt->u.dst.flags = DST_HOST;
ipv6_wash_prefix(&rt->rt6i_dst.addr, rt->rt6i_dst.plen);
#ifdef CONFIG_IPV6_SUBTREES
@@ -940,6 +943,7 @@ source_ok:
ipv6_addr_copy(&nrt->rt6i_dst.addr, dest);
nrt->rt6i_dst.plen = 128;
+ nrt->u.dst.flags |= DST_HOST;
ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key);
nrt->rt6i_nexthop = neigh_clone(neigh);
@@ -1025,6 +1029,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
goto out;
ipv6_addr_copy(&nrt->rt6i_dst.addr, daddr);
nrt->rt6i_dst.plen = 128;
+ nrt->u.dst.flags |= DST_HOST;
nrt->rt6i_nexthop = neigh_clone(rt->rt6i_nexthop);
dst_set_expires(&rt->u.dst, ip6_rt_mtu_expires);
nrt->rt6i_flags |= RTF_DYNAMIC|RTF_CACHE|RTF_EXPIRES;
@@ -1045,7 +1050,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
struct rt6_info *rt;
rt = dst_alloc(&ip6_dst_ops);
-
+
if (rt) {
rt->u.dst.input = ort->u.dst.input;
rt->u.dst.output = ort->u.dst.output;
@@ -1193,7 +1198,8 @@ int ip6_rt_addr_add(struct in6_addr *addr, struct net_device *dev)
rt = dst_alloc(&ip6_dst_ops);
if (rt == NULL)
return -ENOMEM;
-
+
+ rt->u.dst.flags = DST_HOST;
rt->u.dst.input = ip6_input;
rt->u.dst.output = ip6_output;
rt->rt6i_dev = dev_get_by_name("lo");
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index e87ef0c3e..420b81f4a 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -5,7 +5,7 @@
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: tcp_ipv6.c,v 1.116 2000/01/09 02:19:52 davem Exp $
+ * $Id: tcp_ipv6.c,v 1.118 2000/01/18 08:24:22 davem Exp $
*
* Based on:
* linux/net/ipv4/tcp.c
@@ -46,11 +46,6 @@
#include <asm/uaccess.h>
-extern int sysctl_max_syn_backlog;
-extern int sysctl_tcp_tw_recycle;
-extern __u32 sysctl_wmem_max;
-extern __u32 sysctl_rmem_max;
-
static void tcp_v6_send_reset(struct sk_buff *skb);
static void tcp_v6_or_send_ack(struct sk_buff *skb, struct open_request *req);
static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len,
@@ -58,11 +53,6 @@ static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len,
static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
static int tcp_v6_xmit(struct sk_buff *skb);
-static struct open_request *tcp_v6_search_req(struct tcp_opt *tp,
- struct ipv6hdr *ip6h,
- struct tcphdr *th,
- int iif,
- struct open_request **prevp);
static struct tcp_func ipv6_mapped;
static struct tcp_func ipv6_specific;
@@ -282,9 +272,10 @@ static struct sock *tcp_v6_lookup_listener(struct in6_addr *daddr, unsigned shor
*
* The sockhash lock must be held as a reader here.
*/
-static inline struct sock *__tcp_v6_lookup(struct in6_addr *saddr, u16 sport,
- struct in6_addr *daddr, u16 hnum,
- int dif)
+
+static inline struct sock *__tcp_v6_lookup_established(struct in6_addr *saddr, u16 sport,
+ struct in6_addr *daddr, u16 hnum,
+ int dif)
{
struct tcp_ehash_bucket *head;
struct sock *sk;
@@ -314,8 +305,7 @@ static inline struct sock *__tcp_v6_lookup(struct in6_addr *saddr, u16 sport,
}
}
read_unlock(&head->lock);
-
- return tcp_v6_lookup_listener(daddr, hnum, dif);
+ return NULL;
hit:
sock_hold(sk);
@@ -323,6 +313,21 @@ hit:
return sk;
}
+
+static inline struct sock *__tcp_v6_lookup(struct in6_addr *saddr, u16 sport,
+ struct in6_addr *daddr, u16 hnum,
+ int dif)
+{
+ struct sock *sk;
+
+ sk = __tcp_v6_lookup_established(saddr, sport, daddr, hnum, dif);
+
+ if (sk)
+ return sk;
+
+ return tcp_v6_lookup_listener(daddr, hnum, dif);
+}
+
#define tcp_v6_lookup(sa, sp, da, dp, dif) \
({ struct sock *___sk; \
local_bh_disable(); \
@@ -331,6 +336,46 @@ hit:
___sk; \
})
+
+/*
+ * Open request hash tables.
+ */
+
+static __inline__ unsigned tcp_v6_synq_hash(struct in6_addr *raddr, u16 rport)
+{
+ unsigned h = raddr->s6_addr32[3] ^ rport;
+ h ^= h>>16;
+ h ^= h>>8;
+ return h&(TCP_SYNQ_HSIZE-1);
+}
+
+static struct open_request *tcp_v6_search_req(struct tcp_opt *tp,
+ struct ipv6hdr *ip6h,
+ struct tcphdr *th,
+ int iif,
+ struct open_request ***prevp)
+{
+ struct tcp_listen_opt *lopt = tp->listen_opt;
+ struct open_request *req, **prev;
+ __u16 rport = th->source;
+
+ for (prev = &lopt->syn_table[tcp_v6_synq_hash(&ip6h->saddr, rport)];
+ (req = *prev) != NULL;
+ prev = &req->dl_next) {
+ if (req->rmt_port == rport &&
+ req->class->family == AF_INET6 &&
+ !ipv6_addr_cmp(&req->af.v6_req.rmt_addr, &ip6h->saddr) &&
+ !ipv6_addr_cmp(&req->af.v6_req.loc_addr, &ip6h->daddr) &&
+ (!req->af.v6_req.iif || req->af.v6_req.iif == iif)) {
+ BUG_TRAP(req->sk == NULL);
+ *prevp = prev;
+ return req;
+ }
+ }
+
+ return NULL;
+}
+
static __inline__ u16 tcp_v6_check(struct tcphdr *th, int len,
struct in6_addr *saddr,
struct in6_addr *daddr,
@@ -375,10 +420,10 @@ static int tcp_v6_check_established(struct sock *sk)
!ipv6_addr_cmp(&tw->v6_daddr, saddr) &&
!ipv6_addr_cmp(&tw->v6_rcv_saddr, daddr) &&
sk2->bound_dev_if == sk->bound_dev_if) {
-#ifdef CONFIG_TCP_TW_RECYCLE
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
- if (sysctl_tcp_tw_recycle && tw->ts_recent_stamp) {
+ if (tw->substate == TCP_TIME_WAIT &&
+ sysctl_tcp_tw_recycle && tw->ts_recent_stamp) {
/* See comment in tcp_ipv4.c */
if ((tp->write_seq = tw->snd_nxt + 2) == 0)
tp->write_seq = 1;
@@ -388,8 +433,7 @@ static int tcp_v6_check_established(struct sock *sk)
skp = &head->chain;
goto unique;
} else
-#endif
- goto not_unique;
+ goto not_unique;
}
}
tw = NULL;
@@ -399,9 +443,7 @@ static int tcp_v6_check_established(struct sock *sk)
goto not_unique;
}
-#ifdef CONFIG_TCP_TW_RECYCLE
unique:
-#endif
BUG_TRAP(sk->pprev==NULL);
if ((sk->next = *skp) != NULL)
(*skp)->pprev = &sk->next;
@@ -411,17 +453,16 @@ unique:
sock_prot_inc_use(sk->prot);
write_unlock_bh(&head->lock);
-#ifdef CONFIG_TCP_TW_RECYCLE
if (tw) {
/* Silly. Should hash-dance instead... */
local_bh_disable();
tcp_tw_deschedule(tw);
tcp_timewait_kill(tw);
+ NET_INC_STATS_BH(TimeWaitRecycled);
local_bh_enable();
tcp_tw_put(tw);
}
-#endif
return 0;
not_unique:
@@ -467,9 +508,6 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
int addr_type;
int err;
- if (sk->state != TCP_CLOSE)
- return(-EISCONN);
-
if (addr_len < sizeof(struct sockaddr_in6))
return(-EINVAL);
@@ -501,18 +539,11 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
if(addr_type & IPV6_ADDR_MULTICAST)
return -ENETUNREACH;
- /* We may need to bind the socket. */
- if (sk->num==0 && sk->prot->get_port(sk, 0))
- return -EAGAIN;
- sk->sport = htons(sk->num);
-
-#ifdef CONFIG_TCP_TW_RECYCLE
if (tp->ts_recent_stamp && ipv6_addr_cmp(&np->daddr, &usin->sin6_addr)) {
tp->ts_recent = 0;
tp->ts_recent_stamp = 0;
tp->write_seq = 0;
}
-#endif
ipv6_addr_copy(&np->daddr, &usin->sin6_addr);
np->flow_label = fl.fl6_flowlabel;
@@ -602,8 +633,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
tp->mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
err = -ENOBUFS;
- buff = sock_wmalloc(sk, (MAX_HEADER + sk->prot->max_header),
- 0, GFP_KERNEL);
+ buff = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 0, GFP_KERNEL);
if (buff == NULL)
goto failure;
@@ -629,46 +659,6 @@ failure:
return err;
}
-static int tcp_v6_sendmsg(struct sock *sk, struct msghdr *msg, int len)
-{
- struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
- int retval = -EINVAL;
-
- lock_sock(sk);
- /*
- * Do sanity checking for sendmsg/sendto/send
- */
-
- if (msg->msg_flags & ~(MSG_OOB|MSG_DONTROUTE|MSG_DONTWAIT|MSG_NOSIGNAL))
- goto out;
- if (msg->msg_name) {
- struct sockaddr_in6 *addr=(struct sockaddr_in6 *)msg->msg_name;
-
- if (msg->msg_namelen < sizeof(*addr))
- goto out;
-
- if (addr->sin6_family && addr->sin6_family != AF_INET6)
- goto out;
- retval = -ENOTCONN;
-
- if(sk->state == TCP_CLOSE)
- goto out;
- retval = -EISCONN;
- if (addr->sin6_port != sk->dport)
- goto out;
- if (ipv6_addr_cmp(&addr->sin6_addr, &np->daddr))
- goto out;
- if (np->sndflow && np->flow_label != (addr->sin6_flowinfo&IPV6_FLOWINFO_MASK))
- goto out;
- }
-
- retval = tcp_do_sendmsg(sk, msg);
-
-out:
- release_sock(sk);
- return retval;
-}
-
void tcp_v6_err(struct sk_buff *skb, struct ipv6hdr *hdr,
struct inet6_skb_parm *opt,
int type, int code, unsigned char *header, __u32 info)
@@ -701,6 +691,9 @@ void tcp_v6_err(struct sk_buff *skb, struct ipv6hdr *hdr,
if (sk->lock.users)
NET_INC_STATS_BH(LockDroppedIcmps);
+ if (sk->state == TCP_CLOSE)
+ goto out;
+
tp = &sk->tp_pinfo.af_tcp;
seq = ntohl(th->seq);
if (sk->state != TCP_LISTEN && !between(seq, tp->snd_una, tp->snd_nxt)) {
@@ -719,7 +712,7 @@ void tcp_v6_err(struct sk_buff *skb, struct ipv6hdr *hdr,
goto out;
/* icmp should have updated the destination cache entry */
- dst = sk_dst_check(sk, np->dst_cookie);
+ dst = __sk_dst_check(sk, np->dst_cookie);
if (dst == NULL) {
struct flowi fl;
@@ -736,7 +729,8 @@ void tcp_v6_err(struct sk_buff *skb, struct ipv6hdr *hdr,
fl.uli_u.ports.sport = sk->sport;
dst = ip6_route_output(sk, &fl);
- }
+ } else
+ dst_clone(dst);
if (dst->error) {
sk->err_soft = -dst->error;
@@ -752,7 +746,7 @@ void tcp_v6_err(struct sk_buff *skb, struct ipv6hdr *hdr,
/* Might be for an open_request */
switch (sk->state) {
- struct open_request *req, *prev;
+ struct open_request *req, **prev;
struct ipv6hdr hd;
case TCP_LISTEN:
if (sk->lock.users)
@@ -765,35 +759,19 @@ void tcp_v6_err(struct sk_buff *skb, struct ipv6hdr *hdr,
if (!req)
goto out;
- if (req->sk) {
- struct sock *nsk = req->sk;
-
- sock_hold(nsk);
- bh_unlock_sock(sk);
- sock_put(sk);
- sk = nsk;
-
- BUG_TRAP(sk->lock.users==0);
-
- tp = &sk->tp_pinfo.af_tcp;
- if (!between(seq, tp->snd_una, tp->snd_nxt)) {
- NET_INC_STATS_BH(OutOfWindowIcmps);
- goto out;
- }
- } else {
- if (seq != req->snt_isn) {
- NET_INC_STATS_BH(OutOfWindowIcmps);
- goto out;
- }
+ /* ICMPs are not backlogged, hence we cannot get
+ * an established socket here.
+ */
+ BUG_TRAP(req->sk == NULL);
- tp->syn_backlog--;
- tcp_synq_unlink(tp, req, prev);
- tcp_dec_slow_timer(TCP_SLT_SYNACK);
- req->class->destructor(req);
- tcp_openreq_free(req);
+ if (seq != req->snt_isn) {
+ NET_INC_STATS_BH(OutOfWindowIcmps);
goto out;
}
- break;
+
+ tcp_synq_drop(sk, req, prev);
+ goto out;
+
case TCP_SYN_SENT:
case TCP_SYN_RECV: /* Cannot happen.
It can, it SYNs are crossed. --ANK */
@@ -802,7 +780,6 @@ void tcp_v6_err(struct sk_buff *skb, struct ipv6hdr *hdr,
sk->err = err;
sk->error_report(sk); /* Wake people up to see the error (see connect in sock.c) */
- tcp_set_state(sk, TCP_CLOSE);
tcp_done(sk);
} else {
sk->err_soft = err;
@@ -823,12 +800,13 @@ out:
}
-static void tcp_v6_send_synack(struct sock *sk, struct open_request *req)
+static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
+ struct dst_entry *dst)
{
struct sk_buff * skb;
- struct dst_entry *dst;
struct ipv6_txoptions *opt = NULL;
struct flowi fl;
+ int err = -1;
fl.proto = IPPROTO_TCP;
fl.nl_u.ip6_u.daddr = &req->af.v6_req.rmt_addr;
@@ -838,24 +816,26 @@ static void tcp_v6_send_synack(struct sock *sk, struct open_request *req)
fl.uli_u.ports.dport = req->rmt_port;
fl.uli_u.ports.sport = sk->sport;
- opt = sk->net_pinfo.af_inet6.opt;
- if (opt == NULL &&
- sk->net_pinfo.af_inet6.rxopt.bits.srcrt == 2 &&
- req->af.v6_req.pktopts) {
- struct sk_buff *pktopts = req->af.v6_req.pktopts;
- struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)pktopts->cb;
- if (rxopt->srcrt)
- opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt));
- }
+ if (dst == NULL) {
+ opt = sk->net_pinfo.af_inet6.opt;
+ if (opt == NULL &&
+ sk->net_pinfo.af_inet6.rxopt.bits.srcrt == 2 &&
+ req->af.v6_req.pktopts) {
+ struct sk_buff *pktopts = req->af.v6_req.pktopts;
+ struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)pktopts->cb;
+ if (rxopt->srcrt)
+ opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt));
+ }
- if (opt && opt->srcrt) {
- struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
- fl.nl_u.ip6_u.daddr = rt0->addr;
- }
+ if (opt && opt->srcrt) {
+ struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
+ fl.nl_u.ip6_u.daddr = rt0->addr;
+ }
- dst = ip6_route_output(sk, &fl);
- if (dst->error)
- goto done;
+ dst = ip6_route_output(sk, &fl);
+ if (dst->error)
+ goto done;
+ }
skb = tcp_make_synack(sk, dst, req);
if (skb) {
@@ -866,21 +846,22 @@ static void tcp_v6_send_synack(struct sock *sk, struct open_request *req)
csum_partial((char *)th, skb->len, skb->csum));
fl.nl_u.ip6_u.daddr = &req->af.v6_req.rmt_addr;
- ip6_xmit(sk, skb, &fl, opt);
+ err = ip6_xmit(sk, skb, &fl, opt);
+ if (err == NET_XMIT_CN)
+ err = 0;
}
done:
dst_release(dst);
if (opt && opt != sk->net_pinfo.af_inet6.opt)
sock_kfree_s(sk, opt, opt->tot_len);
+ return err;
}
static void tcp_v6_or_free(struct open_request *req)
{
- if (req->af.v6_req.pktopts) {
+ if (req->af.v6_req.pktopts)
kfree_skb(req->af.v6_req.pktopts);
- req->af.v6_req.pktopts = NULL;
- }
}
static struct or_calltable or_ipv6 = {
@@ -907,8 +888,224 @@ static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
}
-#define BACKLOG(sk) ((sk)->tp_pinfo.af_tcp.syn_backlog) /* lvalue! */
-#define BACKLOGMAX(sk) sysctl_max_syn_backlog
+static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len,
+ struct sk_buff *skb)
+{
+ struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
+ th->check = 0;
+
+ th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP,
+ csum_partial((char *)th, th->doff<<2,
+ skb->csum));
+}
+
+
+static void tcp_v6_send_reset(struct sk_buff *skb)
+{
+ struct tcphdr *th = skb->h.th, *t1;
+ struct sk_buff *buff;
+ struct flowi fl;
+
+ if (th->rst)
+ return;
+
+ if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
+ return;
+
+ /*
+ * We need to grab some memory, and put together an RST,
+ * and then put it into the queue to be sent.
+ */
+
+ buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr), GFP_ATOMIC);
+ if (buff == NULL)
+ return;
+
+ skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr));
+
+ t1 = (struct tcphdr *) skb_push(buff,sizeof(struct tcphdr));
+
+ /* Swap the send and the receive. */
+ memset(t1, 0, sizeof(*t1));
+ t1->dest = th->source;
+ t1->source = th->dest;
+ t1->doff = sizeof(*t1)/4;
+ t1->rst = 1;
+
+ if(th->ack) {
+ t1->seq = th->ack_seq;
+ } else {
+ t1->ack = 1;
+ t1->ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin
+ + skb->len - (th->doff<<2));
+ }
+
+ buff->csum = csum_partial((char *)t1, sizeof(*t1), 0);
+
+ fl.nl_u.ip6_u.daddr = &skb->nh.ipv6h->saddr;
+ fl.nl_u.ip6_u.saddr = &skb->nh.ipv6h->daddr;
+ fl.fl6_flowlabel = 0;
+
+ t1->check = csum_ipv6_magic(fl.nl_u.ip6_u.saddr,
+ fl.nl_u.ip6_u.daddr,
+ sizeof(*t1), IPPROTO_TCP,
+ buff->csum);
+
+ fl.proto = IPPROTO_TCP;
+ fl.oif = tcp_v6_iif(skb);
+ fl.uli_u.ports.dport = t1->dest;
+ fl.uli_u.ports.sport = t1->source;
+
+ /* sk = NULL, but it is safe for now. RST socket required. */
+ buff->dst = ip6_route_output(NULL, &fl);
+
+ if (buff->dst->error == 0) {
+ ip6_xmit(NULL, buff, &fl, NULL);
+ TCP_INC_STATS_BH(TcpOutSegs);
+ TCP_INC_STATS_BH(TcpOutRsts);
+ return;
+ }
+
+ kfree_skb(buff);
+}
+
+static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts)
+{
+ struct tcphdr *th = skb->h.th, *t1;
+ struct sk_buff *buff;
+ struct flowi fl;
+ int tot_len = sizeof(struct tcphdr);
+
+ buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr), GFP_ATOMIC);
+ if (buff == NULL)
+ return;
+
+ skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr));
+
+ if (ts)
+ tot_len += 3*4;
+
+ t1 = (struct tcphdr *) skb_push(buff,tot_len);
+
+ /* Swap the send and the receive. */
+ memset(t1, 0, sizeof(*t1));
+ t1->dest = th->source;
+ t1->source = th->dest;
+ t1->doff = tot_len/4;
+ t1->seq = htonl(seq);
+ t1->ack_seq = htonl(ack);
+ t1->ack = 1;
+ t1->window = htons(win);
+
+ if (ts) {
+ u32 *ptr = (u32*)(t1 + 1);
+ *ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
+ (TCPOPT_NOP << 16) |
+ (TCPOPT_TIMESTAMP << 8) |
+ TCPOLEN_TIMESTAMP);
+ *ptr++ = htonl(tcp_time_stamp);
+ *ptr = htonl(ts);
+ }
+
+ buff->csum = csum_partial((char *)t1, tot_len, 0);
+
+ fl.nl_u.ip6_u.daddr = &skb->nh.ipv6h->saddr;
+ fl.nl_u.ip6_u.saddr = &skb->nh.ipv6h->daddr;
+ fl.fl6_flowlabel = 0;
+
+ t1->check = csum_ipv6_magic(fl.nl_u.ip6_u.saddr,
+ fl.nl_u.ip6_u.daddr,
+ tot_len, IPPROTO_TCP,
+ buff->csum);
+
+ fl.proto = IPPROTO_TCP;
+ fl.oif = tcp_v6_iif(skb);
+ fl.uli_u.ports.dport = t1->dest;
+ fl.uli_u.ports.sport = t1->source;
+
+ buff->dst = ip6_route_output(NULL, &fl);
+
+ if (buff->dst->error == 0) {
+ ip6_xmit(NULL, buff, &fl, NULL);
+ TCP_INC_STATS_BH(TcpOutSegs);
+ return;
+ }
+
+ kfree_skb(buff);
+}
+
+static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
+{
+ struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk;
+
+ tcp_v6_send_ack(skb, tw->snd_nxt, tw->rcv_nxt,
+ tw->rcv_wnd>>tw->rcv_wscale, tw->ts_recent);
+
+ tcp_tw_put(tw);
+}
+
+static void tcp_v6_or_send_ack(struct sk_buff *skb, struct open_request *req)
+{
+ tcp_v6_send_ack(skb, req->snt_isn+1, req->rcv_isn+1, req->rcv_wnd, req->ts_recent);
+}
+
+
+static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
+{
+ struct open_request *req, **prev;
+ struct tcphdr *th = skb->h.th;
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+
+ /* Find possible connection requests. */
+ req = tcp_v6_search_req(tp, skb->nh.ipv6h, th, tcp_v6_iif(skb), &prev);
+ if (req)
+ return tcp_check_req(sk, skb, req, prev);
+
+ if (tp->accept_queue) {
+ struct sock *nsk;
+
+ nsk = __tcp_v6_lookup_established(&skb->nh.ipv6h->saddr,
+ th->source,
+ &skb->nh.ipv6h->daddr,
+ ntohs(th->dest),
+ tcp_v6_iif(skb));
+
+ if (nsk) {
+ if (nsk->state != TCP_TIME_WAIT) {
+ bh_lock_sock(nsk);
+ return nsk;
+ }
+ tcp_tw_put((struct tcp_tw_bucket*)sk);
+ return NULL;
+ }
+ }
+
+#if 0 /*def CONFIG_SYN_COOKIES*/
+ if (!th->rst && (th->syn || th->ack))
+ sk = cookie_v6_check(sk, skb, &(IPCB(skb)->opt));
+#endif
+ return sk;
+}
+
+static void tcp_v6_synq_add(struct sock *sk, struct open_request *req)
+{
+ struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
+ struct tcp_listen_opt *lopt = tp->listen_opt;
+ unsigned h = tcp_v6_synq_hash(&req->af.v6_req.rmt_addr, req->rmt_port);
+
+ req->sk = NULL;
+ req->expires = jiffies + TCP_TIMEOUT_INIT;
+ req->retrans = 0;
+ req->index = h;
+ req->dl_next = lopt->syn_table[h];
+
+ write_lock(&tp->syn_wait_lock);
+ lopt->syn_table[h] = req;
+ write_unlock(&tp->syn_wait_lock);
+
+ tcp_synq_added(sk);
+}
+
/* FIXME: this is substantially similar to the ipv4 code.
* Can some kind of merge be done? -- erics
@@ -916,7 +1113,7 @@ static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
{
struct tcp_opt tp;
- struct open_request *req;
+ struct open_request *req = NULL;
__u32 isn = TCP_SKB_CB(skb)->when;
if (skb->protocol == __constant_htons(ETH_P_IP))
@@ -926,44 +1123,31 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
goto drop;
- if (isn == 0)
- isn = tcp_v6_init_sequence(sk,skb);
-
/*
* There are no SYN attacks on IPv6, yet...
*/
- if (BACKLOG(sk) >= BACKLOGMAX(sk)) {
- (void)(net_ratelimit() &&
- printk(KERN_INFO "droping syn ack:%d max:%d\n",
- BACKLOG(sk), BACKLOGMAX(sk)));
+ if (tcp_synq_is_full(sk) && !isn) {
+ if (net_ratelimit())
+ printk(KERN_INFO "TCPv6: dropping request, synflood is possible\n");
goto drop;
}
- req = tcp_openreq_alloc();
- if (req == NULL) {
+ if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
goto drop;
- }
-
- BACKLOG(sk)++;
- req->rcv_wnd = 0; /* So that tcp_send_synack() knows! */
+ req = tcp_openreq_alloc();
+ if (req == NULL)
+ goto drop;
- req->rcv_isn = TCP_SKB_CB(skb)->seq;
- req->snt_isn = isn;
tp.tstamp_ok = tp.sack_ok = tp.wscale_ok = tp.snd_wscale = 0;
-
tp.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
tp.user_mss = sk->tp_pinfo.af_tcp.user_mss;
tcp_parse_options(NULL, skb->h.th, &tp, 0);
- req->mss = tp.mss_clamp;
- req->ts_recent = tp.saw_tstamp ? tp.rcv_tsval : 0;
- req->tstamp_ok = tp.tstamp_ok;
- req->sack_ok = tp.sack_ok;
- req->snd_wscale = tp.snd_wscale;
- req->wscale_ok = tp.wscale_ok;
- req->rmt_port = skb->h.th->source;
+ tcp_openreq_init(req, &tp, skb);
+
+ req->class = &or_ipv6;
ipv6_addr_copy(&req->af.v6_req.rmt_addr, &skb->nh.ipv6h->saddr);
ipv6_addr_copy(&req->af.v6_req.loc_addr, &skb->nh.ipv6h->daddr);
req->af.v6_req.pktopts = NULL;
@@ -979,34 +1163,26 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
if (!sk->bound_dev_if && ipv6_addr_type(&req->af.v6_req.rmt_addr)&IPV6_ADDR_LINKLOCAL)
req->af.v6_req.iif = tcp_v6_iif(skb);
- req->class = &or_ipv6;
- req->retrans = 0;
- req->sk = NULL;
+ if (isn == 0)
+ isn = tcp_v6_init_sequence(sk,skb);
- tcp_v6_send_synack(sk, req);
+ req->snt_isn = isn;
- req->expires = jiffies + TCP_TIMEOUT_INIT;
- tcp_inc_slow_timer(TCP_SLT_SYNACK);
- tcp_synq_queue(&sk->tp_pinfo.af_tcp, req);
+ if (tcp_v6_send_synack(sk, req, NULL))
+ goto drop;
+
+ tcp_v6_synq_add(sk, req);
return 0;
drop:
+ if (req)
+ tcp_openreq_free(req);
+
TCP_INC_STATS_BH(TcpAttemptFails);
return 0; /* don't send reset */
}
-static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len,
- struct sk_buff *skb)
-{
- struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
- th->check = 0;
-
- th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP,
- csum_partial((char *)th, th->doff<<2,
- skb->csum));
-}
-
static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
struct open_request *req,
struct dst_entry *dst)
@@ -1047,7 +1223,9 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
/* Charge newly allocated IPv6 socket. Though it is mapped,
* it is IPv6 yet.
*/
+#ifdef INET_REFCNT_DEBUG
atomic_inc(&inet6_sock_nr);
+#endif
MOD_INC_USE_COUNT;
/* It is tricky place. Until this moment IPv4 tcp
@@ -1061,8 +1239,8 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
opt = sk->net_pinfo.af_inet6.opt;
- if (sk->ack_backlog > sk->max_ack_backlog)
- goto out;
+ if (tcp_acceptq_is_full(sk))
+ goto out_overflow;
if (sk->net_pinfo.af_inet6.rxopt.bits.srcrt == 2 &&
opt == NULL && req->af.v6_req.pktopts) {
@@ -1090,15 +1268,14 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
if (dst->error)
goto out;
- sk->tp_pinfo.af_tcp.syn_backlog--;
- sk->ack_backlog++;
-
newsk = tcp_create_openreq_child(sk, req, skb);
if (newsk == NULL)
goto out;
/* Charge newly allocated IPv6 socket */
+#ifdef INET_REFCNT_DEBUG
atomic_inc(&inet6_sock_nr);
+#endif
MOD_INC_USE_COUNT;
ip6_dst_store(newsk, dst, NULL);
@@ -1124,6 +1301,8 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
np->pktoptions = NULL;
if (req->af.v6_req.pktopts) {
np->pktoptions = skb_clone(req->af.v6_req.pktopts, GFP_ATOMIC);
+ kfree_skb(req->af.v6_req.pktopts);
+ req->af.v6_req.pktopts = NULL;
if (np->pktoptions)
skb_set_owner_r(np->pktoptions, newsk);
}
@@ -1149,250 +1328,49 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
tcp_sync_mss(newsk, dst->pmtu);
tcp_initialize_rcv_mss(newsk);
+ newtp->advmss = dst->advmss;
- if (newsk->rcvbuf < (3 * (dst->advmss+60+MAX_HEADER+15)))
- newsk->rcvbuf = min ((3 * (dst->advmss+60+MAX_HEADER+15)), sysctl_rmem_max);
- if (newsk->sndbuf < (3 * (newtp->mss_clamp+60+MAX_HEADER+15)))
- newsk->sndbuf = min ((3 * (newtp->mss_clamp+60+MAX_HEADER+15)), sysctl_wmem_max);
+ tcp_init_buffer_space(newsk);
newsk->daddr = LOOPBACK4_IPV6;
newsk->saddr = LOOPBACK4_IPV6;
newsk->rcv_saddr= LOOPBACK4_IPV6;
- bh_lock_sock(newsk);
-
__tcp_v6_hash(newsk);
tcp_inherit_port(sk, newsk);
return newsk;
+out_overflow:
+ NET_INC_STATS_BH(ListenOverflows);
out:
+ NET_INC_STATS_BH(ListenDrops);
if (opt && opt != sk->net_pinfo.af_inet6.opt)
sock_kfree_s(sk, opt, opt->tot_len);
dst_release(dst);
return NULL;
}
-static void tcp_v6_send_reset(struct sk_buff *skb)
-{
- struct tcphdr *th = skb->h.th, *t1;
- struct sk_buff *buff;
- struct flowi fl;
-
- if (th->rst)
- return;
-
- if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
- return;
-
- /*
- * We need to grab some memory, and put together an RST,
- * and then put it into the queue to be sent.
- */
-
- buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr), GFP_ATOMIC);
- if (buff == NULL)
- return;
-
- skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr));
-
- t1 = (struct tcphdr *) skb_push(buff,sizeof(struct tcphdr));
-
- /* Swap the send and the receive. */
- memset(t1, 0, sizeof(*t1));
- t1->dest = th->source;
- t1->source = th->dest;
- t1->doff = sizeof(*t1)/4;
- t1->rst = 1;
-
- if(th->ack) {
- t1->seq = th->ack_seq;
- } else {
- t1->ack = 1;
- t1->ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin
- + skb->len - (th->doff<<2));
- }
-
- buff->csum = csum_partial((char *)t1, sizeof(*t1), 0);
-
- fl.nl_u.ip6_u.daddr = &skb->nh.ipv6h->saddr;
- fl.nl_u.ip6_u.saddr = &skb->nh.ipv6h->daddr;
- fl.fl6_flowlabel = 0;
-
- t1->check = csum_ipv6_magic(fl.nl_u.ip6_u.saddr,
- fl.nl_u.ip6_u.daddr,
- sizeof(*t1), IPPROTO_TCP,
- buff->csum);
-
- fl.proto = IPPROTO_TCP;
- fl.oif = tcp_v6_iif(skb);
- fl.uli_u.ports.dport = t1->dest;
- fl.uli_u.ports.sport = t1->source;
-
- /* sk = NULL, but it is safe for now. RST socket required. */
- buff->dst = ip6_route_output(NULL, &fl);
-
- if (buff->dst->error == 0) {
- ip6_xmit(NULL, buff, &fl, NULL);
- TCP_INC_STATS_BH(TcpOutSegs);
- TCP_INC_STATS_BH(TcpOutRsts);
- return;
- }
-
- kfree_skb(buff);
-}
-
-static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts)
-{
- struct tcphdr *th = skb->h.th, *t1;
- struct sk_buff *buff;
- struct flowi fl;
- int tot_len = sizeof(struct tcphdr);
-
- buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr), GFP_ATOMIC);
- if (buff == NULL)
- return;
-
- skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr));
-
- if (ts)
- tot_len += 3*4;
-
- t1 = (struct tcphdr *) skb_push(buff,tot_len);
-
- /* Swap the send and the receive. */
- memset(t1, 0, sizeof(*t1));
- t1->dest = th->source;
- t1->source = th->dest;
- t1->doff = tot_len/4;
- t1->seq = htonl(seq);
- t1->ack_seq = htonl(ack);
- t1->ack = 1;
- t1->window = htons(win);
-
- if (ts) {
- u32 *ptr = (u32*)(t1 + 1);
- *ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
- (TCPOPT_NOP << 16) |
- (TCPOPT_TIMESTAMP << 8) |
- TCPOLEN_TIMESTAMP);
- *ptr++ = htonl(tcp_time_stamp);
- *ptr = htonl(ts);
- }
-
- buff->csum = csum_partial((char *)t1, tot_len, 0);
-
- fl.nl_u.ip6_u.daddr = &skb->nh.ipv6h->saddr;
- fl.nl_u.ip6_u.saddr = &skb->nh.ipv6h->daddr;
- fl.fl6_flowlabel = 0;
-
- t1->check = csum_ipv6_magic(fl.nl_u.ip6_u.saddr,
- fl.nl_u.ip6_u.daddr,
- tot_len, IPPROTO_TCP,
- buff->csum);
-
- fl.proto = IPPROTO_TCP;
- fl.oif = tcp_v6_iif(skb);
- fl.uli_u.ports.dport = t1->dest;
- fl.uli_u.ports.sport = t1->source;
-
- buff->dst = ip6_route_output(NULL, &fl);
-
- if (buff->dst->error == 0) {
- ip6_xmit(NULL, buff, &fl, NULL);
- TCP_INC_STATS_BH(TcpOutSegs);
- return;
- }
-
- kfree_skb(buff);
-}
-
-static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
-{
- struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sk;
-
- tcp_v6_send_ack(skb, tw->snd_nxt, tw->rcv_nxt, 0, tw->ts_recent);
-
- tcp_tw_put(tw);
-}
-
-static void tcp_v6_or_send_ack(struct sk_buff *skb, struct open_request *req)
-{
- tcp_v6_send_ack(skb, req->snt_isn+1, req->rcv_isn+1, req->rcv_wnd, req->ts_recent);
-}
-
-static struct open_request *tcp_v6_search_req(struct tcp_opt *tp,
- struct ipv6hdr *ip6h,
- struct tcphdr *th,
- int iif,
- struct open_request **prevp)
+static int tcp_v6_checksum_init(struct sk_buff *skb)
{
- struct open_request *req, *prev;
- __u16 rport = th->source;
-
- /* assumption: the socket is not in use.
- * as we checked the user count on tcp_rcv and we're
- * running from a soft interrupt.
- */
- prev = (struct open_request *) (&tp->syn_wait_queue);
- for (req = prev->dl_next; req; req = req->dl_next) {
- if (req->rmt_port == rport &&
- req->class->family == AF_INET6 &&
- !ipv6_addr_cmp(&req->af.v6_req.rmt_addr, &ip6h->saddr) &&
- !ipv6_addr_cmp(&req->af.v6_req.loc_addr, &ip6h->daddr) &&
- (!req->af.v6_req.iif || req->af.v6_req.iif == iif)) {
- if (req->sk) {
- bh_lock_sock(req->sk);
- BUG_TRAP(req->sk->lock.users==0);
- if (req->sk->state == TCP_CLOSE) {
- bh_unlock_sock(req->sk);
- prev = req;
- continue;
- }
- }
- *prevp = prev;
- return req;
- }
- prev = req;
- }
- return NULL;
-}
-
-
-static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
-{
- struct open_request *req, *prev;
- struct tcphdr *th = skb->h.th;
- struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-
- /* Find possible connection requests. */
- req = tcp_v6_search_req(tp, skb->nh.ipv6h, th, tcp_v6_iif(skb), &prev);
- if (req)
- return tcp_check_req(sk, skb, req, prev);
-
-#if 0 /*def CONFIG_SYN_COOKIES*/
- if (!th->rst && (th->syn || th->ack))
- sk = cookie_v6_check(sk, skb, &(IPCB(skb)->opt));
-#endif
- return sk;
-}
-
-
-static int tcp_v6_csum_verify(struct sk_buff *skb)
-{
- switch (skb->ip_summed) {
- case CHECKSUM_NONE:
- skb->csum = csum_partial((char *)skb->h.th, skb->len, 0);
- case CHECKSUM_HW:
+ if (skb->ip_summed == CHECKSUM_HW) {
if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
&skb->nh.ipv6h->daddr,skb->csum)) {
- printk(KERN_DEBUG "tcp v6 csum failed\n");
- return 1;
+ NETDEBUG(printk(KERN_DEBUG "hw tcp v6 csum failed\n"));
+ return -1;
}
skb->ip_summed = CHECKSUM_UNNECESSARY;
- default:
- /* CHECKSUM_UNNECESSARY */
- };
+ } else if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
+ if (skb->len <= 68) {
+ if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
+ &skb->nh.ipv6h->daddr,csum_partial((char *)skb->h.th, skb->len, 0)))
+ return -1;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else {
+ skb->csum = ~tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
+ &skb->nh.ipv6h->daddr,0);
+ }
+ }
return 0;
}
@@ -1435,13 +1413,6 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
IP6_INC_STATS_BH(Ip6InDelivers);
- /*
- * This doesn't check if the socket has enough room for the packet.
- * Either process the packet _without_ queueing it and then free it,
- * or do the check later.
- */
- skb_set_owner_r(skb, sk);
-
/* Do Stevens' IPV6_PKTOPTIONS.
Yes, guys, it is the only place in our code, where we
@@ -1461,23 +1432,20 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
}
if (sk->state == TCP_ESTABLISHED) { /* Fast path */
- /* Ready to move deeper ... */
- if (tcp_v6_csum_verify(skb))
- goto csum_err;
+ TCP_CHECK_TIMER(sk);
if (tcp_rcv_established(sk, skb, skb->h.th, skb->len))
goto reset;
+ TCP_CHECK_TIMER(sk);
if (users)
goto ipv6_pktoptions;
return 0;
}
- if (tcp_v6_csum_verify(skb))
+ if (tcp_checksum_complete(skb))
goto csum_err;
if (sk->state == TCP_LISTEN) {
- struct sock *nsk;
-
- nsk = tcp_v6_hnd_req(sk, skb);
+ struct sock *nsk = tcp_v6_hnd_req(sk, skb);
if (!nsk)
goto discard;
@@ -1486,21 +1454,8 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
* otherwise we just shortcircuit this and continue with
* the new socket..
*/
- if(nsk != sk) {
- int ret;
- int state = nsk->state;
-
- skb_orphan(skb);
- BUG_TRAP(nsk->lock.users == 0);
- skb_set_owner_r(skb, nsk);
- ret = tcp_rcv_state_process(nsk, skb, skb->h.th, skb->len);
-
- /* Wakeup parent, send SIGIO */
- if (state == TCP_SYN_RECV && nsk->state != state)
- sk->data_ready(sk, 0);
- bh_unlock_sock(nsk);
-
- if (ret)
+ if(nsk != sk) {
+ if (tcp_child_process(sk, nsk, skb))
goto reset;
if (users)
kfree_skb(skb);
@@ -1508,8 +1463,10 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
}
}
+ TCP_CHECK_TIMER(sk);
if (tcp_rcv_state_process(sk, skb, skb->h.th, skb->len))
goto reset;
+ TCP_CHECK_TIMER(sk);
if (users)
goto ipv6_pktoptions;
return 0;
@@ -1588,6 +1545,9 @@ int tcp_v6_rcv(struct sk_buff *skb, unsigned long len)
if (len < sizeof(struct tcphdr))
goto bad_packet;
+ if (tcp_v6_checksum_init(skb) < 0)
+ goto bad_packet;
+
TCP_SKB_CB(skb)->seq = ntohl(th->seq);
TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
len - th->doff*4);
@@ -1608,9 +1568,10 @@ process:
bh_lock_sock(sk);
ret = 0;
- if (!sk->lock.users)
- ret = tcp_v6_do_rcv(sk, skb);
- else
+ if (!sk->lock.users) {
+ if (!tcp_prequeue(sk, skb))
+ ret = tcp_v6_do_rcv(sk, skb);
+ } else
sk_add_backlog(sk, skb);
bh_unlock_sock(sk);
@@ -1618,7 +1579,7 @@ process:
return ret;
no_tcp_socket:
- if (tcp_v6_csum_verify(skb)) {
+ if (tcp_checksum_complete(skb)) {
bad_packet:
TCP_INC_STATS_BH(TcpInErrs);
} else {
@@ -1639,7 +1600,7 @@ discard_and_relse:
goto discard_it;
do_time_wait:
- if (tcp_v6_csum_verify(skb)) {
+ if (tcp_checksum_complete(skb)) {
TCP_INC_STATS_BH(TcpInErrs);
sock_put(sk);
goto discard_it;
@@ -1677,7 +1638,7 @@ static int tcp_v6_rebuild_header(struct sock *sk)
struct dst_entry *dst;
struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
- dst = sk_dst_check(sk, np->dst_cookie);
+ dst = __sk_dst_check(sk, np->dst_cookie);
if (dst == NULL) {
struct flowi fl;
@@ -1704,12 +1665,9 @@ static int tcp_v6_rebuild_header(struct sock *sk)
}
ip6_dst_store(sk, dst, NULL);
- return 0;
}
- err = dst->error;
- dst_release(dst);
- return err;
+ return 0;
}
static int tcp_v6_xmit(struct sk_buff *skb)
@@ -1732,7 +1690,7 @@ static int tcp_v6_xmit(struct sk_buff *skb)
fl.nl_u.ip6_u.daddr = rt0->addr;
}
- dst = sk_dst_check(sk, np->dst_cookie);
+ dst = __sk_dst_check(sk, np->dst_cookie);
if (dst == NULL) {
dst = ip6_route_output(sk, &fl);
@@ -1743,11 +1701,10 @@ static int tcp_v6_xmit(struct sk_buff *skb)
return -sk->err_soft;
}
- dst_clone(dst);
ip6_dst_store(sk, dst, NULL);
}
- skb->dst = dst;
+ skb->dst = dst_clone(dst);
/* Restore final destination back after routing done */
fl.nl_u.ip6_u.daddr = &np->daddr;
@@ -1767,6 +1724,12 @@ static void v6_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
sin6->sin6_flowinfo = 0;
}
+static int tcp_v6_remember_stamp(struct sock *sk)
+{
+ /* Alas, not yet... */
+ return 0;
+}
+
static struct tcp_func ipv6_specific = {
tcp_v6_xmit,
tcp_v6_send_check,
@@ -1774,6 +1737,7 @@ static struct tcp_func ipv6_specific = {
tcp_v6_conn_request,
tcp_v6_syn_recv_sock,
tcp_v6_hash_connecting,
+ tcp_v6_remember_stamp,
sizeof(struct ipv6hdr),
ipv6_setsockopt,
@@ -1793,6 +1757,7 @@ static struct tcp_func ipv6_mapped = {
tcp_v6_conn_request,
tcp_v6_syn_recv_sock,
tcp_v4_hash_connecting,
+ tcp_v4_remember_stamp,
sizeof(struct iphdr),
ipv6_setsockopt,
@@ -1812,6 +1777,7 @@ static int tcp_v6_init_sock(struct sock *sk)
skb_queue_head_init(&tp->out_of_order_queue);
tcp_init_xmit_timers(sk);
+ tcp_prequeue_init(tp);
tp->rto = TCP_TIMEOUT_INIT;
tp->mdev = TCP_TIMEOUT_INIT;
@@ -1826,16 +1792,11 @@ static int tcp_v6_init_sock(struct sock *sk)
/* See draft-stevens-tcpca-spec-01 for discussion of the
* initialization of these values.
*/
- tp->snd_cwnd_cnt = 0;
tp->snd_ssthresh = 0x7fffffff;
tp->snd_cwnd_clamp = ~0;
tp->mss_cache = 536;
sk->state = TCP_CLOSE;
- sk->max_ack_backlog = SOMAXCONN;
-
- /* Init SYN queue. */
- tcp_synq_init(tp);
sk->tp_pinfo.af_tcp.af_specific = &ipv6_specific;
@@ -1847,27 +1808,19 @@ static int tcp_v6_init_sock(struct sock *sk)
static int tcp_v6_destroy_sock(struct sock *sk)
{
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
- struct sk_buff *skb;
tcp_clear_xmit_timers(sk);
- /*
- * Cleanup up the write buffer.
- */
-
- while((skb = __skb_dequeue(&sk->write_queue)) != NULL)
- kfree_skb(skb);
+ /* Cleanup up the write buffer. */
+ __skb_queue_purge(&sk->write_queue);
- /*
- * Cleans up our, hopefuly empty, out_of_order_queue
- */
+ /* Cleans up our, hopefuly empty, out_of_order_queue. */
+ __skb_queue_purge(&tp->out_of_order_queue);
- while((skb = __skb_dequeue(&tp->out_of_order_queue)) != NULL)
- kfree_skb(skb);
+ /* Clean prequeue, it must be empty really */
+ __skb_queue_purge(&tp->ucopy.prequeue);
- /* Clean up a locked TCP bind bucket, this only happens if a
- * port is allocated for a socket, but it never fully connects.
- */
+ /* Clean up a referenced TCP bind bucket. */
if(sk->prev != NULL)
tcp_put_port(sk);
@@ -1878,12 +1831,16 @@ static int tcp_v6_destroy_sock(struct sock *sk)
static void get_openreq6(struct sock *sk, struct open_request *req, char *tmpbuf, int i)
{
struct in6_addr *dest, *src;
+ int ttd = req->expires - jiffies;
+
+ if (ttd < 0)
+ ttd = 0;
src = &req->af.v6_req.loc_addr;
dest = &req->af.v6_req.rmt_addr;
sprintf(tmpbuf,
"%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
- "%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p",
+ "%02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p",
i,
src->s6_addr32[0], src->s6_addr32[1],
src->s6_addr32[2], src->s6_addr32[3],
@@ -1894,7 +1851,7 @@ static void get_openreq6(struct sock *sk, struct open_request *req, char *tmpbuf
TCP_SYN_RECV,
0,0, /* could print option size, but that is af dependent. */
1, /* timers active (only the expire timer) */
- (unsigned long)(req->expires - jiffies),
+ ttd,
req->retrans,
sk->socket ? sk->socket->inode->i_uid : 0,
0, /* non standard timer */
@@ -1906,7 +1863,7 @@ static void get_tcp6_sock(struct sock *sp, char *tmpbuf, int i)
{
struct in6_addr *dest, *src;
__u16 destp, srcp;
- int timer_active, timer_active1, timer_active2;
+ int timer_active;
unsigned long timer_expires;
struct tcp_opt *tp = &sp->tp_pinfo.af_tcp;
@@ -1914,15 +1871,16 @@ static void get_tcp6_sock(struct sock *sp, char *tmpbuf, int i)
src = &sp->net_pinfo.af_inet6.rcv_saddr;
destp = ntohs(sp->dport);
srcp = ntohs(sp->sport);
- timer_active1 = tp->retransmit_timer.prev != NULL;
- timer_active2 = sp->timer.prev != NULL;
timer_active = 0;
timer_expires = (unsigned) -1;
- if (timer_active1 && tp->retransmit_timer.expires < timer_expires) {
+ if (tp->retransmit_timer.prev != NULL && tp->retransmit_timer.expires < timer_expires) {
timer_active = 1;
timer_expires = tp->retransmit_timer.expires;
+ } else if (tp->probe_timer.prev != NULL && tp->probe_timer.expires < timer_expires) {
+ timer_active = 4;
+ timer_expires = tp->probe_timer.expires;
}
- if (timer_active2 && sp->timer.expires < timer_expires) {
+ if (sp->timer.prev != NULL && sp->timer.expires < timer_expires) {
timer_active = 2;
timer_expires = sp->timer.expires;
}
@@ -1931,7 +1889,7 @@ static void get_tcp6_sock(struct sock *sp, char *tmpbuf, int i)
sprintf(tmpbuf,
"%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
- "%02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p",
+ "%02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p %u %u %u %u",
i,
src->s6_addr32[0], src->s6_addr32[1],
src->s6_addr32[2], src->s6_addr32[3], srcp,
@@ -1942,28 +1900,27 @@ static void get_tcp6_sock(struct sock *sp, char *tmpbuf, int i)
timer_active, timer_expires-jiffies,
tp->retransmits,
sp->socket ? sp->socket->inode->i_uid : 0,
- 0,
+ tp->probes_out,
sp->socket ? sp->socket->inode->i_ino : 0,
- atomic_read(&sp->refcnt), sp);
+ atomic_read(&sp->refcnt), sp,
+ tp->rto, tp->ack.ato, tp->ack.quick, tp->ack.pingpong
+ );
}
static void get_timewait6_sock(struct tcp_tw_bucket *tw, char *tmpbuf, int i)
{
struct in6_addr *dest, *src;
__u16 destp, srcp;
- int slot_dist;
+ int ttd = tw->ttd - jiffies;
+
+ if (ttd < 0)
+ ttd = 0;
dest = &tw->v6_daddr;
src = &tw->v6_rcv_saddr;
destp = ntohs(tw->dport);
srcp = ntohs(tw->sport);
- slot_dist = tw->death_slot;
- if(slot_dist > tcp_tw_death_row_slot)
- slot_dist = (TCP_TWKILL_SLOTS - slot_dist) + tcp_tw_death_row_slot;
- else
- slot_dist = tcp_tw_death_row_slot - slot_dist;
-
sprintf(tmpbuf,
"%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
"%02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p",
@@ -1972,8 +1929,8 @@ static void get_timewait6_sock(struct tcp_tw_bucket *tw, char *tmpbuf, int i)
src->s6_addr32[2], src->s6_addr32[3], srcp,
dest->s6_addr32[0], dest->s6_addr32[1],
dest->s6_addr32[2], dest->s6_addr32[3], destp,
- TCP_TIME_WAIT, 0, 0,
- 3, slot_dist * TCP_TWKILL_PERIOD, 0, 0, 0, 0,
+ tw->substate, 0, 0,
+ 3, ttd, 0, 0, 0, 0,
atomic_read(&tw->refcnt), tw);
}
@@ -2002,6 +1959,8 @@ int tcp6_get_info(char *buffer, char **start, off_t offset, int length)
tcp_listen_lock();
for(i = 0; i < TCP_LHTABLE_SIZE; i++) {
struct sock *sk = tcp_listening_hash[i];
+ struct tcp_listen_opt *lopt;
+ int k;
for (sk = tcp_listening_hash[i]; sk; sk = sk->next, num++) {
struct open_request *req;
@@ -2019,24 +1978,29 @@ int tcp6_get_info(char *buffer, char **start, off_t offset, int length)
}
}
- lock_sock(sk);
- for (req = tp->syn_wait_queue; req; req = req->dl_next, num++) {
- if (req->sk)
- continue;
- if (req->class->family != PF_INET6)
- continue;
- pos += LINE_LEN+1;
- if (pos < offset)
- continue;
- get_openreq6(sk, req, tmpbuf, num);
- len += sprintf(buffer+len, LINE_FMT, tmpbuf);
- if(len >= length) {
- release_sock(sk);
- tcp_listen_unlock();
- goto out_no_bh;
+ read_lock_bh(&tp->syn_wait_lock);
+ lopt = tp->listen_opt;
+ if (lopt && lopt->qlen != 0) {
+ for (k=0; k<TCP_SYNQ_HSIZE; k++) {
+ for (req = lopt->syn_table[k]; req; req = req->dl_next, num++) {
+ if (req->class->family != PF_INET6)
+ continue;
+ pos += LINE_LEN+1;
+ if (pos < offset)
+ continue;
+ get_openreq6(sk, req, tmpbuf, num);
+ len += sprintf(buffer+len, LINE_FMT, tmpbuf);
+ if(len >= length) {
+ read_unlock_bh(&tp->syn_wait_lock);
+ tcp_listen_unlock();
+ goto out_no_bh;
+ }
+ }
}
}
- release_sock(sk);
+ read_unlock_bh(&tp->syn_wait_lock);
+
+ /* Completed requests are in normal socket hash table */
}
}
tcp_listen_unlock();
@@ -2100,25 +2064,19 @@ struct proto tcpv6_prot = {
tcp_v6_connect, /* connect */
tcp_disconnect, /* disconnect */
tcp_accept, /* accept */
- NULL, /* retransmit */
- tcp_write_wakeup, /* write_wakeup */
- tcp_read_wakeup, /* read_wakeup */
- tcp_poll, /* poll */
tcp_ioctl, /* ioctl */
tcp_v6_init_sock, /* init */
tcp_v6_destroy_sock, /* destroy */
tcp_shutdown, /* shutdown */
tcp_setsockopt, /* setsockopt */
tcp_getsockopt, /* getsockopt */
- tcp_v6_sendmsg, /* sendmsg */
+ tcp_sendmsg, /* sendmsg */
tcp_recvmsg, /* recvmsg */
NULL, /* bind */
tcp_v6_do_rcv, /* backlog_rcv */
tcp_v6_hash, /* hash */
tcp_unhash, /* unhash */
tcp_v6_get_port, /* get_port */
- 128, /* max_header */
- 0, /* retransmits */
"TCPv6", /* name */
};
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 3ecc55030..a5984354b 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -7,7 +7,7 @@
*
* Based on linux/ipv4/udp.c
*
- * $Id: udp.c,v 1.48 2000/01/09 02:19:53 davem Exp $
+ * $Id: udp.c,v 1.50 2000/01/18 08:24:24 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -366,54 +366,19 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, int len,
msg->msg_flags |= MSG_TRUNC;
}
-#ifndef CONFIG_UDP_DELAY_CSUM
- err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
- msg->msg_iov, copied);
-#else
if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
copied);
- } else if (copied > msg->msg_iov[0].iov_len || (msg->msg_flags&MSG_TRUNC)) {
- if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum))) {
- /* Clear queue. */
- if (flags&MSG_PEEK) {
- int clear = 0;
- spin_lock_irq(&sk->receive_queue.lock);
- if (skb == skb_peek(&sk->receive_queue)) {
- __skb_unlink(skb, &sk->receive_queue);
- clear = 1;
- }
- spin_unlock_irq(&sk->receive_queue.lock);
- if (clear)
- kfree_skb(skb);
- }
-
- /* Error for blocking case is chosen to masquerade
- as some normal condition.
- */
- err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
- udp_stats_in6.UdpInErrors++;
- goto out_free;
- }
+ } else if (msg->msg_flags&MSG_TRUNC) {
+ if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum)))
+ goto csum_copy_err;
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
copied);
} else {
- unsigned int csum = csum_partial(skb->h.raw, sizeof(struct udphdr), skb->csum);
-
- err = 0;
- csum = csum_and_copy_to_user((char*)&skb->h.uh[1], msg->msg_iov[0].iov_base, copied, csum, &err);
+ err = copy_and_csum_toiovec(msg->msg_iov, skb, sizeof(struct udphdr));
if (err)
- goto out_free;
- if ((unsigned short)csum_fold(csum)) {
- /* Error for blocking case is chosen to masquerade
- as some normal condition.
- */
- err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
- udp_stats_in6.UdpInErrors++;
- goto out_free;
- }
+ goto csum_copy_err;
}
-#endif
if (err)
goto out_free;
@@ -447,6 +412,27 @@ out_free:
skb_free_datagram(sk, skb);
out:
return err;
+
+csum_copy_err:
+ /* Clear queue. */
+ if (flags&MSG_PEEK) {
+ int clear = 0;
+ spin_lock_irq(&sk->receive_queue.lock);
+ if (skb == skb_peek(&sk->receive_queue)) {
+ __skb_unlink(skb, &sk->receive_queue);
+ clear = 1;
+ }
+ spin_unlock_irq(&sk->receive_queue.lock);
+ if (clear)
+ kfree_skb(skb);
+ }
+
+ /* Error for blocking case is chosen to masquerade
+ as some normal condition.
+ */
+ err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
+ UDP6_INC_STATS_USER(UdpInErrors);
+ goto out_free;
}
void udpv6_err(struct sk_buff *skb, struct ipv6hdr *hdr,
@@ -474,7 +460,7 @@ void udpv6_err(struct sk_buff *skb, struct ipv6hdr *hdr,
!sk->net_pinfo.af_inet6.recverr)
goto out;
- if (sk->bsdism && sk->state!=TCP_ESTABLISHED &&
+ if (sk->state!=TCP_ESTABLISHED &&
!sk->net_pinfo.af_inet6.recverr)
goto out;
@@ -489,7 +475,7 @@ out:
static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
{
-#if defined(CONFIG_FILTER) && defined(CONFIG_UDP_DELAY_CSUM)
+#if defined(CONFIG_FILTER)
if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum))) {
UDP6_INC_STATS_BH(UdpInErrors);
@@ -621,24 +607,12 @@ int udpv6_rcv(struct sk_buff *skb, unsigned long len)
skb_trim(skb, ulen);
-#ifndef CONFIG_UDP_DELAY_CSUM
- switch (skb->ip_summed) {
- case CHECKSUM_NONE:
- skb->csum = csum_partial((char*)uh, ulen, 0);
- case CHECKSUM_HW:
- if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) {
- printk(KERN_DEBUG "IPv6: udp checksum error\n");
- goto discard;
- }
- };
-#else
if (skb->ip_summed==CHECKSUM_HW) {
if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum))
goto discard;
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else if (skb->ip_summed != CHECKSUM_UNNECESSARY)
skb->csum = ~csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, 0);
-#endif
len = ulen;
@@ -651,7 +625,7 @@ int udpv6_rcv(struct sk_buff *skb, unsigned long len)
}
/* Unicast */
-
+
/*
* check socket cache ... must talk to Alan about his plans
* for sock caches... i'll skip this for now.
@@ -660,11 +634,9 @@ int udpv6_rcv(struct sk_buff *skb, unsigned long len)
sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, dev->ifindex);
if (sk == NULL) {
-#ifdef CONFIG_UDP_DELAY_CSUM
if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
(unsigned short)csum_fold(csum_partial((char*)uh, len, skb->csum)))
goto discard;
-#endif
UDP6_INC_STATS_BH(UdpNoPorts);
icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev);
@@ -672,12 +644,6 @@ int udpv6_rcv(struct sk_buff *skb, unsigned long len)
kfree_skb(skb);
return(0);
}
- if (0/*sk->user_callback &&
- sk->user_callback(sk->user_data, skb) == 0*/) {
- UDP6_INC_STATS_BH(UdpInDatagrams);
- sock_put(sk);
- return(0);
- }
/* deliver */
@@ -980,10 +946,6 @@ struct proto udpv6_prot = {
udpv6_connect, /* connect */
udp_disconnect, /* disconnect */
NULL, /* accept */
- NULL, /* retransmit */
- NULL, /* write_wakeup */
- NULL, /* read_wakeup */
- datagram_poll, /* poll */
udp_ioctl, /* ioctl */
NULL, /* init */
inet6_destroy_sock, /* destroy */
@@ -997,8 +959,6 @@ struct proto udpv6_prot = {
udp_v6_hash, /* hash */
udp_v6_unhash, /* unhash */
udp_v6_get_port, /* get_port */
- 128, /* max_header */
- 0, /* retransmits */
"UDP", /* name */
};
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 8bea0ce98..bed8c5cc2 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1522,7 +1522,7 @@ static unsigned int irda_poll(struct file * file, struct socket *sock,
* we set writable also when the other side has shut down the
* connection. This prevents stuck sockets.
*/
- if (sk->sndbuf - (int)atomic_read(&sk->wmem_alloc) >= MIN_WRITE_SPACE)
+ if (sk->sndbuf - (int)atomic_read(&sk->wmem_alloc) >= SOCK_MIN_WRITE_SPACE)
mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
return mask;
diff --git a/net/khttpd/accept.c b/net/khttpd/accept.c
index 9c1912c68..97dd21709 100644
--- a/net/khttpd/accept.c
+++ b/net/khttpd/accept.c
@@ -63,7 +63,7 @@ int AcceptConnections(const int CPUNR, struct socket *Socket)
the allocation of a new socket. (Which doesn't seem to be
used anyway)
*/
- if (Socket->sk->tp_pinfo.af_tcp.syn_wait_queue==NULL)
+ if (Socket->sk->tp_pinfo.af_tcp.accept_queue==NULL)
{
return 0;
}
diff --git a/net/khttpd/datasending.c b/net/khttpd/datasending.c
index 7a1afc1df..058b308dc 100644
--- a/net/khttpd/datasending.c
+++ b/net/khttpd/datasending.c
@@ -172,7 +172,7 @@ int DataSending(const int CPUNR)
if (CurrentRequest->sock->sk->state == TCP_ESTABLISHED ||
CurrentRequest->sock->sk->state == TCP_CLOSE_WAIT)
{
- CurrentRequest->sock->sk->nonagle = 0;
+ CurrentRequest->sock->sk->tp_pinfo.af_tcp.nonagle = 0;
tcp_push_pending_frames(CurrentRequest->sock->sk,&(CurrentRequest->sock->sk->tp_pinfo.af_tcp));
}
release_sock(CurrentRequest->sock->sk);
diff --git a/net/khttpd/sockets.c b/net/khttpd/sockets.c
index 8f8b5d250..0d575abdf 100644
--- a/net/khttpd/sockets.c
+++ b/net/khttpd/sockets.c
@@ -68,9 +68,10 @@ int StartListening(const int Port)
(void)printk(KERN_ERR " daemon is (or was a short time ago) using port %i.\n",Port);
return 0;
}
-
+
+ /* Grrr... setsockopt() does this. */
sock->sk->reuse = 1;
- sock->sk->nonagle = 0;
+ /* Wow!!! */
sock->sk->linger = 1;
/* Now, start listening on the socket */
diff --git a/net/khttpd/userspace.c b/net/khttpd/userspace.c
index 2acb27ff1..948d770fe 100644
--- a/net/khttpd/userspace.c
+++ b/net/khttpd/userspace.c
@@ -181,8 +181,7 @@ static struct or_calltable Dummy =
static int AddSocketToAcceptQueue(struct socket *sock,const int Port)
{
struct open_request *req;
- struct sock *sk;
- struct tcp_opt *tp;
+ struct sock *sk, *nsk;
EnterFunction("AddSocketToAcceptQueue");
@@ -196,8 +195,7 @@ static int AddSocketToAcceptQueue(struct socket *sock,const int Port)
lock_sock(sk);
- if (sk->state != TCP_LISTEN ||
- sk->ack_backlog > sk->max_ack_backlog) /* To many pending requests */
+ if (sk->state != TCP_LISTEN || tcp_acceptq_is_full(sk))
{
release_sock(sk);
sock_put(sk);
@@ -213,20 +211,17 @@ static int AddSocketToAcceptQueue(struct socket *sock,const int Port)
return -1;
}
- req->sk = sock->sk;
+ nsk = sock->sk;
sock->sk = NULL;
sock->state = SS_UNCONNECTED;
req->class = &Dummy;
- write_lock_irq(&req->sk->callback_lock);
- req->sk->socket = NULL;
- req->sk->sleep = NULL;
- write_unlock_irq(&req->sk->callback_lock);
-
- tp =&(sk->tp_pinfo.af_tcp);
- sk->ack_backlog++;
+ write_lock_irq(&nsk->callback_lock);
+ nsk->socket = NULL;
+ nsk->sleep = NULL;
+ write_unlock_irq(&nsk->callback_lock);
- tcp_synq_queue(tp,req);
+ tcp_acceptq_queue(sk, req, nsk);
sk->data_ready(sk, 0);
diff --git a/net/khttpd/waitheaders.c b/net/khttpd/waitheaders.c
index a7d4b82e0..47fa1581d 100644
--- a/net/khttpd/waitheaders.c
+++ b/net/khttpd/waitheaders.c
@@ -256,7 +256,7 @@ static int DecodeHeader(const int CPUNR, struct http_request *Request)
}
else /* Normal Case */
{
- Request->sock->sk->nonagle = 2; /* this is TCP_CORK */
+ Request->sock->sk->tp_pinfo.af_tcp.nonagle = 2; /* this is TCP_CORK */
if (Request->HTTPVER!=9) /* HTTP/0.9 doesn't allow a header */
SendHTTPHeader(Request);
}
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 9c472a937..0136d15c2 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -48,9 +48,9 @@
struct netlink_opt
{
- pid_t pid;
+ u32 pid;
unsigned groups;
- pid_t dst_pid;
+ u32 dst_pid;
unsigned dst_groups;
unsigned long state;
int (*handler)(int unit, struct sk_buff *skb);
@@ -95,6 +95,12 @@ static void netlink_sock_destruct(struct sock *sk)
#endif
}
+/* This lock without TASK_EXCLUSIVE is good on UP and it is _very_ bad on SMP.
+ * Look, when several writers sleep and reader wakes them up, all but one
+ * immediately hit write lock and grab all the cpus. Exclusive sleep solves
+ * this, _but_ remember, it adds useless work on UP machines.
+ */
+
static void netlink_table_grab(void)
{
write_lock_bh(&nl_table_lock);
@@ -102,9 +108,9 @@ static void netlink_table_grab(void)
if (atomic_read(&nl_table_users)) {
DECLARE_WAITQUEUE(wait, current);
- add_wait_queue(&nl_table_wait, &wait);
+ add_wait_queue_exclusive(&nl_table_wait, &wait);
for(;;) {
- set_current_state(TASK_UNINTERRUPTIBLE);
+ set_current_state(TASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE);
if (atomic_read(&nl_table_users) == 0)
break;
write_unlock_bh(&nl_table_lock);
@@ -120,6 +126,7 @@ static void netlink_table_grab(void)
static __inline__ void netlink_table_ungrab(void)
{
write_unlock_bh(&nl_table_lock);
+ wake_up(&nl_table_wait);
}
static __inline__ void
@@ -254,14 +261,9 @@ static int netlink_release(struct socket *sock)
/* OK. Socket is unlinked, and, therefore,
no new packets will arrive */
- write_lock_irq(&sk->callback_lock);
- sk->dead = 1;
- sk->socket = NULL;
+ sock_orphan(sk);
sock->sk = NULL;
- wake_up_interruptible(sk->sleep);
- sk->sleep = NULL;
- wake_up_interruptible(&sk->protinfo.af_netlink->wait);
- write_unlock_irq(&sk->callback_lock);
+ wake_up_interruptible_all(&sk->protinfo.af_netlink->wait);
skb_queue_purge(&sk->write_queue);
@@ -391,8 +393,11 @@ int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 pid, int nonblock
struct sock *sk;
int len = skb->len;
int protocol = ssk->protocol;
+ long timeo;
DECLARE_WAITQUEUE(wait, current);
+ timeo = sock_sndtimeo(ssk, nonblock);
+
retry:
sk = netlink_lookup(protocol, pid);
if (sk == NULL)
@@ -409,7 +414,7 @@ retry:
if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf ||
test_bit(0, &sk->protinfo.af_netlink->state)) {
- if (nonblock) {
+ if (!timeo) {
if (ssk->protinfo.af_netlink->pid == 0)
netlink_overrun(sk);
sock_put(sk);
@@ -422,9 +427,8 @@ retry:
if ((atomic_read(&sk->rmem_alloc) > sk->rcvbuf ||
test_bit(0, &sk->protinfo.af_netlink->state)) &&
- !signal_pending(current) &&
!sk->dead)
- schedule();
+ timeo = schedule_timeout(timeo);
__set_current_state(TASK_RUNNING);
remove_wait_queue(&sk->protinfo.af_netlink->wait, &wait);
@@ -554,9 +558,6 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, int len,
if (msg->msg_flags&MSG_OOB)
return -EOPNOTSUPP;
- if (msg->msg_flags&~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
- return -EINVAL;
-
if (msg->msg_namelen) {
if (addr->nl_family != AF_NETLINK)
return -EINVAL;
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index e23edd41b..f378632ac 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -978,7 +978,7 @@ static int nr_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct s
unsigned char *asmptr;
int size;
- if (msg->msg_flags & ~MSG_DONTWAIT)
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR))
return -EINVAL;
if (sk->zapped)
diff --git a/net/netsyms.c b/net/netsyms.c
index 9891d5cb0..993f728f8 100644
--- a/net/netsyms.c
+++ b/net/netsyms.c
@@ -61,7 +61,6 @@ extern struct net_proto_family inet_family_ops;
#include <net/ndisc.h>
#include <net/transp_v6.h>
-extern int tcp_tw_death_row_slot;
extern int sysctl_local_port_range[2];
extern int tcp_port_rover;
extern int udp_port_rover;
@@ -277,14 +276,15 @@ EXPORT_SYMBOL(inet_release);
EXPORT_SYMBOL(inet_stream_connect);
EXPORT_SYMBOL(inet_dgram_connect);
EXPORT_SYMBOL(inet_accept);
-EXPORT_SYMBOL(inet_poll);
EXPORT_SYMBOL(inet_listen);
EXPORT_SYMBOL(inet_shutdown);
EXPORT_SYMBOL(inet_setsockopt);
EXPORT_SYMBOL(inet_getsockopt);
EXPORT_SYMBOL(inet_sendmsg);
EXPORT_SYMBOL(inet_recvmsg);
+#ifdef INET_REFCNT_DEBUG
EXPORT_SYMBOL(inet_sock_nr);
+#endif
EXPORT_SYMBOL(inet_sock_destruct);
EXPORT_SYMBOL(inet_sock_release);
@@ -307,7 +307,6 @@ EXPORT_SYMBOL(ip_queue_xmit);
EXPORT_SYMBOL(memcpy_fromiovecend);
EXPORT_SYMBOL(csum_partial_copy_fromiovecend);
EXPORT_SYMBOL(copy_and_csum_toiovec);
-EXPORT_SYMBOL(tcp_keepalive_timer);
EXPORT_SYMBOL(tcp_v4_lookup_listener);
/* UDP/TCP exported functions for TCPv6 */
EXPORT_SYMBOL(udp_ioctl);
@@ -318,7 +317,6 @@ EXPORT_SYMBOL(tcp_close);
EXPORT_SYMBOL(tcp_disconnect);
EXPORT_SYMBOL(tcp_accept);
EXPORT_SYMBOL(tcp_write_wakeup);
-EXPORT_SYMBOL(tcp_read_wakeup);
EXPORT_SYMBOL(tcp_write_space);
EXPORT_SYMBOL(tcp_poll);
EXPORT_SYMBOL(tcp_ioctl);
@@ -328,19 +326,18 @@ EXPORT_SYMBOL(tcp_getsockopt);
EXPORT_SYMBOL(tcp_recvmsg);
EXPORT_SYMBOL(tcp_send_synack);
EXPORT_SYMBOL(tcp_check_req);
+EXPORT_SYMBOL(tcp_child_process);
EXPORT_SYMBOL(tcp_reset_xmit_timer);
EXPORT_SYMBOL(tcp_parse_options);
EXPORT_SYMBOL(tcp_rcv_established);
EXPORT_SYMBOL(tcp_init_xmit_timers);
EXPORT_SYMBOL(tcp_clear_xmit_timers);
-EXPORT_SYMBOL(tcp_slt_array);
-EXPORT_SYMBOL(__tcp_inc_slow_timer);
EXPORT_SYMBOL(tcp_statistics);
EXPORT_SYMBOL(tcp_rcv_state_process);
EXPORT_SYMBOL(tcp_timewait_state_process);
EXPORT_SYMBOL(tcp_timewait_cachep);
EXPORT_SYMBOL(tcp_timewait_kill);
-EXPORT_SYMBOL(tcp_do_sendmsg);
+EXPORT_SYMBOL(tcp_sendmsg);
EXPORT_SYMBOL(tcp_v4_rebuild_header);
EXPORT_SYMBOL(tcp_v4_send_check);
EXPORT_SYMBOL(tcp_v4_conn_request);
@@ -362,8 +359,9 @@ EXPORT_SYMBOL(tcp_simple_retransmit);
EXPORT_SYMBOL(tcp_transmit_skb);
EXPORT_SYMBOL(tcp_connect);
EXPORT_SYMBOL(tcp_make_synack);
-EXPORT_SYMBOL(tcp_tw_death_row_slot);
EXPORT_SYMBOL(tcp_tw_deschedule);
+EXPORT_SYMBOL(tcp_delete_keepalive_timer);
+EXPORT_SYMBOL(tcp_reset_keepalive_timer);
EXPORT_SYMBOL(sysctl_local_port_range);
EXPORT_SYMBOL(tcp_port_rover);
EXPORT_SYMBOL(udp_port_rover);
@@ -375,7 +373,12 @@ EXPORT_SYMBOL(xrlim_allow);
EXPORT_SYMBOL(tcp_write_xmit);
EXPORT_SYMBOL(dev_loopback_xmit);
+EXPORT_SYMBOL(tcp_v4_remember_stamp);
+
+extern int sysctl_tcp_tw_recycle;
+
#ifdef CONFIG_SYSCTL
+EXPORT_SYMBOL(sysctl_tcp_tw_recycle);
EXPORT_SYMBOL(sysctl_max_syn_backlog);
#endif
@@ -489,7 +492,9 @@ EXPORT_SYMBOL(eth_type_trans);
EXPORT_SYMBOL(fddi_type_trans);
EXPORT_SYMBOL(fddi_setup);
#endif /* CONFIG_FDDI */
+#if 0
EXPORT_SYMBOL(eth_copy_and_sum);
+#endif
EXPORT_SYMBOL(alloc_skb);
EXPORT_SYMBOL(__kfree_skb);
EXPORT_SYMBOL(skb_clone);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index eec4d92d7..e73adb8e2 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -5,7 +5,7 @@
*
* PACKET - implements raw packet sockets.
*
- * Version: $Id: af_packet.c,v 1.26 1999/12/20 05:20:02 davem Exp $
+ * Version: $Id: af_packet.c,v 1.28 2000/01/24 23:35:59 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -789,13 +789,8 @@ static int packet_release(struct socket *sock)
* Now the socket is dead. No more input will appear.
*/
- write_lock_irq(&sk->callback_lock);
+ sock_orphan(sk);
sock->sk = NULL;
- sk->socket = NULL;
- sk->dead = 1;
- sk->sleep = NULL;
- write_unlock_irq(&sk->callback_lock);
-
/* Purge queues */
@@ -1537,15 +1532,8 @@ static void packet_mm_close(struct vm_area_struct *vma)
}
static struct vm_operations_struct packet_mmap_ops = {
- packet_mm_open, /* open */
- packet_mm_close, /* close */
- NULL, /* unmap */
- NULL, /* no special protect */
- NULL, /* sync */
- NULL, /* advise */
- NULL, /* nopage */
- NULL, /* wppage */
- NULL /* swapout */
+ open: packet_mm_open,
+ close: packet_mm_close,
};
static void free_pg_vec(unsigned long *pg_vec, unsigned order, unsigned len)
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 0cab1224d..e43573991 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1010,7 +1010,7 @@ static int rose_sendmsg(struct socket *sock, struct msghdr *msg, int len,
unsigned char *asmptr;
int n, size, qbit = 0;
- if (msg->msg_flags & ~MSG_DONTWAIT)
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_OOB|MSG_EOR))
return -EINVAL;
if (sk->zapped)
diff --git a/net/socket.c b/net/socket.c
index 4b4bc45b9..b1a0d5400 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -176,7 +176,10 @@ static __inline__ void net_family_read_unlock(void)
* Statistics counters of the socket lists
*/
-static int sockets_in_use = 0;
+static union {
+ int counter;
+ char __pad[SMP_CACHE_BYTES];
+} sockets_in_use[NR_CPUS] __cacheline_aligned = {{0}};
/*
* Support routines. Move socket addresses back and forth across the kernel/user
@@ -261,23 +264,14 @@ static int sock_map_fd(struct socket *sock)
goto out;
}
- lock_kernel();
file->f_dentry = d_alloc_root(sock->inode);
if (!file->f_dentry) {
- unlock_kernel();
put_filp(file);
put_unused_fd(fd);
fd = -ENOMEM;
goto out;
}
- /*
- * The socket maintains a reference to the inode, so we
- * have to increment the count.
- */
- sock->inode->i_count++;
- unlock_kernel();
-
file->f_op = &socket_file_ops;
file->f_mode = 3;
file->f_flags = O_RDWR;
@@ -360,7 +354,7 @@ struct socket *sock_alloc(void)
sock->sk = NULL;
sock->file = NULL;
- sockets_in_use++;
+ sockets_in_use[smp_processor_id()].counter++;
return sock;
}
@@ -383,9 +377,12 @@ void sock_release(struct socket *sock)
if (sock->fasync_list)
printk(KERN_ERR "sock_release: fasync list not empty!\n");
- --sockets_in_use; /* Bookkeeping.. */
+ sockets_in_use[smp_processor_id()].counter--;
+ if (!sock->file) {
+ iput(sock->inode);
+ return;
+ }
sock->file=NULL;
- iput(sock->inode);
}
int sock_sendmsg(struct socket *sock, struct msghdr *msg, int size)
@@ -889,8 +886,6 @@ asmlinkage long sys_listen(int fd, int backlog)
int err;
if ((sock = sockfd_lookup(fd, &err)) != NULL) {
- if ((unsigned) backlog == 0) /* BSDism */
- backlog = 1;
if ((unsigned) backlog > SOMAXCONN)
backlog = SOMAXCONN;
err=sock->ops->listen(sock, backlog);
@@ -943,6 +938,9 @@ asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_a
goto out_release;
}
+ /* File flags are inherited via accept(). It looks silly, but we
+ * have to be compatible with another OSes.
+ */
if ((err = sock_map_fd(newsock)) < 0)
goto out_release;
@@ -1119,7 +1117,7 @@ asmlinkage long sys_recvfrom(int fd, void * ubuf, size_t size, unsigned flags,
flags |= MSG_DONTWAIT;
err=sock_recvmsg(sock, &msg, size, flags);
- if(err >= 0 && addr != NULL)
+ if(err >= 0 && addr != NULL && msg.msg_namelen)
{
err2=move_addr_to_user(address, msg.msg_namelen, addr, addr_len);
if(err2<0)
@@ -1341,7 +1339,7 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr *msg, unsigned int flags)
goto out_freeiov;
len = err;
- if (uaddr != NULL) {
+ if (uaddr != NULL && msg_sys.msg_namelen) {
err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
if (err < 0)
goto out_freeiov;
@@ -1595,7 +1593,17 @@ void __init sock_init(void)
int socket_get_info(char *buffer, char **start, off_t offset, int length)
{
- int len = sprintf(buffer, "sockets: used %d\n", sockets_in_use);
+ int len, cpu;
+ int counter = 0;
+
+ for (cpu=0; cpu<smp_num_cpus; cpu++)
+ counter += sockets_in_use[cpu].counter;
+
+ /* It can be negative, by the way. 8) */
+ if (counter < 0)
+ counter = 0;
+
+ len = sprintf(buffer, "sockets: used %d\n", counter);
if (offset >= len)
{
*start = buffer;
@@ -1605,5 +1613,7 @@ int socket_get_info(char *buffer, char **start, off_t offset, int length)
len -= offset;
if (len > length)
len = length;
+ if (len < 0)
+ len = 0;
return len;
}
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 521152396..459de5e7f 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -816,7 +816,7 @@ static void
do_rpciod_tcp_dispatcher(void)
{
struct rpc_xprt *xprt;
- int result;
+ int result = 0;
dprintk("rpciod_tcp_dispatcher: Queue Running\n");
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index e6b0eb50c..7b3c63e87 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -8,7 +8,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * Version: $Id: af_unix.c,v 1.87 1999/12/09 00:54:25 davem Exp $
+ * Version: $Id: af_unix.c,v 1.88 2000/01/18 08:24:28 davem Exp $
*
* Fixes:
* Linus Torvalds : Assorted bug cures.
@@ -337,10 +337,7 @@ static int unix_release_sock (unix_socket *sk, int embrion)
/* Clear state */
unix_state_wlock(sk);
- write_lock(&sk->callback_lock);
- sk->dead = 1;
- sk->socket = NULL;
- write_unlock(&sk->callback_lock);
+ sock_orphan(sk);
sk->shutdown = SHUTDOWN_MASK;
dentry = sk->protinfo.af_unix.dentry;
sk->protinfo.af_unix.dentry=NULL;
@@ -348,8 +345,7 @@ static int unix_release_sock (unix_socket *sk, int embrion)
sk->state = TCP_CLOSE;
unix_state_wunlock(sk);
- wake_up_interruptible(sk->sleep);
- wake_up_interruptible(&sk->protinfo.af_unix.peer_wait);
+ wake_up_interruptible_all(&sk->protinfo.af_unix.peer_wait);
skpair=unix_peer(sk);
@@ -360,7 +356,8 @@ static int unix_release_sock (unix_socket *sk, int embrion)
if (!skb_queue_empty(&sk->receive_queue) || embrion)
skpair->err = ECONNRESET;
unix_state_wunlock(skpair);
- sk->data_ready(skpair,0);
+ sk->state_change(skpair);
+ sock_wake_async(sk->socket,1,POLL_HUP);
}
sock_put(skpair); /* It may now die */
unix_peer(sk) = NULL;
@@ -418,7 +415,7 @@ static int unix_listen(struct socket *sock, int backlog)
if (sk->state != TCP_CLOSE && sk->state != TCP_LISTEN)
goto out_unlock;
if (backlog > sk->max_ack_backlog)
- wake_up_interruptible(&sk->protinfo.af_unix.peer_wait);
+ wake_up_interruptible_all(&sk->protinfo.af_unix.peer_wait);
sk->max_ack_backlog=backlog;
sk->state=TCP_LISTEN;
sock->flags |= SO_ACCEPTCON;
@@ -740,26 +737,26 @@ out:
return err;
}
-static void unix_wait_for_peer(unix_socket *other)
+static long unix_wait_for_peer(unix_socket *other, long timeo)
{
int sched;
DECLARE_WAITQUEUE(wait, current);
- __set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&other->protinfo.af_unix.peer_wait, &wait);
+ __set_current_state(TASK_INTERRUPTIBLE|TASK_EXCLUSIVE);
+ add_wait_queue_exclusive(&other->protinfo.af_unix.peer_wait, &wait);
sched = (!other->dead &&
!(other->shutdown&RCV_SHUTDOWN) &&
- !signal_pending(current) &&
- skb_queue_len(&other->receive_queue) >= other->max_ack_backlog);
+ skb_queue_len(&other->receive_queue) > other->max_ack_backlog);
unix_state_runlock(other);
if (sched)
- schedule();
+ timeo = schedule_timeout(timeo);
__set_current_state(TASK_RUNNING);
remove_wait_queue(&other->protinfo.af_unix.peer_wait, &wait);
+ return timeo;
}
static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
@@ -773,6 +770,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
unsigned hash;
int st;
int err;
+ long timeo;
err = unix_mkname(sunaddr, addr_len, &hash);
if (err < 0)
@@ -783,6 +781,8 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
(err = unix_autobind(sock)) != 0)
goto out;
+ timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
+
/* First of all allocate resources.
If we will make it after state is locked,
we will have to recheck all again in any case.
@@ -820,12 +820,12 @@ restart:
if (other->state != TCP_LISTEN)
goto out_unlock;
- if (skb_queue_len(&other->receive_queue) >= other->max_ack_backlog) {
+ if (skb_queue_len(&other->receive_queue) > other->max_ack_backlog) {
err = -EAGAIN;
- if (flags & O_NONBLOCK)
+ if (!timeo)
goto out_unlock;
- unix_wait_for_peer(other);
+ timeo = unix_wait_for_peer(other, timeo);
err = -ERESTARTSYS;
if (signal_pending(current))
@@ -959,8 +959,8 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags)
if (sk->state!=TCP_LISTEN)
goto out;
- /* If socket state is TCP_LISTEN it cannot change,
- so that no locks are necessary.
+ /* If socket state is TCP_LISTEN it cannot change (for now...),
+ * so that no locks are necessary.
*/
skb = skb_recv_datagram(sk, 0, flags&O_NONBLOCK, &err);
@@ -968,16 +968,13 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags)
goto out;
tsk = skb->sk;
- if (skb_queue_len(&sk->receive_queue) <= sk->max_ack_backlog/2)
- wake_up_interruptible(&sk->protinfo.af_unix.peer_wait);
skb_free_datagram(sk, skb);
+ wake_up_interruptible(&sk->protinfo.af_unix.peer_wait);
/* attach accepted sock to socket */
unix_state_wlock(tsk);
newsock->state = SS_CONNECTED;
- newsock->sk = tsk;
- tsk->sleep = &newsock->wait;
- tsk->socket = newsock;
+ sock_graft(tsk, newsock);
unix_state_wunlock(tsk);
return 0;
@@ -1069,15 +1066,12 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, int len,
int err;
unsigned hash;
struct sk_buff *skb;
+ long timeo;
err = -EOPNOTSUPP;
if (msg->msg_flags&MSG_OOB)
goto out;
- err = -EINVAL;
- if (msg->msg_flags&~(MSG_DONTWAIT|MSG_NOSIGNAL))
- goto out;
-
if (msg->msg_namelen) {
err = unix_mkname(sunaddr, msg->msg_namelen, &hash);
if (err < 0)
@@ -1095,6 +1089,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, int len,
(err = unix_autobind(sock)) != 0)
goto out;
+
skb = sock_alloc_send_skb(sk, len, 0, msg->msg_flags&MSG_DONTWAIT, &err);
if (skb==NULL)
goto out;
@@ -1108,6 +1103,8 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, int len,
if (err)
goto out_free;
+ timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
+
restart:
if (!other) {
err = -ECONNRESET;
@@ -1151,20 +1148,13 @@ restart:
if (other->shutdown&RCV_SHUTDOWN)
goto out_unlock;
- if (0/*other->user_callback &&
- other->user_callback(other->user_data, skb) == 0*/) {
- unix_state_runlock(other);
- sock_put(other);
- return len;
- }
-
- if (skb_queue_len(&other->receive_queue) >= other->max_ack_backlog) {
- if (msg->msg_flags & MSG_DONTWAIT) {
+ if (skb_queue_len(&other->receive_queue) > other->max_ack_backlog) {
+ if (!timeo) {
err = -EAGAIN;
goto out_unlock;
}
- unix_wait_for_peer(other);
+ timeo = unix_wait_for_peer(other, timeo);
err = -ERESTARTSYS;
if (signal_pending(current))
@@ -1205,10 +1195,6 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, int len,
if (msg->msg_flags&MSG_OOB)
goto out_err;
- err = -EINVAL;
- if (msg->msg_flags&~(MSG_DONTWAIT|MSG_NOSIGNAL))
- goto out_err;
-
if (msg->msg_namelen) {
err = (sk->state==TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP);
goto out_err;
@@ -1329,8 +1315,7 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, int size,
if (!skb)
goto out;
- if (skb_queue_len(&sk->receive_queue) <= sk->max_ack_backlog/2)
- wake_up_interruptible(&sk->protinfo.af_unix.peer_wait);
+ wake_up_interruptible(&sk->protinfo.af_unix.peer_wait);
if (msg->msg_name)
unix_copy_addr(msg, skb->sk);
@@ -1380,7 +1365,7 @@ out:
* Sleep until data has arrive. But check for races..
*/
-static void unix_stream_data_wait(unix_socket * sk)
+static long unix_stream_data_wait(unix_socket * sk, long timeo)
{
DECLARE_WAITQUEUE(wait, current);
@@ -1394,12 +1379,13 @@ static void unix_stream_data_wait(unix_socket * sk)
if (skb_queue_len(&sk->receive_queue) ||
sk->err ||
(sk->shutdown & RCV_SHUTDOWN) ||
- signal_pending(current))
+ signal_pending(current) ||
+ !timeo)
break;
sk->socket->flags |= SO_WAITDATA;
unix_state_runlock(sk);
- schedule();
+ timeo = schedule_timeout(timeo);
unix_state_rlock(sk);
sk->socket->flags &= ~SO_WAITDATA;
}
@@ -1407,6 +1393,7 @@ static void unix_stream_data_wait(unix_socket * sk)
__set_current_state(TASK_RUNNING);
remove_wait_queue(sk->sleep, &wait);
unix_state_runlock(sk);
+ return timeo;
}
@@ -1415,12 +1402,12 @@ static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg, int size
int flags, struct scm_cookie *scm)
{
struct sock *sk = sock->sk;
- int noblock = flags & MSG_DONTWAIT;
struct sockaddr_un *sunaddr=msg->msg_name;
int copied = 0;
int check_creds = 0;
- int target = 1;
+ int target;
int err = 0;
+ long timeo;
err = -EINVAL;
if (sk->state != TCP_ESTABLISHED)
@@ -1430,9 +1417,8 @@ static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg, int size
if (flags&MSG_OOB)
goto out;
- if (flags&MSG_WAITALL)
- target = size;
-
+ target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
+ timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
msg->msg_namelen = 0;
@@ -1462,11 +1448,11 @@ static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg, int size
if (sk->shutdown & RCV_SHUTDOWN)
break;
err = -EAGAIN;
- if (noblock)
+ if (!timeo)
break;
up(&sk->protinfo.af_unix.readsem);
- unix_stream_data_wait(sk);
+ timeo = unix_stream_data_wait(sk, timeo);
if (signal_pending(current)) {
err = -ERESTARTSYS;
@@ -1569,10 +1555,9 @@ static int unix_shutdown(struct socket *sock, int mode)
unix_state_wlock(other);
other->shutdown |= peer_mode;
unix_state_wunlock(other);
+ other->state_change(other);
if (peer_mode&RCV_SHUTDOWN)
- other->data_ready(other,0);
- else
- other->state_change(other);
+ sock_wake_async(sk->socket,1,POLL_HUP);
}
if (other)
sock_put(other);
@@ -1589,14 +1574,11 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
switch(cmd)
{
-
- case TIOCOUTQ:
- amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
- if(amount<0)
- amount=0;
+ case SIOCOUTQ:
+ amount = atomic_read(&sk->wmem_alloc);
err = put_user(amount, (int *)arg);
break;
- case TIOCINQ:
+ case SIOCINQ:
{
struct sk_buff *skb;
if (sk->state==TCP_LISTEN) {
@@ -1630,11 +1612,11 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl
/* exceptional events? */
if (sk->err)
mask |= POLLERR;
- if (sk->shutdown & RCV_SHUTDOWN)
+ if (sk->shutdown == SHUTDOWN_MASK)
mask |= POLLHUP;
/* readable? */
- if (!skb_queue_empty(&sk->receive_queue))
+ if (!skb_queue_empty(&sk->receive_queue) || (sk->shutdown&RCV_SHUTDOWN))
mask |= POLLIN | POLLRDNORM;
/* Connection-based need to check for termination and startup */
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c
index ae365edaa..af7191563 100644
--- a/net/wanrouter/wanmain.c
+++ b/net/wanrouter/wanmain.c
@@ -9,15 +9,16 @@
* o Logical connection management (switched virtual circuits)
* o Protocol encapsulation/decapsulation
*
-* Author: Gene Kozin <genek@compuserve.com>
+* Author: Gideon Hack
*
-* Copyright: (c) 1995-1997 Sangoma Technologies Inc.
+* Copyright: (c) 1995-1999 Sangoma Technologies 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.
* ============================================================================
+* Oct 01, 1999 Gideon Hack Update for s514 PCI card
* Dec 27, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE)
* Jan 16, 1997 Gene Kozin router_devlist made public
* Jan 31, 1997 Alan Cox Hacked it about a bit for 2.1
@@ -31,8 +32,10 @@
* kernel memory and copy configuration data to
* kernel space (for big firmwares)
* May 19, 1999 Arnaldo Melo __init in wanrouter_init
+* Jun 02, 1999 Gideon Hack Updates for Linux 2.0.X and 2.2.X kernels.
*****************************************************************************/
+#include <linux/version.h>
#include <linux/config.h>
#include <linux/stddef.h> /* offsetof(), etc. */
#include <linux/errno.h> /* return codes */
@@ -48,7 +51,11 @@
#include <linux/wanrouter.h> /* WAN router API definitions */
#include <linux/init.h> /* __init et al. */
-/****** Defines and Macros **************************************************/
+
+
+/*
+ * Defines and Macros
+ */
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
@@ -57,48 +64,49 @@
#define max(a,b) (((a)>(b))?(a):(b))
#endif
-/****** Function Prototypes *************************************************/
-
/*
- * Kernel loadable module interface.
+ * Function Prototypes
*/
+/*
+ * Kernel loadable module interface.
+ */
#ifdef MODULE
int init_module (void);
void cleanup_module (void);
#endif
-/*
+/*
* WAN device IOCTL handlers
*/
-static int device_setup (wan_device_t* wandev, wandev_conf_t* u_conf);
-static int device_stat (wan_device_t* wandev, wandev_stat_t* u_stat);
-static int device_shutdown (wan_device_t* wandev);
-static int device_new_if (wan_device_t* wandev, wanif_conf_t* u_conf);
-static int device_del_if (wan_device_t* wandev, char* u_name);
-
-/*
+static int device_setup(wan_device_t *wandev, wandev_conf_t *u_conf);
+static int device_stat(wan_device_t *wandev, wandev_stat_t *u_stat);
+static int device_shutdown(wan_device_t *wandev);
+static int device_new_if(wan_device_t *wandev, wanif_conf_t *u_conf);
+static int device_del_if(wan_device_t *wandev, char *u_name);
+
+/*
* Miscellaneous
*/
-static wan_device_t* find_device (char* name);
-static int delete_interface (wan_device_t* wandev, char* name, int forse);
+static wan_device_t *find_device (char *name);
+static int delete_interface (wan_device_t *wandev, char *name, int force);
/*
* Global Data
*/
static char fullname[] = "WAN Router";
-static char copyright[] = "(c) 1995-1997 Sangoma Technologies Inc.";
+static char copyright[] = "(c) 1995-1999 Sangoma Technologies Inc.";
static char modname[] = ROUTER_NAME; /* short module name */
-wan_device_t * router_devlist = NULL; /* list of registered devices */
-static int devcnt = 0;
+wan_device_t* router_devlist = NULL; /* list of registered devices */
+static int devcnt = 0;
-/*
- * Organizationally Unique Identifiers for encapsulation/decapsulation
+/*
+ * Organize Unique Identifiers for encapsulation/decapsulation
*/
-
+
static unsigned char oui_ether[] = { 0x00, 0x00, 0x00 };
#if 0
static unsigned char oui_802_2[] = { 0x00, 0x80, 0xC2 };
@@ -115,8 +123,7 @@ int __init wanrouter_init(void)
fullname, ROUTER_VERSION, ROUTER_RELEASE, copyright);
err = wanrouter_proc_init();
if (err)
- printk(KERN_ERR "%s: can't create entry in proc filesystem!\n",
- modname);
+ printk(KERN_ERR "%s: can't create entry in proc filesystem!\n", modname);
/*
* Initialise compiled in boards
@@ -138,14 +145,14 @@ int __init wanrouter_init(void)
*/
/*
- * Module 'insert' entry point.
- * o print announcement
- * o initialize static data
- * o create /proc/net/router directory and static entries
+ * Module 'insert' entry point.
+ * o print announcement
+ * o initialize static data
+ * o create /proc/net/router directory and static entries
*
- * Return: 0 Ok
+ * Return: 0 Ok
* < 0 error.
- * Context: process
+ * Context: process
*/
int init_module (void)
@@ -161,10 +168,10 @@ int init_module (void)
}
/*
- * Module 'remove' entry point.
- * o delete /proc/net/router directory and static entries.
+ * Module 'remove' entry point.
+ * o delete /proc/net/router directory and static entries.
*/
-
+
void cleanup_module (void)
{
wanrouter_proc_cleanup();
@@ -173,33 +180,34 @@ void cleanup_module (void)
#endif
/*
- * Kernel APIs
+ * Kernel APIs
*/
/*
- * Register WAN device.
- * o verify device credentials
- * o create an entry for the device in the /proc/net/router directory
- * o initialize internally maintained fields of the wan_device structure
- * o link device data space to a singly-linked list
- * o if it's the first device, then start kernel 'thread'
- * o increment module use count
+ * Register WAN device.
+ * o verify device credentials
+ * o create an entry for the device in the /proc/net/router directory
+ * o initialize internally maintained fields of the wan_device structure
+ * o link device data space to a singly-linked list
+ * o if it's the first device, then start kernel 'thread'
+ * o increment module use count
*
- * Return:
- * 0 Ok
- * < 0 error.
+ * Return:
+ * 0 Ok
+ * < 0 error.
*
- * Context: process
+ * Context: process
*/
-int register_wan_device(wan_device_t* wandev)
+
+int register_wan_device(wan_device_t *wandev)
{
int err, namelen;
if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC) ||
(wandev->name == NULL))
return -EINVAL;
-
+
namelen = strlen(wandev->name);
if (!namelen || (namelen > WAN_DRVNAME_SZ))
return -EINVAL;
@@ -215,12 +223,10 @@ int register_wan_device(wan_device_t* wandev)
* Register /proc directory entry
*/
err = wanrouter_proc_add(wandev);
- if (err)
- {
+ if (err) {
printk(KERN_ERR
"%s: can't create /proc/net/router/%s entry!\n",
- modname, wandev->name)
- ;
+ modname, wandev->name);
return err;
}
@@ -250,8 +256,8 @@ int register_wan_device(wan_device_t* wandev)
* Context: process
*/
-
-int unregister_wan_device(char* name)
+
+int unregister_wan_device(char *name)
{
wan_device_t *wandev, *prev;
@@ -269,8 +275,7 @@ int unregister_wan_device(char* name)
printk(KERN_INFO "%s: unregistering WAN device %s\n", modname, name);
#endif
- if (wandev->state != WAN_UNCONFIGURED)
- {
+ if (wandev->state != WAN_UNCONFIGURED) {
while(wandev->dev)
delete_interface(wandev, wandev->dev->name, 1);
if (wandev->shutdown)
@@ -359,7 +364,6 @@ unsigned short wanrouter_type_trans (struct sk_buff* skb, struct net_device* dev
"on interface %s!\n", modname,
skb->data[cnt+1], skb->data[cnt+2],
skb->data[cnt+3], dev->name);
- ;
return 0;
}
ethertype = *((unsigned short*)&skb->data[cnt+4]);
@@ -371,8 +375,7 @@ unsigned short wanrouter_type_trans (struct sk_buff* skb, struct net_device* dev
default:
printk(KERN_INFO
"%s: unsupported NLPID 0x%02X on interface %s!\n",
- modname, skb->data[cnt], dev->name)
- ;
+ modname, skb->data[cnt], dev->name);
return 0;
}
skb->protocol = ethertype;
@@ -382,18 +385,19 @@ unsigned short wanrouter_type_trans (struct sk_buff* skb, struct net_device* dev
return ethertype;
}
+
/*
* WAN device IOCTL.
* o find WAN device associated with this node
* o execute requested action or pass command to the device driver
*/
-int wanrouter_ioctl(struct inode* inode, struct file* file,
+int wanrouter_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
int err = 0;
- struct proc_dir_entry* dent;
- wan_device_t* wandev;
+ struct proc_dir_entry *dent;
+ wan_device_t *wandev;
if (!capable(CAP_NET_ADMIN)){
return -EPERM;
@@ -410,8 +414,7 @@ int wanrouter_ioctl(struct inode* inode, struct file* file,
if (wandev->magic != ROUTER_MAGIC)
return -EINVAL;
- switch (cmd)
- {
+ switch (cmd) {
case ROUTER_SETUP:
err = device_setup(wandev, (void*)arg);
break;
@@ -439,8 +442,7 @@ int wanrouter_ioctl(struct inode* inode, struct file* file,
if ((cmd >= ROUTER_USER) &&
(cmd <= ROUTER_USER_MAX) &&
wandev->ioctl)
- err = wandev->ioctl(wandev, cmd, arg)
- ;
+ err = wandev->ioctl(wandev, cmd, arg);
else err = -EINVAL;
}
return err;
@@ -458,51 +460,52 @@ int wanrouter_ioctl(struct inode* inode, struct file* file,
* o call driver's setup() entry point
*/
-static int device_setup (wan_device_t* wandev, wandev_conf_t* u_conf)
+static int device_setup (wan_device_t *wandev, wandev_conf_t *u_conf)
{
- void* data;
+ void *data = NULL;
wandev_conf_t *conf;
- int err= -EINVAL;
+ int err = -EINVAL;
if (wandev->setup == NULL) /* Nothing to do ? */
return 0;
-
+
conf = kmalloc(sizeof(wandev_conf_t), GFP_KERNEL);
if (conf == NULL)
return -ENOBUFS;
-
- if(copy_from_user(conf, u_conf, sizeof(wandev_conf_t)))
- {
+
+ if(copy_from_user(conf, u_conf, sizeof(wandev_conf_t))) {
kfree(conf);
return -EFAULT;
}
- if (conf->magic != ROUTER_MAGIC)
- goto bail;
+ if (conf->magic != ROUTER_MAGIC) {
+ kfree(conf);
+ return -EINVAL;
+ }
- if (conf->data_size && conf->data)
- {
- if(conf->data_size > 128000 || conf->data_size < 0){
- goto bail;
+ if (conf->data_size && conf->data) {
+ if(conf->data_size > 128000 || conf->data_size < 0) {
+ kfree(conf);
+ return -EINVAL;;
}
+
data = vmalloc(conf->data_size);
- if (data)
- {
- if(!copy_from_user(data, conf->data, conf->data_size))
- {
+ if (data) {
+ if(!copy_from_user(data, conf->data, conf->data_size)){
conf->data=data;
err = wandev->setup(wandev,conf);
}
else
err = -EFAULT;
}
- else
+ else
err = -ENOBUFS;
-
+
if (data)
vfree(data);
+
}
-bail:
+
kfree(conf);
return err;
}
@@ -537,7 +540,7 @@ static int device_shutdown (wan_device_t* wandev)
* Get WAN device status & statistics.
*/
-static int device_stat (wan_device_t* wandev, wandev_stat_t* u_stat)
+static int device_stat (wan_device_t *wandev, wandev_stat_t *u_stat)
{
wandev_stat_t stat;
@@ -553,6 +556,7 @@ static int device_stat (wan_device_t* wandev, wandev_stat_t* u_stat)
if(copy_to_user(u_stat, &stat, sizeof(stat)))
return -EFAULT;
+
return 0;
}
@@ -569,7 +573,7 @@ static int device_stat (wan_device_t* wandev, wandev_stat_t* u_stat)
static int device_new_if (wan_device_t* wandev, wanif_conf_t* u_conf)
{
wanif_conf_t conf;
- struct net_device* dev;
+ struct net_device *dev;
int err;
if ((wandev->state == WAN_UNCONFIGURED) || (wandev->new_if == NULL))
@@ -587,8 +591,7 @@ static int device_new_if (wan_device_t* wandev, wanif_conf_t* u_conf)
memset(dev, 0, sizeof(struct net_device));
err = wandev->new_if(wandev, dev, &conf);
- if (!err)
- {
+ if (!err) {
/* Register network interface. This will invoke init()
* function supplied by the driver. If device registered
* successfully, add it to the interface list.
@@ -598,15 +601,13 @@ static int device_new_if (wan_device_t* wandev, wanif_conf_t* u_conf)
else if (dev_get(dev->name))
err = -EEXIST; /* name already exists */
- else
- {
+ else {
#ifdef WANDEBUG
printk(KERN_INFO "%s: registering interface %s...\n",
modname, dev->name);
#endif
err = register_netdev(dev);
- if (!err)
- {
+ if (!err) {
cli(); /***** critical section start *****/
dev->slave = wandev->dev;
wandev->dev = dev;
@@ -622,25 +623,28 @@ static int device_new_if (wan_device_t* wandev, wanif_conf_t* u_conf)
return err;
}
+
/*
* Delete WAN logical channel.
* o verify user address space
* o copy configuration data to kernel address space
*/
-static int device_del_if (wan_device_t* wandev, char* u_name)
+static int device_del_if (wan_device_t *wandev, char *u_name)
{
char name[WAN_IFNAME_SZ + 1];
if (wandev->state == WAN_UNCONFIGURED)
return -ENODEV;
-
+
memset(name, 0, sizeof(name));
+
if(copy_from_user(name, u_name, WAN_IFNAME_SZ))
return -EFAULT;
return delete_interface(wandev, name, 0);
}
+
/*
* Miscellaneous Functions
*/
@@ -650,9 +654,9 @@ static int device_del_if (wan_device_t* wandev, char* u_name)
* Return pointer to the WAN device data space or NULL if device not found.
*/
-static wan_device_t* find_device (char* name)
+static wan_device_t *find_device(char *name)
{
- wan_device_t* wandev;
+ wan_device_t *wandev;
for (wandev = router_devlist;wandev && strcmp(wandev->name, name);
wandev = wandev->next);
@@ -676,7 +680,7 @@ static wan_device_t* find_device (char* name)
* sure that opened interfaces are not removed!
*/
-static int delete_interface (wan_device_t* wandev, char* name, int force)
+static int delete_interface (wan_device_t *wandev, char *name, int force)
{
struct net_device *dev, *prev;
@@ -687,16 +691,16 @@ static int delete_interface (wan_device_t* wandev, char* name, int force)
if (dev == NULL)
return -ENODEV; /* interface not found */
- if (dev->start)
- {
- if (force)
- {
+ if (dev->start) {
+ if (force) {
printk(KERN_WARNING
- "%s: deleting opened interface %s!\n",modname, name);
+ "%s: deleting opened interface %s!\n",
+ modname, name);
}
else
return -EBUSY; /* interface in use */
}
+
if (wandev->del_if)
wandev->del_if(wandev, dev);
@@ -708,7 +712,7 @@ static int delete_interface (wan_device_t* wandev, char* name, int force)
--wandev->ndev;
sti(); /****** critical section end ******/
- printk("Unregistering '%s'\n", dev->name);
+ printk("Unregistering '%s'\n", dev->name);
unregister_netdev(dev);
kfree(dev);
return 0;
@@ -722,4 +726,3 @@ EXPORT_SYMBOL(wanrouter_type_trans);
/*
* End
*/
-
diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c
index f895fc58b..91696d57e 100644
--- a/net/wanrouter/wanproc.c
+++ b/net/wanrouter/wanproc.c
@@ -4,21 +4,23 @@
* This module is completely hardware-independent and provides
* access to the router using Linux /proc filesystem.
*
-* Author: Gene Kozin <genek@compuserve.com>
+* Author: Gideon Hack
*
-* Copyright: (c) 1995-1997 Sangoma Technologies Inc.
+* Copyright: (c) 1995-1999 Sangoma Technologies 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.
* ============================================================================
+* Jun 02, 1999 Gideon Hack Updates for Linux 2.2.X kernels.
* Jun 29, 1997 Alan Cox Merged with 1.0.3 vendor code
* Jan 29, 1997 Gene Kozin v1.0.1. Implemented /proc read routines
* Jan 30, 1997 Alan Cox Hacked around for 2.1
* Dec 13, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE)
*****************************************************************************/
+#include <linux/version.h>
#include <linux/config.h>
#include <linux/stddef.h> /* offsetof(), etc. */
#include <linux/errno.h> /* return codes */
@@ -36,6 +38,8 @@
/****** Defines and Macros **************************************************/
+#define PROC_STATS_FORMAT "%30s: %12lu\n"
+
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#endif
@@ -45,11 +49,12 @@
#define PROC_BUFSZ 4000 /* buffer size for printing proc info */
+
/****** Data Types **********************************************************/
typedef struct wan_stat_entry
{
- struct wan_stat_entry * next;
+ struct wan_stat_entry *next;
char *description; /* description string */
void *data; /* -> data */
unsigned data_type; /* data type */
@@ -83,7 +88,6 @@ static int wandev_get_info(char* buf, char** start, off_t offs, int len);
/*
* Generic /proc/net/router/<file> file and inode operations
*/
-
static struct file_operations router_fops =
{
NULL, /* lseek */
@@ -266,7 +270,7 @@ static int router_proc_perms (struct inode* inode, int op)
/*
* Read router proc directory entry.
- * This is universal routine for reading all entries in /proc/net/router
+ * This is universal routine for reading all entries in /proc/net/wanrouter
* directory. Each directory entry contains a pointer to the 'method' for
* preparing data for that entry.
* o verify arguments
@@ -300,8 +304,7 @@ static ssize_t router_proc_read(struct file* file, char* buf, size_t count,
pos = dent->get_info(page, dent->data, 0, 0);
offs = file->f_pos;
- if (offs < pos)
- {
+ if (offs < pos) {
len = min(pos - offs, count);
if(copy_to_user(buf, (page + offs), len))
return -EFAULT;
@@ -325,15 +328,14 @@ static int config_get_info(char* buf, char** start, off_t offs, int len)
strcpy(buf, conf_hdr);
for (wandev = router_devlist;
wandev && (cnt < (PROC_BUFSZ - 120));
- wandev = wandev->next)
- {
+ wandev = wandev->next) {
if (wandev->state) cnt += sprintf(&buf[cnt],
"%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n",
wandev->name,
wandev->ioport,
wandev->irq,
wandev->dma,
- virt_to_phys(wandev->maddr),
+ wandev->maddr,
wandev->msize,
wandev->hw_opt[0],
wandev->hw_opt[1],
@@ -351,13 +353,16 @@ static int config_get_info(char* buf, char** start, off_t offs, int len)
static int status_get_info(char* buf, char** start, off_t offs, int len)
{
- int cnt = sizeof(stat_hdr) - 1;
+ int cnt = 0;
wan_device_t* wandev;
- strcpy(buf, stat_hdr);
+
+ cnt += sprintf(&buf[cnt], "\nSTATUS FOR PORT 0\n\n");
+ strcpy(&buf[cnt], stat_hdr);
+ cnt += sizeof(stat_hdr) - 1;
+
for (wandev = router_devlist;
wandev && (cnt < (PROC_BUFSZ - 80));
- wandev = wandev->next)
- {
+ wandev = wandev->next) {
if (!wandev->state) continue;
cnt += sprintf(&buf[cnt],
"%-15s|%-7s|%-9s|%-8s|%9u|%5u|%3u |",
@@ -367,10 +372,10 @@ static int status_get_info(char* buf, char** start, off_t offs, int len)
wandev->clocking ? "internal" : "external",
wandev->bps,
wandev->mtu,
- wandev->ndev)
- ;
- switch (wandev->state)
- {
+ wandev->ndev);
+
+ switch (wandev->state) {
+
case WAN_UNCONFIGURED:
cnt += sprintf(&buf[cnt], "%-12s\n", "unconfigured");
break;
@@ -407,56 +412,64 @@ static int wandev_get_info(char* buf, char** start, off_t offs, int len)
{
wan_device_t* wandev = (void*)start;
int cnt = 0;
+ int rslt = 0;
if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC))
return 0;
if (!wandev->state)
- return sprintf(&buf[cnt], "device is not configured!\n")
- ;
+ return sprintf(&buf[cnt], "device is not configured!\n");
/* Update device statistics */
- if (wandev->update) wandev->update(wandev);
-
- cnt += sprintf(&buf[cnt], "%30s: %12lu\n",
- "total frames received", wandev->stats.rx_packets)
- ;
- cnt += sprintf(&buf[cnt], "%30s: %12lu\n",
- "receiver overrun errors", wandev->stats.rx_over_errors)
- ;
- cnt += sprintf(&buf[cnt], "%30s: %12lu\n",
- "CRC errors", wandev->stats.rx_crc_errors)
- ;
- cnt += sprintf(&buf[cnt], "%30s: %12lu\n",
- "frame length errors", wandev->stats.rx_length_errors)
- ;
- cnt += sprintf(&buf[cnt], "%30s: %12lu\n",
- "frame format errors", wandev->stats.rx_frame_errors)
- ;
- cnt += sprintf(&buf[cnt], "%30s: %12lu\n",
- "aborted frames received", wandev->stats.rx_missed_errors)
- ;
- cnt += sprintf(&buf[cnt], "%30s: %12lu\n",
- "reveived frames dropped", wandev->stats.rx_dropped)
- ;
- cnt += sprintf(&buf[cnt], "%30s: %12lu\n",
- "other receive errors", wandev->stats.rx_errors)
- ;
- cnt += sprintf(&buf[cnt], "\n%30s: %12lu\n",
- "total frames transmitted", wandev->stats.tx_packets)
- ;
- cnt += sprintf(&buf[cnt], "%30s: %12lu\n",
- "aborted frames transmitted", wandev->stats.tx_aborted_errors)
- ;
- cnt += sprintf(&buf[cnt], "%30s: %12lu\n",
- "transmit frames dropped", wandev->stats.tx_dropped)
- ;
- cnt += sprintf(&buf[cnt], "%30s: %12lu\n",
- "transmit collisions", wandev->stats.collisions)
- ;
- cnt += sprintf(&buf[cnt], "%30s: %12lu\n",
- "other transmit errors", wandev->stats.tx_errors)
- ;
- return cnt;
+ if (wandev->update) {
+
+ rslt = wandev->update(wandev);
+ if(rslt) {
+ switch (rslt) {
+ case -EAGAIN:
+ return sprintf(&buf[cnt], "Device is busy!\n");
+
+ default:
+ return sprintf(&buf[cnt],
+ "Device is not configured!\n");
+ }
+ }
+ }
+
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "total packets received", wandev->stats.rx_packets);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "total packets transmitted", wandev->stats.tx_packets);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "total bytes received", wandev->stats.rx_bytes);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "total bytes transmitted", wandev->stats.tx_bytes);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "bad packets received", wandev->stats.rx_errors);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "packet transmit problems", wandev->stats.tx_errors);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "received frames dropped", wandev->stats.rx_dropped);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "transmit frames dropped", wandev->stats.tx_dropped);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "multicast packets received", wandev->stats.multicast);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "transmit collisions", wandev->stats.collisions);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "receive length errors", wandev->stats.rx_length_errors);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "receiver overrun errors", wandev->stats.rx_over_errors);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "CRC errors", wandev->stats.rx_crc_errors);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "frame format errors (aborts)", wandev->stats.rx_frame_errors);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "receiver fifo overrun", wandev->stats.rx_fifo_errors);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "receiver missed packet", wandev->stats.rx_missed_errors);
+ cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
+ "aborted frames transmitted", wandev->stats.tx_aborted_errors);
+ return cnt;
}
/*
@@ -490,3 +503,8 @@ int wanrouter_proc_delete(wan_device_t *wandev)
}
#endif
+
+/*
+ * End
+ */
+